def delete(request, plan_id): """Delete testplan""" if request.GET.get('sure', 'no') == 'no': # TODO: rewrite the response return HttpResponse("\ <script>if(confirm('Are you sure you want to delete this plan %s? \ \\n \\n \ Click OK to delete or cancel to come back')) { \ window.location.href='%s?sure=yes' \ } else { \ history.go(-1) \ };</script>" % (plan_id, reverse('plan-delete', args=[plan_id]))) elif request.GET.get('sure') == 'yes': tp = get_object_or_404(TestPlan, plan_id=plan_id) try: tp.delete() return HttpResponse( "<script>window.location.href='%s'</script>" % reverse( 'tcms.testplans.views.all') ) except Exception: return HttpResponse(Prompt.render( request=request, info_type=Prompt.Info, info='Delete failed.', next='javascript:window.history.go(-1)', )) else: return HttpResponse(Prompt.render( request=request, info_type=Prompt.Info, info='Nothing yet.', next='javascript:window.history.go(-1)', ))
def confirm(request, activation_key): """Confirm the user registration""" # Get the object try: ak = UserActivateKey.objects.select_related('user') ak = ak.get(activation_key=activation_key) except UserActivateKey.DoesNotExist: msg = 'This key no longer exist in the database.' return HttpResponse( Prompt.render(request=request, info_type=Prompt.Info, info=msg, next=request.GET.get('next', reverse('core-views-index')))) # All thing done, start to active the user and use the user login user = ak.user user.is_active = True user.save(update_fields=['is_active']) ak.delete() # login(request, user) # Response to web browser. msg = 'Your account has been activated successfully, click next link to ' \ 're-login.' return HttpResponse( Prompt.render(request=request, info_type=Prompt.Info, info=msg, next=request.GET.get( 'next', reverse('tcms-redirect_to_profile'))))
def confirm(request, activation_key): """Confirm the user registration""" # Get the object try: ak = UserActivateKey.objects.select_related('user') ak = ak.get(activation_key=activation_key) except UserActivateKey.DoesNotExist: msg = 'This key no longer exist in the database.' return HttpResponse(Prompt.render( request=request, info_type=Prompt.Info, info=msg, next=request.GET.get('next', reverse('tcms.core.views.index')) )) # All thing done, start to active the user and use the user login user = ak.user user.is_active = True user.save(update_fields=['is_active']) ak.delete() # login(request, user) # Response to web browser. msg = 'Your account has been activated successfully, click next link to ' \ 're-login.' return HttpResponse(Prompt.render( request=request, info_type=Prompt.Info, info=msg, next=request.GET.get('next', reverse( 'tcms.profiles.views.redirect_to_profile')) ))
def delete(request, plan_id): """Delete testplan""" if request.GET.get('sure', 'no') == 'no': # TODO: rewrite the response return HttpResponse("\ <script>if(confirm('Are you sure you want to delete this plan %s? \ \\n \\n \ Click OK to delete or cancel to come back')) { \ window.location.href='%s?sure=yes' \ } else { \ history.go(-1) \ };</script>" % (plan_id, reverse('plan-delete', args=[plan_id]))) elif request.GET.get('sure') == 'yes': tp = get_object_or_404(TestPlan, plan_id=plan_id) try: tp.delete() return HttpResponse("<script>window.location.href='%s'</script>" % reverse('tcms.testplans.views.all')) except Exception: return HttpResponse( Prompt.render( request=request, info_type=Prompt.Info, info='Delete failed.', next='javascript:window.history.go(-1)', )) else: return HttpResponse( Prompt.render( request=request, info_type=Prompt.Info, info='Nothing yet.', next='javascript:window.history.go(-1)', ))
def register(request, template_name='registration/registration_form.html'): """ Register method of account """ from tcms.core.contrib.auth import get_using_backend from forms import RegistrationForm # Check the register is allowed by backend backend = get_using_backend() cr = getattr(backend, 'can_register') # can register if not cr: return HttpResponse(Prompt.render( request = request, info_type = Prompt.Alert, info = 'The backend is not allow to register.', next = request.REQUEST.get('next', reverse('tcms.core.views.index')) )) if request.method == 'POST': form = form = RegistrationForm(data=request.POST, files=request.FILES) if form.is_valid(): form.save() ak = form.set_active_key() # Send email to user if mail server availabel. if form.cleaned_data['email'] and settings.EMAIL_HOST: form.send_confirm_mail(request = request, active_key = ak) msg = 'Your accounts has been create, please check your mailbox for active.' return HttpResponse(Prompt.render( request = request, info_type = Prompt.Info, info = msg, next = request.REQUEST.get('next', reverse('tcms.core.views.index')) )) # If can not send email, prompt to user. msg = 'Your accounts has been create, but you need to contact admins to active your account.' if settings.ADMINS: msg += '<p>Following is the admin list</p><ul>' for admin in settings.ADMINS: msg += '<li><a href="mailto:%s">%s</a></li>' % (admin[1], admin[0]) msg += '</ul>' return HttpResponse(Prompt.render( request = request, info_type = Prompt.Info, info = msg, next = request.REQUEST.get('next', reverse('tcms.core.views.index')) )) else: form = RegistrationForm() context_data = { 'form': form, } return render_to_response(template_name, context_data, context_instance=RequestContext(request))
def register(request, template_name='registration/registration_form.html'): """Register method of account""" request_data = request.GET or request.POST # Check that registration is allowed by backend config user_pwd_backend_config = settings.ENABLED_AUTH_BACKENDS.get('USERPWD') if (user_pwd_backend_config is None or not user_pwd_backend_config.get('ALLOW_REGISTER')): return Prompt.render( request=request, info_type=Prompt.Alert, info='The backend is not allowed to register.', next=request_data.get('next', reverse('nitrate-index')) ) if request.method == 'POST': form = RegistrationForm(data=request.POST, files=request.FILES) if form.is_valid(): form.save() ak = form.set_active_key() # Send email to user if mail server is available. if form.cleaned_data['email'] and settings.EMAIL_HOST: form.send_confirm_mail(request=request, active_key=ak) msg = ( 'Your account has been created, please check your mailbox ' 'for confirmation.' ) else: msg = [ '<p>Your account has been created, but you need to contact ' 'an administrator to active your account.</p>', ] # If can not send email, prompt to user. if settings.ADMINS: msg.append('<p>Following is the admin list</p><ul>') for name, email in settings.ADMINS: msg.append(f'<li><a href="mailto:{email}">{name}</a></li>') msg.append('</ul>') msg = ''.join(msg) return Prompt.render( request=request, info_type=Prompt.Info, info=msg, next=request.POST.get('next', reverse('nitrate-index')) ) else: form = RegistrationForm() context_data = { 'form': form, } return render(request, template_name, context=context_data)
def register(request, template_name='registration/registration_form.html'): """Register method of account""" request_data = request.GET or request.POST # Check that registration is allowed by backend backend = get_using_backend() cr = getattr(backend, 'can_register') # can register if not cr: return HttpResponse( Prompt.render(request=request, info_type=Prompt.Alert, info='The backend is not allowed to register.', next=request_data.get('next', reverse('core-views-index')))) if request.method == 'POST': form = RegistrationForm(data=request.POST, files=request.FILES) if form.is_valid(): form.save() ak = form.set_active_key() # Send email to user if mail server is available. if form.cleaned_data['email'] and settings.EMAIL_HOST: form.send_confirm_mail(request=request, active_key=ak) msg = 'Your account has been created, please check your ' \ 'mailbox for confirmation.' else: msg = [ '<p>Your account has been created, but you need to contact ' 'an administrator to active your account.</p>', ] # If can not send email, prompt to user. if settings.ADMINS: msg.append('<p>Following is the admin list</p><ul>') for name, email in settings.ADMINS: msg.append( '<li><a href="mailto:{}">{}</a></li>'.format( email, name)) msg.append('</ul>') msg = ''.join(msg) return HttpResponse( Prompt.render(request=request, info_type=Prompt.Info, info=msg, next=request.POST.get( 'next', reverse('core-views-index')))) else: form = RegistrationForm() context_data = { 'form': form, } return render(request, template_name, context_data)
def register(request, template_name='registration/registration_form.html'): """Register method of account""" request_data = request.GET or request.POST # Check that registration is allowed by backend config user_pwd_backend_config = settings.ENABLED_AUTH_BACKENDS.get('USERPWD') if (user_pwd_backend_config is None or not user_pwd_backend_config.get('ALLOW_REGISTER')): return Prompt.render( request=request, info_type=Prompt.Alert, info='The backend is not allowed to register.', next=request_data.get('next', reverse('nitrate-index')) ) if request.method == 'POST': form = RegistrationForm(data=request.POST, files=request.FILES) if form.is_valid(): form.save() ak = form.set_active_key() # Send email to user if mail server is available. if form.cleaned_data['email'] and settings.EMAIL_HOST: form.send_confirm_mail(request=request, active_key=ak) msg = 'Your account has been created, please check your ' \ 'mailbox for confirmation.' else: msg = [ '<p>Your account has been created, but you need to contact ' 'an administrator to active your account.</p>', ] # If can not send email, prompt to user. if settings.ADMINS: msg.append('<p>Following is the admin list</p><ul>') for name, email in settings.ADMINS: msg.append('<li><a href="mailto:{}">{}</a></li>'.format(email, name)) msg.append('</ul>') msg = ''.join(msg) return Prompt.render( request=request, info_type=Prompt.Info, info=msg, next=request.POST.get('next', reverse('nitrate-index')) ) else: form = RegistrationForm() context_data = { 'form': form, } return render(request, template_name, context=context_data)
def register(request, template_name='registration/registration_form.html'): """Register method of account""" request_data = request.GET or request.POST # Check that registration is allowed by backend backend = get_using_backend() cr = getattr(backend, 'can_register') # can register if not cr: return HttpResponse(Prompt.render( request=request, info_type=Prompt.Alert, info='The backend is not allowed to register.', next=request_data.get('next', reverse('tcms.core.views.index')) )) if request.method == 'POST': form = RegistrationForm(data=request.POST, files=request.FILES) if form.is_valid(): form.save() ak = form.set_active_key() # Send email to user if mail server is available. if form.cleaned_data['email'] and settings.EMAIL_HOST: form.send_confirm_mail(request=request, active_key=ak) msg = 'Your account has been created, please check your ' \ 'mailbox for confirmation.' else: msg = [ '<p>Your account has been created, but you need to contact ' 'an administrator to active your account.</p>', ] # If can not send email, prompt to user. if settings.ADMINS: msg.append('<p>Following is the admin list</p><ul>') for name, email in settings.ADMINS: msg.append('<li><a href="mailto:{}">{}</a></li>'.format(email, name)) msg.append('</ul>') msg = ''.join(msg) return HttpResponse(Prompt.render( request=request, info_type=Prompt.Info, info=msg, next=request.POST.get('next', reverse('tcms.core.views.index')) )) else: form = RegistrationForm() context_data = { 'form': form, } return render_to_response(template_name, context_data, context_instance=RequestContext(request))
def update_case_run_text(request, run_id): """Update the IDLE cases to newest text""" tr = get_object_or_404(TestRun, run_id=run_id) if request.REQUEST.get('case_run'): tcrs = tr.case_run.filter(pk__in=request.REQUEST.getlist('case_run')) else: tcrs = tr.case_run.all() tcrs = tcrs.filter(case_run_status__name='IDLE') count = 0 updated_tcrs = '' for tcr in tcrs: lctv = tcr.latest_text().case_text_version if tcr.case_text_version != lctv: count += 1 updated_tcrs += '<li>%s: %s -> %s</li>' % ( tcr.case.summary, tcr.case_text_version, lctv ) tcr.case_text_version = lctv tcr.save() info = '<p>%s case run(s) succeed to update, following is the list:</p>\ <ul>%s</ul>' % (count, updated_tcrs) del tr, tcrs, count, updated_tcrs return HttpResponse(Prompt.render( request=request, info_type=Prompt.Info, info=info, next=reverse('tcms.apps.testruns.views.get', args=[run_id,]), ))
def printable(request, template_name='plan/printable.html'): """Create the printable copy for plan""" plan_pks = request.GET.getlist('plan') if not plan_pks: return HttpResponse( Prompt.render(request=request, info_type=Prompt.Info, info='At least one target is required.')) tps = TestPlan.objects.filter(pk__in=plan_pks).only('pk', 'name') def plan_generator(): repeat = len(plan_pks) params_sql = ','.join(itertools.repeat('%s', repeat)) sql = sqls.TP_PRINTABLE_CASE_TEXTS % (params_sql, params_sql) result_set = SQLExecution(sql, plan_pks * 2) group_data = itertools.groupby(result_set.rows, lambda data: data['plan_id']) cases_dict = dict((key, list(values)) for key, values in group_data) for tp in tps: tp.result_set = cases_dict.get(tp.plan_id, None) yield tp context_data = { 'test_plans': plan_generator(), } return render(request, template_name, context=context_data)
def order_case(request, run_id): """Resort case with new order""" # Current we should rewrite all of cases belong to the plan. # Because the cases sortkey in database is chaos, # Most of them are None. tr = get_object_or_404(TestRun, run_id=run_id) if not request.REQUEST.get('case_run'): return HttpResponse(Prompt.render( request = request, info_type = Prompt.Info, info = 'At least one case is required by re-oder in run.', next = reverse('tcms.apps.testruns.views.get', args=[run_id, ]), )) case_run_ids = request.REQUEST.getlist('case_run') tcrs = TestCaseRun.objects.filter(case_run_id__in=case_run_ids) for tcr in tcrs: new_sort_key = (case_run_ids.index(str(tcr.case_run_id)) + 1) * 10 if tcr.sortkey != new_sort_key: tcr.sortkey = new_sort_key tcr.save() return HttpResponseRedirect( reverse('tcms.apps.testruns.views.get', args=[run_id, ]) )
def printable(request, template_name='plan/printable.html'): '''Create the printable copy for plan''' plan_pks = request.GET.getlist('plan') if not plan_pks: return HttpResponse(Prompt.render( request=request, info_type=Prompt.Info, info='At least one target is required.')) tps = TestPlan.objects.filter(pk__in=plan_pks).only('pk', 'name') def plan_generator(): repeat = len(plan_pks) params_sql = ','.join(itertools.repeat('%s', repeat)) sql = sqls.TP_PRINTABLE_CASE_TEXTS % (params_sql, params_sql) result_set = SQLExecution(sql, plan_pks * 2) group_data = itertools.groupby(result_set.rows, lambda data: data['plan_id']) cases_dict = dict((key, list(values)) for key, values in group_data) for tp in tps: tp.result_set = cases_dict.get(tp.plan_id, None) yield tp context_data = { 'test_plans': plan_generator(), } return render_to_response(template_name, context_data, context_instance=RequestContext(request))
def post(self, request, plan_id): plan = get_object_or_404(TestPlan.objects.only('pk'), pk=int(plan_id)) xml_form = ImportCasesViaXMLForm(request.POST, request.FILES) if xml_form.is_valid(): plan.import_cases(xml_form.cleaned_data['xml_file']) return HttpResponseRedirect( reverse('plan-get', args=[plan_id]) + '#testcases') else: return HttpResponse( Prompt.render(request=request, info_type=Prompt.Alert, info=xml_form.errors, next=reverse('plan-get', args=[plan_id]) + '#testcases'))
def post(self, request, plan_id): plan = get_object_or_404(TestPlan.objects.only('pk'), pk=int(plan_id)) xml_form = ImportCasesViaXMLForm(request.POST, request.FILES) if xml_form.is_valid(): plan.import_cases(xml_form.cleaned_data['xml_file']) return HttpResponseRedirect( reverse('plan-get', args=[plan_id]) + '#testcases') else: return HttpResponse(Prompt.render( request=request, info_type=Prompt.Alert, info=xml_form.errors, next=reverse('plan-get', args=[plan_id]) + '#testcases' ))
def printable(request, template_name='plan/printable.html'): '''Create the printable copy for plan''' plan_pks = request.GET.getlist('plan') if not plan_pks: return Prompt.render(request=request, info_type=Prompt.Info, info='At least one target is required.') tps = TestPlan.objects.filter(pk__in=plan_pks).only('pk', 'name') def plan_generator(): cases_dict = {} cases_seen = [] for row in TestCaseText.objects.values( 'setup', 'action', 'effect', 'breakdown', 'case', 'case__summary', 'case__plan').filter(case__plan__in=plan_pks, case__case_status__name__in=[ 'PROPOSED', 'CONFIRMED', 'NEEDS_UPDATE' ]).order_by('case__plan', 'case', '-case_text_version'): plan_id = row['case__plan'] # start info for new plan if plan_id not in cases_dict: cases_dict[plan_id] = [] cases_seen = [] # continue adding cases to plan case_id = row['case'] # only latest case text version if case_id in cases_seen: continue cases_seen.append(case_id) cases_dict[plan_id].append(row) for tp in tps: tp.result_set = cases_dict.get(tp.plan_id, None) yield tp context_data = { 'test_plans': plan_generator(), } return render(request, template_name, context_data)
def export(request, template_name='plan/export.xml'): '''Export the plan''' plan_pks = request.GET.getlist('plan') if not plan_pks: return Prompt.render( request=request, info_type=Prompt.Info, info='At least one target is required.') timestamp = datetime.datetime.now() timestamp_str = '%02i-%02i-%02i' % (timestamp.year, timestamp.month, timestamp.day) context_data = { 'data_generator': generator_proxy(plan_pks), } response = render(request, template_name, context_data) response['Content-Disposition'] = 'attachment; filename=tcms-testcases-%s.xml' % timestamp_str return response
def export(request, template_name='plan/export.xml'): """Export the plan""" plan_pks = request.GET.getlist('plan') if not plan_pks: return HttpResponse(Prompt.render( request=request, info_type=Prompt.Info, info='At least one target is required.')) timestamp = datetime.datetime.now() timestamp_str = '%02i-%02i-%02i' % (timestamp.year, timestamp.month, timestamp.day) context_data = { 'data_generator': generator_proxy(plan_pks), } response = render(request, template_name, context=context_data) response['Content-Disposition'] = 'attachment; filename=tcms-testcases-%s.xml' % timestamp_str return response
def confirm(request, activation_key): """ Confirm the user registeration """ import datetime from django.contrib.auth import login # Get the object try: ak = UserActivateKey.objects.select_related('user') ak = ak.get(activation_key = activation_key) except UserActivateKey.DoesNotExist, error: msg = 'They key is no longer exist in database.' return HttpResponse(Prompt.render( request = request, info_type = Prompt.Info, info = msg, next = request.REQUEST.get('next', reverse('tcms.core.views.index')) ))
def check_file(request, file_id): """Download attachment file""" attachment = get_object_or_404(TestAttachment, pk=file_id) attachment_data = TestAttachmentData.objects.filter( attachment__attachment_id=file_id).first() # First try to read file content from database. if attachment_data: # File content is not written into TestAttachmentData in upload_file, # this code path is dead now. Think about if file content should be # written into database in the future. contents = attachment_data.contents else: # File was not written into database, read it from configured file # system. stored_file_name = os.path.join( settings.FILE_UPLOAD_DIR, unquote(attachment.stored_name or attachment.file_name)).replace('\\', '/') if not os.path.exists(stored_file_name): raise Http404( f'Attachment file {stored_file_name} does not exist.') try: with open(stored_file_name, 'rb') as f: contents = f.read() except IOError: msg = 'Cannot read attachment file from server.' log.exception(msg) return Prompt.render( request=request, info_type=Prompt.Alert, info=msg, next='javascript:window.history.go(-1);', ) response = HttpResponse(contents, content_type=str(attachment.mime_type)) file_name = smart_str(attachment.file_name) response['Content-Disposition'] = f'attachment; filename="{file_name}"' return response
def new_run_with_caseruns(request,run_id,template_name='run/clone.html'): """Clone cases from filter caserun""" SUB_MODULE_NAME = "runs" tr = get_object_or_404(TestRun, run_id=run_id) if request.REQUEST.get('case_run'): tcrs=tr.case_run.filter(pk__in=request.REQUEST.getlist('case_run')) else: tcrs=[] if not tcrs: return HttpResponse(Prompt.render( request=request, info_type=Prompt.Info, info='At least one case is required by a run', next = request.META.get('HTTP_REFERER', '/'))) estimated_time = reduce(lambda x, y: x + y, [tcr.case.estimated_time for tcr in tcrs]) if not request.REQUEST.get('submit'): form=RunCloneForm(initial={ 'summary':tr.summary, 'notes':tr.notes, 'manager':tr.manager.email, 'product':tr.plan.product_id, 'product_version':tr.get_version_id(), 'build':tr.build_id, 'default_tester':tr.default_tester_id and tr.default_tester.email or '', 'estimated_time': estimated_time, 'use_newest_case_text':True, }) form.populate(product_id=tr.plan.product_id) return direct_to_template(request,template_name,{ 'module':MODULE_NAME, 'sub_module':SUB_MODULE_NAME, 'clone_form':form, 'test_run':tr, 'cases_run':tcrs, })
def choose_run(request, plan_id, template_name='plan/choose_testrun.html'): '''Choose one run to add cases''' # Define the default sub module SUB_MODULE_NAME = 'runs' if request.method == 'GET': try: plan_id = int(plan_id) tp = TestPlan.objects.filter(pk=plan_id).defer('product_version')[0] except IndexError: raise Http404 testruns = TestRun.objects.filter(plan=plan_id).values('pk', 'summary', 'build__name', 'manager__username') # Ready to write cases to test plan tcs = get_selected_testcases(request) tcs = tcs.values('pk', 'summary', 'author__username', 'create_date', 'category__name', 'priority__value', ) context_data = { 'module': MODULE_NAME, 'sub_module': SUB_MODULE_NAME, 'plan_id': plan_id, 'plan': tp, 'test_runs': testruns.iterator(), 'test_cases': tcs.iterator(), } return render_to_response(template_name, context_data, context_instance=RequestContext(request)) # Add cases to runs if request.method == 'POST': choosed_testrun_ids = request.POST.getlist('testrun_ids') to_be_added_cases = TestCase.objects.filter(pk__in=request.POST.getlist('case_ids')) # cases and runs are required in this process if not len(choosed_testrun_ids) or not len(to_be_added_cases): return HttpResponse(Prompt.render( request=request, info_type=Prompt.Info, info='At least one test run and one case is required to add cases to runs.', next=reverse('tcms.testplans.views.get', args=[plan_id]), )) # Adding cases to runs by recursion for tr_id in choosed_testrun_ids: testrun = get_object_or_404(TestRun, run_id=tr_id) cases = TestCaseRun.objects.filter(run=tr_id) exist_cases_id = cases.values_list('case', flat=True) for testcase in to_be_added_cases: if testcase.case_id not in exist_cases_id: testrun.add_case_run(case=testcase) estimated_time = reduce(lambda x, y: x + y, [nc.estimated_time for nc in to_be_added_cases]) testrun.estimated_time = testrun.estimated_time + estimated_time testrun.save() return HttpResponseRedirect(reverse('tcms.testplans.views.get', args=[plan_id]))
def clone(request, template_name='plan/clone.html'): """Clone testplan""" SUB_MODULE_NAME = 'plans' req_data = request.GET or request.POST if 'plan' not in req_data: return HttpResponse(Prompt.render( request=request, info_type=Prompt.Info, info='At least one plan is required by clone function.', next='javascript:window.history.go(-1)', )) tps = TestPlan.objects.filter(pk__in=req_data.getlist('plan')) if not tps: return HttpResponse(Prompt.render( request=request, info_type=Prompt.Info, info='The plan you specify does not exist in database.', next='javascript:window.history.go(-1)', )) # Clone the plan if the form is submitted if request.method == "POST": clone_form = ClonePlanForm(request.POST) clone_form.populate(product_id=request.POST.get('product_id')) if clone_form.is_valid(): clone_options = clone_form.cleaned_data # Create new test plan. for tp in tps: new_name = len(tps) == 1 and clone_options['name'] or None clone_params = dict( # Cloned plan properties new_name=new_name, product=clone_options['product'], version=clone_options['product_version'], set_parent=clone_options['set_parent'], # Related data copy_texts=clone_options['copy_texts'], copy_attachments=clone_options['copy_attachements'], copy_environment_group=clone_options['copy_environment_group'], # Link or copy cases link_cases=clone_options['link_testcases'], copy_cases=clone_options['copy_testcases'], default_component_initial_owner=request.user, ) assign_me_as_plan_author = not clone_options['keep_orignal_author'] if assign_me_as_plan_author: clone_params['new_original_author'] = request.user assign_me_as_copied_case_author = \ clone_options['copy_testcases'] and \ not clone_options['maintain_case_orignal_author'] if assign_me_as_copied_case_author: clone_params['new_case_author'] = request.user assign_me_as_copied_case_default_tester = \ clone_options['copy_testcases'] and \ not clone_options['keep_case_default_tester'] if assign_me_as_copied_case_default_tester: clone_params['new_case_default_tester'] = request.user assign_me_as_text_author = not clone_options['copy_texts'] if assign_me_as_text_author: clone_params['default_text_author'] = request.user cloned_plan = tp.clone(**clone_params) if len(tps) == 1: return HttpResponseRedirect( reverse('tcms.testplans.views.get', args=[cloned_plan.plan_id])) else: args = { 'action': 'search', 'product': clone_form.cleaned_data['product'].id, 'product_version': clone_form.cleaned_data['product_version'].id, } url_args = urllib.urlencode(args) return HttpResponseRedirect( '{}?{}'.format(reverse('tcms.testplans.views.all'), url_args)) else: # Generate the default values for the form if len(tps) == 1: clone_form = ClonePlanForm(initial={ 'product': tps[0].product_id, 'product_version': tps[0].product_version_id, 'set_parent': True, 'copy_texts': True, 'copy_attachements': True, 'copy_environment_group': True, 'link_testcases': True, 'copy_testcases': False, 'maintain_case_orignal_author': True, 'keep_case_default_tester': False, 'name': tps[0].make_cloned_name(), }) clone_form.populate(product_id=tps[0].product.id) else: clone_form = ClonePlanForm(initial={ 'set_parent': True, 'copy_texts': True, 'copy_attachements': True, 'link_testcases': True, 'copy_testcases': False, 'maintain_case_orignal_author': True, 'keep_case_default_tester': True, }) context_data = { 'module': MODULE_NAME, 'sub_module': SUB_MODULE_NAME, 'testplans': tps, 'clone_form': clone_form, } return render_to_response(template_name, context_data, context_instance=RequestContext(request))
def clone(request, template_name='run/clone.html'): """Clone test run to another build""" SUB_MODULE_NAME = "runs" trs = TestRun.objects.select_related() trs = trs.filter(pk__in=request.REQUEST.getlist('run')) if not trs: return HttpResponse(Prompt.render( request = request, info_type = Prompt.Info, info = 'At least one run is required', next = request.META.get('HTTP_REFERER', '/') )) # Generate the clone run page for one run if len(trs) == 1 and not request.REQUEST.get('submit'): tr = trs[0] tcrs = tr.case_run.all() form = RunCloneForm(initial={ 'summary': tr.summary, 'notes': tr.notes, 'manager': tr.manager.email, 'product': tr.plan.product_id, 'product_version': tr.get_version_id(), 'build': tr.build_id, 'default_tester': tr.default_tester_id and tr.default_tester.email or '', 'use_newest_case_text': True, 'errata_id': tr.errata_id, }) form.populate(product_id=tr.plan.product_id) return direct_to_template(request, template_name, { 'module': MODULE_NAME, 'sub_module': SUB_MODULE_NAME, 'clone_form': form, 'test_run': tr, 'cases_run': tcrs, }) # Process multiple runs clone page template_name = 'run/clone_multiple.html' if request.method == "POST": form = MulitpleRunsCloneForm(request.REQUEST) form.populate(trs=trs, product_id=request.REQUEST.get('product')) if form.is_valid(): for tr in trs: n_tr = TestRun.objects.create( product_version=form.cleaned_data['product_version'].value, plan_text_version=tr.plan_text_version, summary=tr.summary, notes=tr.notes, estimated_time=tr.estimated_time, plan=tr.plan, build=form.cleaned_data['build'], manager=(form.cleaned_data['update_manager'] and form.cleaned_data['manager'] or tr.manager), default_tester=(form.cleaned_data['update_default_tester'] and form.cleaned_data['default_tester'] or tr.default_tester), ) for tcr in tr.case_run.all(): n_tr.add_case_run( case=tcr.case, assignee= tcr.assignee, case_text_version=(form.cleaned_data['update_case_text'] and bool(tcr.get_text_versions()) and tcr.get_text_versions()[0] or tcr.case_text_version), build=form.cleaned_data['build'], notes=tcr.notes, sortkey=tcr.sortkey, ) for env_value in tr.env_value.all(): n_tr.add_env_value(env_value) if form.cleaned_data['clone_cc']: for cc in tr.cc.all(): n_tr.add_cc(user=cc) if form.cleaned_data['clone_tag']: for tag in tr.tag.all(): n_tr.add_tag(tag=tag) if len(trs) == 1: return HttpResponseRedirect( reverse('tcms.apps.testruns.views.get', args=[n_tr.pk]) ) params = { 'product': form.cleaned_data['product'].pk, 'product_version': form.cleaned_data['product_version'].pk, 'build': form.cleaned_data['build'].pk} return HttpResponseRedirect('%s?%s' % ( reverse('tcms.apps.testruns.views.all'), urllib.urlencode(params, True) )) else: form = MulitpleRunsCloneForm(initial={ 'run': trs.values_list('pk', flat=True), 'manager': request.user, 'default_tester': request.user, 'assignee': request.user, 'update_manager': False, 'update_default_tester': True, 'update_assignee': True, 'update_case_text': True, 'clone_cc': True, 'clone_tag': True,}) form.populate(trs=trs) return direct_to_template(request, template_name, { 'module': MODULE_NAME, 'sub_module': SUB_MODULE_NAME, 'clone_form': form, })
def new(request, template_name='run/new.html'): """Display the create test run page.""" SUB_MODULE_NAME = "new_run" # If from_plan does not exist will redirect to plans for select a plan if not request.REQUEST.get('from_plan'): return HttpResponseRedirect(reverse('tcms.apps.testplans.views.all')) plan_id = request.REQUEST.get('from_plan') # Case is required by a test run if not request.REQUEST.get('case'): return HttpResponse(Prompt.render( request=request, info_type=Prompt.Info, info='At least one case is required by a run.', next=reverse('tcms.apps.testplans.views.get', args=[plan_id, ]), )) # Ready to write cases to test plan tcs = TestCase.objects.filter(case_id__in=request.REQUEST.getlist('case')) tp = TestPlan.objects.select_related().get(plan_id=plan_id) tcrs = TestCaseRun.objects.filter(case_run_id__in=request.REQUEST.getlist('case_run_id')) num_unconfirmed_cases = 0 for tc in tcs: # Hardcode here, the case_status_id is CONFIRMED if not tc.case_status.is_confirmed(): num_unconfirmed_cases += 1 if request.REQUEST.get('POSTING_TO_CREATE'): form = NewRunForm(request.POST) if request.REQUEST.get('product'): form.populate(product_id=request.REQUEST['product']) else: form.populate(product_id=tp.product_id) if form.is_valid(): # All validation rules pass # Process the data in form.cleaned_data default_tester = form.cleaned_data['default_tester'] tr = TestRun.objects.create( product_version=form.cleaned_data['product_version'], plan_text_version=tp.latest_text() and tp.latest_text().plan_text_version or 0, stop_date=None, summary=form.cleaned_data.get('summary'), notes=form.cleaned_data.get('notes'), plan=tp, build=form.cleaned_data['build'], manager=form.cleaned_data['manager'], default_tester=default_tester, estimated_time=form.cleaned_data['estimated_time'], errata_id=form.cleaned_data['errata_id'], auto_update_run_status = form.cleaned_data['auto_update_run_status'] ) keep_status = form.cleaned_data['keep_status'] keep_assign = form.cleaned_data['keep_assignee'] loop = 1 # not reserve assignee and status, assignee will default set to default_tester if not keep_assign and not keep_status: for case in form.cleaned_data['case']: try: tcp = TestCasePlan.objects.get(plan=tp, case=case) sortkey = tcp.sortkey except ObjectDoesNotExist, error: sortkey = loop * 10 try: assignee_tester = User.objects.get(username=default_tester) except ObjectDoesNotExist, error: assignee_tester = None tr.add_case_run(case=case, sortkey=sortkey, assignee=assignee_tester) loop += 1 # Add case to the run for tcr in tcrs: if (keep_status and keep_assign): tr.add_case_run(case=tcr.case, assignee=tcr.assignee, case_run_status=tcr.case_run_status, sortkey=tcr.sortkey or loop * 10) loop += 1 elif keep_status and not keep_assign: tr.add_case_run(case=tcr.case, case_run_status=tcr.case_run_status, sortkey=tcr.sortkey or loop * 10) loop += 1 elif keep_assign and not keep_status: tr.add_case_run(case=tcr.case, assignee=tcr.assignee, sortkey=tcr.sortkey or loop * 10) loop += 1 # Write the values into tcms_env_run_value_map table for key, value in request.REQUEST.items(): if key.startswith('select_property_id_'): try: property_id = key.split('_')[3] property_id = int(property_id) except IndexError, error: raise except ValueError, error: raise if request.REQUEST.get('select_property_value_%s' % property_id): try: value_id = int(request.REQUEST.get( 'select_property_value_%s' % property_id) ) except ValueError, error: raise TCMSEnvRunValueMap.objects.create( run=tr, value_id=request.REQUEST.get( 'select_property_value_%s' % property_id ), )
def clone(request, template_name='plan/clone.html'): """Clone testplan""" SUB_MODULE_NAME = 'plans' req_data = request.GET or request.POST if 'plan' not in req_data: return HttpResponse( Prompt.render( request=request, info_type=Prompt.Info, info='At least one plan is required by clone function.', next='javascript:window.history.go(-1)', )) tps = TestPlan.objects.filter(pk__in=req_data.getlist('plan')) if not tps: return HttpResponse( Prompt.render( request=request, info_type=Prompt.Info, info='The plan you specify does not exist in database.', next='javascript:window.history.go(-1)', )) # Clone the plan if the form is submitted if request.method == "POST": clone_form = ClonePlanForm(request.POST) clone_form.populate(product_id=request.POST.get('product_id')) if clone_form.is_valid(): clone_options = clone_form.cleaned_data # Create new test plan. for tp in tps: new_name = len(tps) == 1 and clone_options['name'] or None clone_params = dict( # Cloned plan properties new_name=new_name, product=clone_options['product'], version=clone_options['product_version'], set_parent=clone_options['set_parent'], # Related data copy_texts=clone_options['copy_texts'], copy_attachments=clone_options['copy_attachements'], copy_environment_group=clone_options[ 'copy_environment_group'], # Link or copy cases link_cases=clone_options['link_testcases'], copy_cases=clone_options['copy_testcases'], default_component_initial_owner=request.user, ) assign_me_as_plan_author = not clone_options[ 'keep_orignal_author'] if assign_me_as_plan_author: clone_params['new_original_author'] = request.user assign_me_as_copied_case_author = \ clone_options['copy_testcases'] and \ not clone_options['maintain_case_orignal_author'] if assign_me_as_copied_case_author: clone_params['new_case_author'] = request.user assign_me_as_copied_case_default_tester = \ clone_options['copy_testcases'] and \ not clone_options['keep_case_default_tester'] if assign_me_as_copied_case_default_tester: clone_params['new_case_default_tester'] = request.user assign_me_as_text_author = not clone_options['copy_texts'] if assign_me_as_text_author: clone_params['default_text_author'] = request.user cloned_plan = tp.clone(**clone_params) if len(tps) == 1: return HttpResponseRedirect( reverse('plan-get', args=[cloned_plan.plan_id])) else: args = { 'action': 'search', 'product': clone_form.cleaned_data['product'].id, 'product_version': clone_form.cleaned_data['product_version'].id, } url_args = urllib.parse.urlencode(args) return HttpResponseRedirect('{}?{}'.format( reverse('plans-all'), url_args)) else: # Generate the default values for the form if len(tps) == 1: clone_form = ClonePlanForm( initial={ 'product': tps[0].product_id, 'product_version': tps[0].product_version_id, 'set_parent': True, 'copy_texts': True, 'copy_attachements': True, 'copy_environment_group': True, 'link_testcases': True, 'copy_testcases': False, 'maintain_case_orignal_author': True, 'keep_case_default_tester': False, 'name': tps[0].make_cloned_name(), }) clone_form.populate(product_id=tps[0].product.id) else: clone_form = ClonePlanForm( initial={ 'set_parent': True, 'copy_texts': True, 'copy_attachements': True, 'link_testcases': True, 'copy_testcases': False, 'maintain_case_orignal_author': True, 'keep_case_default_tester': True, }) context_data = { 'module': MODULE_NAME, 'sub_module': SUB_MODULE_NAME, 'testplans': tps, 'clone_form': clone_form, } return render(request, template_name, context=context_data)
def choose_run(request, plan_id, template_name='plan/choose_testrun.html'): """Choose one run to add cases""" # Define the default sub module SUB_MODULE_NAME = 'runs' if request.method == 'GET': tp = get_object_or_404(TestPlan, plan_id=plan_id) testruns = TestRun.objects.filter(plan=plan_id) # Make sure there exists at least one testrun if not len(testruns): return HttpResponse( Prompt.render ( request=request, info_type=Prompt.Info, info='At least one test run is required for assigning the cases.', next=reverse ('tcms.apps.testplans.views.get', args=[plan_id, ]), )) #case is required by a test run if not request.REQUEST.get('case'): return HttpResponse(Prompt.render( request=request, info_type=Prompt.Info, info='At least one case is required by a run.', next=reverse('tcms.apps.testplans.views.get', args=[plan_id, ]), )) # Ready to write cases to test plan tcs_id = request.REQUEST.getlist('case') tcs = TestCase.objects.filter(case_id__in=tcs_id) return direct_to_template(request, template_name, { 'module': MODULE_NAME, 'sub_module': SUB_MODULE_NAME, 'plan_id': plan_id, 'plan': tp, 'test_run_list': testruns, 'test_cases': tcs, 'tcids': tcs_id, }) #Add cases to runs if request.method == 'POST': choosed_testrun_ids = request.REQUEST.getlist('testrun_ids') to_be_added_cases = TestCase.objects.filter(pk__in=request.REQUEST.getlist('case_ids')) # cases and runs are required in this process if not len(choosed_testrun_ids) or not len(to_be_added_cases): return HttpResponse(Prompt.render( request=request, info_type=Prompt.Info, info='At least one test run and one case is required to add cases to runs.', next=reverse('tcms.apps.testplans.views.get', args=[plan_id, ]), )) # Adding cases to runs by recursion for tr_id in choosed_testrun_ids: testrun = get_object_or_404(TestRun, run_id=tr_id) cases = TestCaseRun.objects.filter(run=tr_id) exist_cases_id = cases.values_list ('case', flat=True) for testcase in to_be_added_cases: if testcase.case_id not in exist_cases_id: testrun.add_case_run(case=testcase) estimated_time = reduce(lambda x, y: x + y, [nc.estimated_time for nc in to_be_added_cases]) testrun.estimated_time = testrun.estimated_time + estimated_time testrun.save() return HttpResponseRedirect ( reverse ( 'tcms.apps.testplans.views.get', args=[plan_id, ]) )
def upload_file(request): if request.FILES.get('upload_file'): import os from datetime import datetime from django.conf import settings from tcms.core.views import Prompt from tcms.apps.management.models import TestAttachment, TestAttachmentData try: upload_file = request.FILES['upload_file'] try: upload_file.name.decode('utf8') except UnicodeEncodeError: return HttpResponse( Prompt.render( request=request, info_type=Prompt.Alert, info='Upload File name is not legal.', next='javascript:window.history.go(-1);', )) now = datetime.now() stored_name = '%s-%s-%s' % (request.user.username, now, upload_file.name) stored_file_name = os.path.join(settings.FILE_UPLOAD_DIR, stored_name).replace('\\', '/') stored_file_name = smart_str(stored_file_name) if upload_file._size > settings.MAX_UPLOAD_SIZE: return HttpResponse( Prompt.render( request=request, info_type=Prompt.Alert, info='You upload entity is too large. \ Please ensure the file is less than %s bytes. \ ' % settings.MAX_UPLOAD_SIZE, next='javascript:window.history.go(-1);', )) # Create the upload directory when it's not exist try: os.listdir(settings.FILE_UPLOAD_DIR) except OSError: os.mkdir(settings.FILE_UPLOAD_DIR) # Write to a temporary file try: open(stored_file_name, 'ro') return HttpResponse( Prompt.render( request=request, info_type=Prompt.Alert, info='File named \'%s\' already exist in upload folder, \ please rename to another name for solve conflict.\ ' % upload_file.name, next='javascript:window.history.go(-1);', )) except IOError: pass dest = open(stored_file_name, 'wb+') for chunk in upload_file.chunks(): dest.write(chunk) dest.close() # Write the file to database #store_file = open(upload_file_name, 'ro') ta = TestAttachment.objects.create( submitter_id=request.user.id, description=request.REQUEST.get('description', None), file_name=upload_file.name, stored_name=stored_name, create_date=now, mime_type=upload_file.content_type) if request.REQUEST.get('to_plan_id'): from tcms.apps.testplans.models import TestPlanAttachment try: int(request.REQUEST['to_plan_id']) except ValueError, error: raise TestPlanAttachment.objects.create( plan_id=request.REQUEST.get('to_plan_id'), attachment_id=ta.attachment_id, ) return HttpResponseRedirect( reverse('tcms.apps.testplans.views.attachment', args=[request.REQUEST['to_plan_id']])\ ) elif request.REQUEST.get('to_case_id'): from tcms.apps.testcases.models import TestCaseAttachment try: int(request.REQUEST['to_case_id']) except ValueError, error: raise TestCaseAttachment.objects.create( attachment_id=ta.attachment_id, case_id=request.REQUEST['to_case_id']) return HttpResponseRedirect( reverse('tcms.apps.testcases.views.attachment', args=[request.REQUEST['to_case_id']]))
def import_cases(self): if request.method == 'POST': # Process import case from XML action if not request.user.has_perm('testcases.add_testcaseplan'): return HttpResponse(Prompt.render( request=request, info_type=Prompt.Alert, info='Permission denied', next=reverse('tcms.testplans.views.get', args=[plan_id]), )) xml_form = ImportCasesViaXMLForm(request.POST, request.FILES) if xml_form.is_valid(): i = 0 for case in xml_form.cleaned_data['xml_file']: i += 1 # Get the case category from the case and related to # the product of the plan try: category = TestCaseCategory.objects.get(product=tp.product, name=case['category_name']) except TestCaseCategory.DoesNotExist: category = TestCaseCategory.objects.create(product=tp.product, name=case['category_name']) # Start to create the objects tc = TestCase.objects.create( is_automated=case['is_automated'], script='', arguments='', summary=case['summary'], requirement='', alias='', estimated_time=0, case_status_id=case['case_status_id'], category_id=category.id, priority_id=case['priority_id'], author_id=case['author_id'], default_tester_id=case['default_tester_id'], notes=case['notes'], ) TestCasePlan.objects.create(plan=tp, case=tc, sortkey=i * 10) tc.add_text(case_text_version=1, author=case['author'], action=case['action'], effect=case['effect'], setup=case['setup'], breakdown=case['breakdown']) # handle tags if case['tags']: for tag in case['tags']: tc.add_tag(tag=tag) tc.add_to_plan(plan=tp) return HttpResponseRedirect( reverse('tcms.testplans.views.get', args=[plan_id]) + '#testcases') else: return HttpResponse(Prompt.render( request=request, info_type=Prompt.Alert, info=xml_form.errors, next=reverse('tcms.testplans.views.get', args=[plan_id]) + '#testcases' )) else: return HttpResponseRedirect( reverse('tcms.testplans.views.get', args=[plan_id]) + '#testcases')
info = msg, next = request.REQUEST.get('next', reverse('tcms.core.views.index')) )) # Check the key expires date #if ak.key_expires < datetime.datetime.today(): # ak.delete() # msg = 'They key is expired, please need re-register your account again.' # return HttpResponse(Prompt.render( # request = request, # info_type = Prompt.Info, # info = msg, # next = request.REQUEST.get('next', reverse('tcms.core.views.index')) # )) # All thing done, start to active the user and use the user login user = ak.user user.is_active = True user.save() ak.delete() # login(request, user) # Response to web browser. msg = 'Your accound has been activate successful, click next link to re-login.' return HttpResponse(Prompt.render( request = request, info_type = Prompt.Info, info = msg, next = request.REQUEST.get('next', reverse('tcms.apps.profiles.views.redirect_to_profile')) ))
def cases(request, plan_id): """Process the xml with import""" ajax_response = {'rc': 0, 'response': 'ok'} tp = get_object_or_404(TestPlan, plan_id=plan_id) class CaseActions(object): def __init__(self, request, tp): self.__all__ = ['link_cases', 'delete_cases', 'order_cases'] self.request = request self.tp = tp def link_cases(self, template_name='plan/search_case.html'): """Handle to form to add case to plans""" SUB_MODULE_NAME = 'plans' tcs = None if request.POST.get('action') == 'add_to_plan': if request.user.has_perm('testcases.add_testcaseplan'): tcs = TestCase.objects.filter( case_id__in=request.POST.getlist('case')) for tc in tcs: tp.add_case(tc) else: return HttpResponse("Permission Denied") return HttpResponseRedirect( reverse('test_plan_url_short', args=[plan_id])) search_mode = request.POST.get('search_mode') if request.POST.get('action') == 'search': if search_mode == 'quick': form = quick_form = QuickSearchCaseForm(request.POST) normal_form = SearchCaseForm() else: form = normal_form = SearchCaseForm(request.POST) form.populate(product_id=request.POST.get('product')) quick_form = QuickSearchCaseForm() if form.is_valid(): tcs = TestCase.list(form.cleaned_data) tcs = tcs.select_related( 'author', 'default_tester', 'case_status', 'priority').only('pk', 'summary', 'create_date', 'author__email', 'default_tester__email', 'case_status__name', 'priority__value') tcs = tcs.exclude( case_id__in=tp.case.values_list('case_id', flat=True)) else: normal_form = SearchCaseForm( initial={ 'product': tp.product_id, 'product_version': tp.product_version_id, 'case_status_id': TestCaseStatus.get_CONFIRMED() }) quick_form = QuickSearchCaseForm() context_data = { 'module': MODULE_NAME, 'sub_module': SUB_MODULE_NAME, 'test_plan': tp, 'test_cases': tcs, 'search_form': normal_form, 'quick_form': quick_form, 'search_mode': search_mode } return render(request, template_name, context_data) def delete_cases(self): if not request.POST.get('case'): ajax_response['rc'] = 1 ajax_response[ 'response'] = 'At least one case is required to delete.' return JsonResponse(ajax_response) tcs = get_selected_testcases(request) # Log Action tp_log = TCMSLog(model=tp) for tc in tcs: tp_log.make(who=request.user, action='Remove case %s from plan %s' % (tc.case_id, tp.plan_id)) tc.log_action(who=request.user, action='Remove from plan %s' % tp.plan_id) tp.delete_case(case=tc) return JsonResponse(ajax_response) def order_cases(self): """Resort case with new order""" # Current we should rewrite all of cases belong to the plan. # Because the cases sortkey in database is chaos, # Most of them are None. if not request.POST.get('case'): ajax_response['rc'] = 1 ajax_response[ 'response'] = 'At least one case is required to re-order.' return JsonResponse(ajax_response) tc_pks = request.POST.getlist('case') tcs = TestCase.objects.filter(pk__in=tc_pks) for tc in tcs: new_sort_key = (tc_pks.index(str(tc.pk)) + 1) * 10 TestCasePlan.objects.filter( plan=tp, case=tc).update(sortkey=new_sort_key) return JsonResponse(ajax_response) # tp = get_object_or_404(TestPlan, plan_id=plan_id) cas = CaseActions(request, tp) req_data = request.GET or request.POST action = req_data.get('a') if action not in cas.__all__: if request.GET.get('format') == 'json': ajax_response['rc'] = 1 ajax_response['response'] = 'Unrecognizable actions' return HttpResponse(json_dumps(ajax_response)) return Prompt.render( request=request, info_type=Prompt.Alert, info='Unrecognizable actions', next=reverse('test_plan_url_short', args=[plan_id]), ) func = getattr(cas, action) return func()
def choose_run(request, plan_id, template_name='plan/choose_testrun.html'): """Choose one run to add cases""" # Define the default sub module SUB_MODULE_NAME = 'runs' if request.method == 'GET': try: plan_id = int(plan_id) tp = TestPlan.objects.filter( pk=plan_id).defer('product_version')[0] except IndexError: raise Http404 testruns = TestRun.objects.filter(plan=plan_id).values( 'pk', 'summary', 'build__name', 'manager__username') # Ready to write cases to test plan tcs = get_selected_testcases(request) tcs = tcs.values( 'pk', 'summary', 'author__username', 'create_date', 'category__name', 'priority__value', ) context_data = { 'module': MODULE_NAME, 'sub_module': SUB_MODULE_NAME, 'plan_id': plan_id, 'plan': tp, 'test_runs': testruns.iterator(), 'test_cases': tcs.iterator(), } return render(request, template_name, context=context_data) # Add cases to runs if request.method == 'POST': choosed_testrun_ids = request.POST.getlist('testrun_ids') to_be_added_cases = TestCase.objects.filter( pk__in=request.POST.getlist('case_ids')) # cases and runs are required in this process if not len(choosed_testrun_ids) or not len(to_be_added_cases): return HttpResponse( Prompt.render( request=request, info_type=Prompt.Info, info= 'At least one test run and one case is required to add cases to runs.', next=reverse('plan-get', args=[plan_id]), )) # Adding cases to runs by recursion for tr_id in choosed_testrun_ids: testrun = get_object_or_404(TestRun, run_id=tr_id) cases = TestCaseRun.objects.filter(run=tr_id) exist_cases_id = cases.values_list('case', flat=True) for testcase in to_be_added_cases: if testcase.case_id not in exist_cases_id: testrun.add_case_run(case=testcase) estimated_time = six.moves.reduce( lambda x, y: x + y, [nc.estimated_time for nc in to_be_added_cases]) testrun.estimated_time = testrun.estimated_time + estimated_time testrun.save() return HttpResponseRedirect(reverse('plan-get', args=[plan_id]))
def upload_file(request): if request.FILES.get('upload_file'): upload_file = request.FILES['upload_file'] try: upload_file.name.encode('utf8') except UnicodeEncodeError: return HttpResponse(Prompt.render( request=request, info_type=Prompt.Alert, info='Upload File name is not legal.', next='javascript:window.history.go(-1);', )) now = datetime.now() stored_name = '%s-%s-%s' % (request.user.username, now, upload_file.name) stored_file_name = os.path.join( settings.FILE_UPLOAD_DIR, stored_name).replace('\\', '/') stored_file_name = smart_str(stored_file_name) if upload_file._size > settings.MAX_UPLOAD_SIZE: return HttpResponse(Prompt.render( request=request, info_type=Prompt.Alert, info='You upload entity is too large. \ Please ensure the file is less than %s bytes. \ ' % settings.MAX_UPLOAD_SIZE, next='javascript:window.history.go(-1);', )) # Create the upload directory when it's not exist try: os.listdir(settings.FILE_UPLOAD_DIR) except OSError: os.mkdir(settings.FILE_UPLOAD_DIR) # Write to a temporary file try: open(stored_file_name, 'ro') return HttpResponse(Prompt.render( request=request, info_type=Prompt.Alert, info='File named \'%s\' already exist in upload folder, \ please rename to another name for solve conflict.\ ' % upload_file.name, next='javascript:window.history.go(-1);', )) except IOError: pass dest = open(stored_file_name, 'wb+') for chunk in upload_file.chunks(): dest.write(chunk) dest.close() # Write the file to database # store_file = open(upload_file_name, 'ro') ta = TestAttachment.objects.create( submitter_id=request.user.id, description=request.POST.get('description', None), file_name=upload_file.name, stored_name=stored_name, create_date=now, mime_type=upload_file.content_type ) if request.POST.get('to_plan_id'): TestPlanAttachment.objects.create( plan_id=int(request.POST['to_plan_id']), attachment_id=ta.attachment_id, ) return HttpResponseRedirect( reverse('tcms.testplans.views.attachment', args=[request.POST['to_plan_id']]) ) elif request.POST.get('to_case_id'): TestCaseAttachment.objects.create( attachment_id=ta.attachment_id, case_id=int(request.POST['to_case_id']) ) return HttpResponseRedirect( reverse('tcms.testcases.views.attachment', args=[request.POST['to_case_id']]) ) else: try: return HttpResponseRedirect( reverse('tcms.testplans.views.attachment', args=[request.POST['to_plan_id']]) ) except KeyError: return HttpResponseRedirect( reverse('tcms.testcases.views.attachment', args=[request.POST['to_case_id']]) )
def clone(request, template_name='plan/clone.html'): """Clone testplan""" SUB_MODULE_NAME = 'plans' if not request.REQUEST.get('plan'): return HttpResponse(Prompt.render( request=request, info_type=Prompt.Info, info='At least one plan is required by clone function.', next='javascript:window.history.go(-1)', )) tps = TestPlan.objects.filter(pk__in=request.REQUEST.getlist('plan')) if not tps: return HttpResponse(Prompt.render( request=request, info_type=Prompt.Info, info='The plan you specific does not exist in database', next='javascript:window.history.go(-1)', )) # Clone the plan if the form is submitted if request.method == "POST": clone_form = ClonePlanForm(request.REQUEST) clone_form.populate(product_id=request.REQUEST.get('product_id')) if clone_form.is_valid(): # Create new test plan. for tp in tps: tp_dest = TestPlan.objects.create( product=clone_form.cleaned_data['product'], author=clone_form.cleaned_data['keep_orignal_author'] and tp.author or request.user, type=tp.type, default_product_version=clone_form.cleaned_data['default_product_version'], name = len(tps) == 1 and clone_form.cleaned_data['name'] or tp.name, create_date=tp.create_date, is_active=tp.is_active, extra_link=tp.extra_link, parent=clone_form.cleaned_data['set_parent'] and tp or None, ) # Copy the plan documents if clone_form.cleaned_data['copy_texts']: tptxts_src = tp.text.all() for tptxt_src in tptxts_src: tp_dest.add_text( plan_text_version=tptxt_src.plan_text_version, author=tptxt_src.author, create_date=tptxt_src.create_date, plan_text=tptxt_src.plan_text, ) else: tp_dest.add_text(author=request.user, plan_text='',) # Copy the plan tags for tp_tag_src in tp.tag.all(): tp_dest.add_tag(tag=tp_tag_src) # Copy the plan attachments if clone_form.cleaned_data['copy_attachements']: for tp_attach_src in tp.attachment.all(): tp_dest.add_attachment(attachment=tp_attach_src) # Copy the environment group if clone_form.cleaned_data['copy_environment_group']: for env_group in tp.env_group.all(): tp_dest.add_env_group(env_group=env_group) # Link the cases of the plan if clone_form.cleaned_data['link_testcases']: tpcases_src = tp.case.all() if clone_form.cleaned_data['copy_testcases']: for tpcase_src in tpcases_src: tcp = get_object_or_404(TestCasePlan, plan=tp, case=tpcase_src) if clone_form.cleaned_data['maintain_case_orignal_author']: author = tpcase_src.author else: author = request.user if clone_form.cleaned_data['keep_case_default_tester']: if hasattr(tpcase_src, 'default_tester'): default_tester = getattr(tpcase_src, 'default_tester') else: default_tester = None else: default_tester = request.user tc_category, b_created = TestCaseCategory.objects.get_or_create( name = tpcase_src.category.name, product = clone_form.cleaned_data['product'] ) tpcase_dest = TestCase.objects.create( create_date=tpcase_src.create_date, is_automated=tpcase_src.is_automated, script=tpcase_src.script, arguments=tpcase_src.arguments, summary=tpcase_src.summary, requirement=tpcase_src.requirement, alias=tpcase_src.alias, estimated_time=tpcase_src.estimated_time, case_status=TestCaseStatus.get_PROPOSED(), category=tc_category, priority=tpcase_src.priority, author=author, default_tester=default_tester, ) # Add case to plan. tp_dest.add_case(tpcase_dest, tcp.sortkey) for tc_tag_src in tpcase_src.tag.all(): tpcase_dest.add_tag(tag=tc_tag_src) for component in tpcase_src.component.filter(product__id=tp.product_id): try: new_c = tp_dest.product.component.get( name=component.name ) except ObjectDoesNotExist, error: new_c = tp_dest.product.component.create( name=component.name, initial_owner=request.user, description=component.description, ) tpcase_dest.add_component(new_c) text = tpcase_src.latest_text() if text: tpcase_dest.add_text( author=text.author, action=text.action, effect=text.effect, setup=text.setup, breakdown=text.breakdown, create_date=text.create_date, ) else: for tpcase_src in tpcases_src: tcp = get_object_or_404(TestCasePlan, plan=tp, case=tpcase_src) tp_dest.add_case(tpcase_src, tcp.sortkey) if len(tps) == 1: return HttpResponseRedirect( reverse('tcms.apps.testplans.views.get', args = [tp_dest.plan_id, ]) ) else: args = { 'action': 'search', 'product': clone_form.cleaned_data['product'].id, 'default_product_version': Version.string_to_id( product_id=clone_form.cleaned_data['product'].id, value=clone_form.cleaned_data['default_product_version'] ) } url_args = urllib.urlencode(args) return HttpResponseRedirect( reverse('tcms.apps.testplans.views.all') + '?' + url_args )
def upload_file(request): if 'to_plan_id' not in request.POST and 'to_case_id' not in request.POST: return HttpResponse(Prompt.render( request=request, info_type=Prompt.Alert, info='Uploading file works with plan or case. Nitrate cannot ' 'proceed with no plan or case ID.', next='javascript:window.history.go(-1);', )) if request.FILES.get('upload_file'): upload_file = request.FILES['upload_file'] try: upload_file.name.encode('utf8') except UnicodeEncodeError: return HttpResponse(Prompt.render( request=request, info_type=Prompt.Alert, info='Upload File name is not legal.', next='javascript:window.history.go(-1);', )) now = datetime.now() stored_name = '%s-%s-%s' % (request.user.username, now, upload_file.name) stored_file_name = os.path.join( settings.FILE_UPLOAD_DIR, stored_name).replace('\\', '/') stored_file_name = smart_str(stored_file_name) if upload_file.size > settings.MAX_UPLOAD_SIZE: return HttpResponse(Prompt.render( request=request, info_type=Prompt.Alert, info='You upload entity is too large. Please ensure the file is' ' less than {} bytes.'.format(settings.MAX_UPLOAD_SIZE), next='javascript:window.history.go(-1);', )) # Create the upload directory when it's not exist if not os.path.exists(settings.FILE_UPLOAD_DIR): os.mkdir(settings.FILE_UPLOAD_DIR) if os.path.exists(stored_file_name): return HttpResponse(Prompt.render( request=request, info_type=Prompt.Alert, info="File named '{}' already exists in upload folder, please " "rename to another name for solve conflict.".format( upload_file.name), next='javascript:window.history.go(-1);', )) with open(stored_file_name, 'wb+') as f: for chunk in upload_file.chunks(): f.write(chunk) # Write the file to database # store_file = open(upload_file_name, 'ro') ta = TestAttachment.objects.create( submitter_id=request.user.id, description=request.POST.get('description', None), file_name=upload_file.name, stored_name=stored_name, create_date=now, mime_type=upload_file.content_type ) if request.POST.get('to_plan_id'): TestPlanAttachment.objects.create( plan_id=int(request.POST['to_plan_id']), attachment_id=ta.attachment_id, ) return HttpResponseRedirect( reverse('plan-attachment', args=[request.POST['to_plan_id']]) ) if request.POST.get('to_case_id'): TestCaseAttachment.objects.create( attachment_id=ta.attachment_id, case_id=int(request.POST['to_case_id']) ) return HttpResponseRedirect( reverse('case-attachment', args=[request.POST['to_case_id']]) ) else: if 'to_plan_id' in request.POST: return HttpResponseRedirect( reverse('plan-attachment', args=[request.POST['to_plan_id']]) ) if 'to_case_id' in request.POST: return HttpResponseRedirect( reverse('case-attachment', args=[request.POST['to_case_id']]) )
"""Delete the test run - Maybe will be not use again """ try: tr = TestRun.objects.select_related('manager', 'plan__author').get( run_id=run_id ) except ObjectDoesNotExist, error: raise Http404 if not tr.belong_to(request.user): return HttpResponse(Prompt.render( request=request, info_type=Prompt.Info, info="Permission denied - The run is not belong to you.", next='javascript:window.history.go(-1)' )) if request.GET.get('sure', 'no') == 'no': return HttpResponse("<script>\n \ if(confirm('Are you sure you want to delete this run %s? \ \\n \\n \ Click OK to delete or cancel to come back')) \ { window.location.href='/run/%s/delete/?sure=yes' } \ else { history.go(-1) };</script>" % ( run_id, run_id)) elif request.GET.get('sure') == 'yes': try: plan_id = tr.plan_id tr.env_value.clear() tr.case_run.all().delete()
def post(self, request): to_plan_id = request.POST.get('to_plan_id') to_case_id = request.POST.get('to_case_id') if to_plan_id is None and to_case_id is None: return Prompt.render( request=request, info_type=Prompt.Alert, info='Uploading file works with plan or case. Nitrate cannot ' 'proceed with no plan or case ID.', next='javascript:window.history.go(-1);', ) if request.FILES.get('upload_file'): upload_file = request.FILES['upload_file'] try: upload_file.name.encode('utf8') except UnicodeEncodeError: return Prompt.render( request=request, info_type=Prompt.Alert, info='Upload File name is not legal.', next='javascript:window.history.go(-1);', ) now = datetime.now() stored_name = f'{request.user.username}-{now}-{upload_file.name}' stored_file_name = os.path.join(settings.FILE_UPLOAD_DIR, stored_name).replace('\\', '/') stored_file_name = smart_str(stored_file_name) if upload_file.size > settings.MAX_UPLOAD_SIZE: return Prompt.render( request=request, info_type=Prompt.Alert, info= f'You upload entity is too large. Please ensure the file is' f' less than {settings.MAX_UPLOAD_SIZE} bytes.', next='javascript:window.history.go(-1);', ) # Create the upload directory when it's not exist if not os.path.exists(settings.FILE_UPLOAD_DIR): os.mkdir(settings.FILE_UPLOAD_DIR) if os.path.exists(stored_file_name): return Prompt.render( request=request, info_type=Prompt.Alert, info=f"File named '{upload_file.name}' already exists in " f"upload folder, please rename to another name for " f"solve conflict.", next='javascript:window.history.go(-1);', ) with open(stored_file_name, 'wb+') as f: for chunk in upload_file.chunks(): f.write(chunk) # Write the file to database # store_file = open(upload_file_name, 'ro') ta = TestAttachment.objects.create( submitter_id=request.user.id, description=request.POST.get('description', None), file_name=upload_file.name, stored_name=stored_name, create_date=now, mime_type=upload_file.content_type) if request.POST.get('to_plan_id'): TestPlanAttachment.objects.create( plan_id=int(to_plan_id), attachment_id=ta.attachment_id, ) return HttpResponseRedirect( reverse('plan-attachment', args=[to_plan_id])) if request.POST.get('to_case_id'): TestCaseAttachment.objects.create( attachment_id=ta.attachment_id, case_id=int(to_case_id)) return HttpResponseRedirect( reverse('case-attachment', args=[to_case_id])) else: if 'to_plan_id' in request.POST: return HttpResponseRedirect( reverse('plan-attachment', args=[to_plan_id])) if 'to_case_id' in request.POST: return HttpResponseRedirect( reverse('case-attachment', args=[to_case_id]))
def cases(request, plan_id): """Process the xml with import""" ajax_response = {'rc': 0, 'response': 'ok'} tp = get_object_or_404(TestPlan, plan_id=plan_id) class CaseActions(object): def __init__(self, request, tp): self.__all__ = ['link_cases', 'delete_cases', 'order_cases', 'import_cases'] self.request = request self.tp = tp def link_cases(self, template_name='plan/search_case.html'): """Handle to form to add case to plans""" SUB_MODULE_NAME = 'plans' tcs = None if request.POST.get('action') == 'add_to_plan': if request.user.has_perm('testcases.add_testcaseplan'): tcs = TestCase.objects.filter(case_id__in=request.POST.getlist('case')) for tc in tcs: tp.add_case(tc) else: return HttpResponse("Permission Denied") return HttpResponseRedirect( reverse('tcms.testplans.views.get', args=[plan_id])) search_mode = request.POST.get('search_mode') if request.POST.get('action') == 'search': if search_mode == 'quick': form = quick_form = QuickSearchCaseForm(request.POST) normal_form = SearchCaseForm() else: form = normal_form = SearchCaseForm(request.POST) form.populate(product_id=request.POST.get('product')) quick_form = QuickSearchCaseForm() if form.is_valid(): tcs = TestCase.list(form.cleaned_data) tcs = tcs.select_related( 'author', 'default_tester', 'case_status', 'priority').only( 'pk', 'summary', 'create_date', 'author__email', 'default_tester__email', 'case_status__name', 'priority__value') tcs = tcs.exclude(case_id__in=tp.case.values_list('case_id', flat=True)) else: normal_form = SearchCaseForm(initial={ 'product': tp.product_id, 'product_version': tp.product_version_id, 'case_status_id': TestCaseStatus.get_CONFIRMED() }) quick_form = QuickSearchCaseForm() context_data = { 'module': MODULE_NAME, 'sub_module': SUB_MODULE_NAME, 'test_plan': tp, 'test_cases': tcs, 'search_form': normal_form, 'quick_form': quick_form, 'search_mode': search_mode } return render_to_response(template_name, context_data, context_instance=RequestContext(request)) def delete_cases(self): if not request.POST.get('case'): ajax_response['rc'] = 1 ajax_response['response'] = 'At least one case is required to delete.' return JsonResponse(ajax_response) tcs = get_selected_testcases(request) # Log Action tp_log = TCMSLog(model=tp) for tc in tcs: tp_log.make(who=request.user, action='Remove case %s from plan %s' % (tc.case_id, tp.plan_id)) tc.log_action(who=request.user, action='Remove from plan %s' % tp.plan_id) tp.delete_case(case=tc) return JsonResponse(ajax_response) def order_cases(self): """Resort case with new order""" # Current we should rewrite all of cases belong to the plan. # Because the cases sortkey in database is chaos, # Most of them are None. if not request.POST.get('case'): ajax_response['rc'] = 1 ajax_response['response'] = 'At least one case is required to re-order.' return JsonResponse(ajax_response) tc_pks = request.POST.getlist('case') tcs = TestCase.objects.filter(pk__in=tc_pks) for tc in tcs: new_sort_key = (tc_pks.index(str(tc.pk)) + 1) * 10 TestCasePlan.objects.filter(plan=tp, case=tc).update(sortkey=new_sort_key) return JsonResponse(ajax_response) def import_cases(self): if request.method == 'POST': # Process import case from XML action if not request.user.has_perm('testcases.add_testcaseplan'): return HttpResponse(Prompt.render( request=request, info_type=Prompt.Alert, info='Permission denied', next=reverse('tcms.testplans.views.get', args=[plan_id]), )) xml_form = ImportCasesViaXMLForm(request.POST, request.FILES) if xml_form.is_valid(): i = 0 for case in xml_form.cleaned_data['xml_file']: i += 1 # Get the case category from the case and related to # the product of the plan try: category = TestCaseCategory.objects.get(product=tp.product, name=case['category_name']) except TestCaseCategory.DoesNotExist: category = TestCaseCategory.objects.create(product=tp.product, name=case['category_name']) # Start to create the objects tc = TestCase.objects.create( is_automated=case['is_automated'], script='', arguments='', summary=case['summary'], requirement='', alias='', estimated_time=0, case_status_id=case['case_status_id'], category_id=category.id, priority_id=case['priority_id'], author_id=case['author_id'], default_tester_id=case['default_tester_id'], notes=case['notes'], ) TestCasePlan.objects.create(plan=tp, case=tc, sortkey=i * 10) tc.add_text(case_text_version=1, author=case['author'], action=case['action'], effect=case['effect'], setup=case['setup'], breakdown=case['breakdown']) # handle tags if case['tags']: for tag in case['tags']: tc.add_tag(tag=tag) tc.add_to_plan(plan=tp) return HttpResponseRedirect( reverse('tcms.testplans.views.get', args=[plan_id]) + '#testcases') else: return HttpResponse(Prompt.render( request=request, info_type=Prompt.Alert, info=xml_form.errors, next=reverse('tcms.testplans.views.get', args=[plan_id]) + '#testcases' )) else: return HttpResponseRedirect( reverse('tcms.testplans.views.get', args=[plan_id]) + '#testcases') # tp = get_object_or_404(TestPlan, plan_id=plan_id) cas = CaseActions(request, tp) req_data = request.GET or request.POST action = req_data.get('a') if action not in cas.__all__: if request.GET.get('format') == 'json': ajax_response['rc'] = 1 ajax_response['response'] = 'Unrecognizable actions' return HttpResponse(json_dumps(ajax_response)) return HttpResponse(Prompt.render( request=request, info_type=Prompt.Alert, info='Unrecognizable actions', next=reverse('tcms.testplans.views.get', args=[plan_id]), )) func = getattr(cas, action) return func()