def ajax_search(request, template_name='plan/common/json_plans.txt'): """Display all testplans""" # Define the default sub module # If it's not a search the page will be blank tps = TestPlan.objects.none() # if it's a search request the page will be fill if list(request.GET.items()): search_form = SearchPlanForm(request.GET) if request.GET.get('product'): search_form.populate(product_id=request.GET['product']) else: search_form.populate() if search_form.is_valid(): # Detemine the query is the user's plans and change the sub # module value author = request.GET.get('author__email__startswith') if author and len(search_form.changed_data) == 1: if request.user.is_authenticated(): if author == request.user.username or author == request.user.email: q = Q(author__email__startswith=author) | \ Q(owner__email__startswith=author) tps = TestPlan.objects.filter(q).distinct() else: tps = TestPlan.list(search_form.cleaned_data) tps = tps.select_related('author', 'owner', 'type', 'product') # columnIndexNameMap is required for correct sorting behavior, 5 should # be product, but we use run.build.product column_names = [ '', 'plan_id', 'name', 'author__username', 'owner__username', 'product', 'product_version', 'type', 'num_cases', 'num_runs', '' ] return ajax_response(request, tps, column_names, 'plan/common/json_plans.txt')
def clone(request, template_name='case/clone.html'): """Clone one case or multiple case into other plan or plans""" request_data = getattr(request, request.method) if 'selectAll' not in request_data and 'case' not in request_data: messages.add_message(request, messages.ERROR, _('At least one TestCase is required')) # redirect back where we came from return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/')) test_plan_src = plan_from_request_or_none(request) test_plan = None search_plan_form = SearchPlanForm() # Do the clone action if request.method == 'POST': clone_form = CloneCaseForm(request.POST) clone_form.populate(case_ids=request.POST.getlist('case')) if clone_form.is_valid(): tcs_src = clone_form.cleaned_data['case'] for tc_src in tcs_src: if clone_form.cleaned_data['copy_case']: tc_dest = TestCase.objects.create( is_automated=tc_src.is_automated, script=tc_src.script, arguments=tc_src.arguments, extra_link=tc_src.extra_link, summary=tc_src.summary, requirement=tc_src.requirement, case_status=TestCaseStatus.get_proposed(), category=tc_src.category, priority=tc_src.priority, notes=tc_src.notes, text=tc_src.text, author=clone_form. cleaned_data['maintain_case_orignal_author'] and tc_src.author or request.user, default_tester=clone_form. cleaned_data['maintain_case_orignal_default_tester'] and tc_src.author or request.user, ) for test_plan in clone_form.cleaned_data['plan']: # copy a case and keep origin case's sortkey if test_plan_src: try: tcp = TestCasePlan.objects.get( plan=test_plan_src, case=tc_src) sortkey = tcp.sortkey except ObjectDoesNotExist: sortkey = test_plan.get_case_sortkey() else: sortkey = test_plan.get_case_sortkey() test_plan.add_case(tc_dest, sortkey) for tag in tc_src.tag.all(): tc_dest.add_tag(tag=tag) else: tc_dest = tc_src tc_dest.author = request.user if clone_form.cleaned_data['maintain_case_orignal_author']: tc_dest.author = tc_src.author tc_dest.default_tester = request.user if clone_form.cleaned_data[ 'maintain_case_orignal_default_tester']: tc_dest.default_tester = tc_src.default_tester tc_dest.save() for test_plan in clone_form.cleaned_data['plan']: # create case link and keep origin plan's sortkey if test_plan_src: try: tcp = TestCasePlan.objects.get( plan=test_plan_src, case=tc_dest) sortkey = tcp.sortkey except ObjectDoesNotExist: sortkey = test_plan.get_case_sortkey() else: sortkey = test_plan.get_case_sortkey() test_plan.add_case(tc_dest, sortkey) # Add the cases to plan for test_plan in clone_form.cleaned_data['plan']: # Clone the categories to new product if clone_form.cleaned_data['copy_case']: try: tc_category = test_plan.product.category.get( name=tc_src.category.name) except ObjectDoesNotExist: tc_category = test_plan.product.category.create( name=tc_src.category.name, description=tc_src.category.description, ) tc_dest.category = tc_category tc_dest.save() del tc_category # Clone the components to new product if clone_form.cleaned_data['copy_component'] and \ clone_form.cleaned_data['copy_case']: for component in tc_src.component.all(): try: new_c = test_plan.product.component.get( name=component.name) except ObjectDoesNotExist: new_c = test_plan.product.component.create( name=component.name, initial_owner=request.user, description=component.description, ) tc_dest.add_component(new_c) # Detect the number of items and redirect to correct one cases_count = len(clone_form.cleaned_data['case']) plans_count = len(clone_form.cleaned_data['plan']) if cases_count == 1 and plans_count == 1: return HttpResponseRedirect( '%s?from_plan=%s' % (reverse('testcases-get', args=[ tc_dest.pk, ]), test_plan.pk)) if cases_count == 1: return HttpResponseRedirect( reverse('testcases-get', args=[ tc_dest.pk, ])) if plans_count == 1: return HttpResponseRedirect( reverse('test_plan_url_short', args=[ test_plan.pk, ])) # Otherwise it will prompt to user the clone action is successful. messages.add_message(request, messages.SUCCESS, _('TestCase cloning was successful')) return HttpResponseRedirect(reverse('plans-search')) else: selected_cases = get_selected_testcases(request) # Initial the clone case form clone_form = CloneCaseForm( initial={ 'case': selected_cases, 'copy_case': False, 'maintain_case_orignal_author': False, 'maintain_case_orignal_default_tester': False, 'copy_component': True, }) clone_form.populate(case_ids=selected_cases) # Generate search plan form if request_data.get('from_plan'): test_plan = TestPlan.objects.get(plan_id=request_data['from_plan']) search_plan_form = SearchPlanForm(initial={ 'product': test_plan.product_id, 'is_active': True }) search_plan_form.populate(product_id=test_plan.product_id) submit_action = request_data.get('submit', None) context = { 'test_plan': test_plan, 'search_form': search_plan_form, 'clone_form': clone_form, 'submit_action': submit_action, } return render(request, template_name, context)
def all(request, template_name='plan/all.html'): '''Display all testplans''' # Define the default sub module SUB_MODULE_NAME = 'plans' # TODO: this function now only performs a forward feature, no queries # need here. All of it will be removed in the future. # If it's not a search the page will be blank tps = TestPlan.objects.none() query_result = False order_by = request.GET.get('order_by', 'create_date') asc = bool(request.GET.get('asc', None)) # if it's a search request the page will be fill if request.GET.items(): search_form = SearchPlanForm(request.GET) if request.GET.get('product'): search_form.populate(product_id=request.GET['product']) else: search_form.populate() if search_form.is_valid(): # Detemine the query is the user's plans and change the sub # module value author = request.GET.get('author') if author and request.user.is_authenticated(): if author == request.user.username or author == request.user.email: SUB_MODULE_NAME = "my_plans" query_result = True # build a QuerySet: tps = TestPlan.list(search_form.cleaned_data) tps = tps.select_related('author', 'type', 'product') # We want to get the number of cases and runs, without doing # lots of per-test queries. # # Ideally we would get the case/run counts using m2m field tricks # in the ORM # Unfortunately, Django's select_related only works on ForeignKey # relationships, not on ManyToManyField attributes # See http://code.djangoproject.com/ticket/6432 # SQLAlchemy can handle this kind of thing in several ways. # Unfortunately we're using Django # The cleanest way I can find to get it into one query is to # use QuerySet.extra() # See http://docs.djangoproject.com/en/dev/ref/models/querysets tps = tps.extra(select={ 'num_cases': RawSQL.num_cases, 'num_runs': RawSQL.num_runs, 'num_children': RawSQL.num_plans, }) tps = order_plan_queryset(tps, order_by, asc) else: # Set search active plans only by default # I wish to use 'default' argument, as the same as in ModelForm # But it does not seem to work search_form = SearchPlanForm(initial={'is_active': True}) if request.GET.get('action') == 'clone_case': template_name = 'case/clone_select_plan.html' tps = tps.order_by('name') if request.GET.get('t') == 'ajax': return HttpResponse(serializers.serialize( request.GET.get('f', 'json'), tps, extras=('num_cases', 'num_runs', 'num_children', 'get_url_path') )) if request.GET.get('t') == 'html': if request.GET.get('f') == 'preview': template_name = 'plan/preview.html' query_url = remove_from_request_path(request, 'order_by') if asc: query_url = remove_from_request_path(query_url, 'asc') else: query_url = '%s&asc=True' % query_url page_type = request.GET.get('page_type', 'pagination') query_url_page_type = remove_from_request_path(request, 'page_type') if query_url_page_type: query_url_page_type = remove_from_request_path(query_url_page_type, 'page') context_data = { 'module': MODULE_NAME, 'sub_module': SUB_MODULE_NAME, 'test_plans': tps, 'query_result': query_result, 'search_plan_form': search_form, 'query_url': query_url, 'query_url_page_type': query_url_page_type, 'page_type': page_type } return render_to_response(template_name, context_data, context_instance=RequestContext(request))
def get_all(request, template_name='plan/all.html'): """Display all testplans""" # TODO: this function now only performs a forward feature, no queries # need here. All of it will be removed in the future. # If it's not a search the page will be blank tps = TestPlan.objects.none() query_result = False order_by = request.GET.get('order_by', 'create_date') asc = bool(request.GET.get('asc', None)) # if it's a search request the page will be fill if request.GET: search_form = SearchPlanForm(request.GET) search_form.populate(product_id=request.GET.get('product')) if search_form.is_valid(): query_result = True # build a QuerySet: tps = TestPlan.list(search_form.cleaned_data) tps = tps.select_related('author', 'type', 'product') # We want to get the number of cases and runs, without doing # lots of per-test queries. # # Ideally we would get the case/run counts using m2m field tricks # in the ORM # Unfortunately, Django's select_related only works on ForeignKey # relationships, not on ManyToManyField attributes # See http://code.djangoproject.com/ticket/6432 # SQLAlchemy can handle this kind of thing in several ways. # Unfortunately we're using Django # The cleanest way I can find to get it into one query is to # use QuerySet.extra() # See http://docs.djangoproject.com/en/dev/ref/models/querysets tps = tps.extra( select={ 'num_cases': RawSQL.num_cases, 'num_runs': RawSQL.num_runs, 'num_children': RawSQL.num_plans, }) tps = order_plan_queryset(tps, order_by, asc) else: # Set search active plans only by default search_form = SearchPlanForm(initial={'is_active': True}) if request.GET.get('action') == 'clone_case': template_name = 'case/clone_select_plan.html' tps = tps.order_by('name') if request.GET.get('t') == 'ajax': results = [] for obj in tps: dict_obj = model_to_dict(obj, fields=('name', 'parent', 'is_active')) for attr in [ 'pk', 'num_cases', 'num_cases', 'num_runs', 'num_children' ]: dict_obj[attr] = getattr(obj, attr) dict_obj['get_full_url'] = obj.get_full_url() results.append(dict_obj) return JsonResponse(results, safe=False) if request.GET.get('t') == 'html': if request.GET.get('f') == 'preview': template_name = 'plan/preview.html' query_url = remove_from_request_path(request, 'order_by') if asc: query_url = remove_from_request_path(query_url, 'asc') else: query_url = '%s&asc=True' % query_url page_type = request.GET.get('page_type', 'pagination') query_url_page_type = remove_from_request_path(request, 'page_type') if query_url_page_type: query_url_page_type = remove_from_request_path(query_url_page_type, 'page') context_data = { 'test_plans': tps, 'query_result': query_result, 'search_plan_form': search_form, 'query_url': query_url, 'query_url_page_type': query_url_page_type, 'page_type': page_type } return render(request, template_name, context_data)