Exemple #1
0
    def filter_plans(self):
        search_form = SearchPlanForm(self.request.GET)
        product_id = self.request.GET.get('product')
        search_form.populate(int(product_id) if product_id else None)

        plans = TestPlan.objects.none()

        if search_form.is_valid():
            # Determine the query is the user's plans and change the sub module value
            author = self.request.GET.get('author__email__startswith')
            req_user = self.request.user
            if req_user.is_authenticated and author in (req_user.username,
                                                        req_user.email):
                self.SUB_MODULE_NAME = "my_plans"

            plans = (TestPlan.list(search_form.cleaned_data).select_related(
                'author', 'type', 'product').order_by('-create_date'))

            plans = TestPlan.apply_subtotal(
                plans,
                cases_count=True,
                runs_count=True,
                children_count=True,
            )

        return search_form, plans
Exemple #2
0
def ajax_search(request, template_name='plan/common/json_plans.txt'):
    """Display all testplans"""
    # If it's not a search the page will be blank
    test_plans = TestPlan.objects.none()
    # if it's a search request the request will be full
    if request.GET:
        search_form = SearchPlanForm(request.GET)
        search_form.populate(product_id=request.GET.get('product'))

        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:
                        query = Q(author__email__startswith=author) | \
                            Q(owner__email__startswith=author)
                        test_plans = TestPlan.objects.filter(query).distinct()
            else:
                test_plans = TestPlan.list(search_form.cleaned_data)
                test_plans = test_plans.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, test_plans, column_names, template_name)
Exemple #3
0
def get_all(request):  # pylint: disable=missing-permission-required
    """Display all testplans"""
    # TODO: this function should be deleted
    # todo: this function can be replaced with the existing JSON-RPC search
    # 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')
            tps = order_plan_queryset(tps, order_by, asc)
    else:
        # Set search active plans only by default
        search_form = SearchPlanForm(initial={'is_active': True})

    template_name = 'non-existing.html'

    # used in tree preview only
    # fixme: must be replaced by JSON RPC and the
    # JavaScript dialog that displays the preview
    # should be converted to Patternfly
    # todo: when this is done SearchPlanForm must contain only the
    # fields which are used in search.html
    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)
Exemple #4
0
def search(request):
    form = SearchPlanForm(request.GET)
    form.populate(product_id=request.GET.get('product'))

    context_data = {
        'form': form,
        'plan_types': PlanType.objects.all().only('pk', 'name').order_by('name'),
    }
    return render(request, 'testplans/search.html', context_data)
Exemple #5
0
    def get_context_data(self, **kwargs):
        form = SearchPlanForm(self.request.GET)
        form.populate(product_id=self.request.GET.get("product"))

        context_data = {
            "form": form,
        }

        return context_data
Exemple #6
0
    def get_context_data(self, **kwargs):
        form = SearchPlanForm(self.request.GET)
        form.populate(product_id=self.request.GET.get('product'))

        context_data = {
            'form': form,
            'plan_types': PlanType.objects.all().only('pk', 'name').order_by('name'),
        }

        return context_data
Exemple #7
0
    def get_context_data(self, **kwargs):
        form = SearchPlanForm(self.request.GET)
        form.populate(product_id=self.request.GET.get("product"))

        context_data = {
            "form":
            form,
            "plan_types":
            PlanType.objects.all().only("pk", "name").order_by("name"),
        }

        return context_data
Exemple #8
0
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')
Exemple #9
0
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)
Exemple #10
0
def 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)
        if request.GET.get('product'):
            search_form.populate(product_id=request.GET['product'])
        else:
            search_form.populate()

        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_url_path'] = obj.get_url_path()

            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)
Exemple #11
0
def get_all(request):
    """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')
            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')

    # test plan TreeView
    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']:
                dict_obj[attr] = getattr(obj, attr)
            dict_obj['plan_url'] = reverse('test_plan_url_short',
                                           args=[obj.pk])

            results.append(dict_obj)
        return JsonResponse(results, safe=False)

    # used in tree preview
    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)
Exemple #12
0
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 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')
            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':
        data = [
            dict(
                pk=plan.pk,
                name=plan.name,
                is_active=plan.is_active,
                parent_id=plan.parent_id,
                num_cases=plan.num_cases,
                num_runs=plan.num_runs,
                num_children=plan.num_children,
                get_url_path=plan.get_absolute_url(),
            ) for plan in tps
        ]
        return JsonResponse(data, 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 = {
        '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(request, template_name, context=context_data)
Exemple #13
0
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))