Exemple #1
0
def unlink_plan(requst, case_id, plan_id):
    """
    Description: Unlink a test case from the given plan. If only one plan is linked, this will delete
                 the test case.

    Params:      $case_ids - Integer/String: An integer or alias representing the ID in the database.
                 $plan_id  - Integer: An integer representing the ID in the database.

    Returns:     Array: Array of plans hash still linked if any, empty if not.

    Example:
    >>> TestCase.unlink_plan(12345, 137)
    """
    from tcms.apps.testplans.models import TestPlan
    try:
        tc = TestCase.objects.get(case_id = case_id)
        tp = tc.plan.get(plan_id = plan_id)
    except:
        raise

    tc.remove_plan(plan = tp)

    plan_ids = tc.plan.values_list('plan_id', flat = True)
    query = {'plan_id__in': plan_ids}
    return TestPlan.to_xmlrpc(query)
    def test_to_xmlrpc(self):
        result = TestPlan.to_xmlrpc(query={'pk__in': self.plan_pks})
        self.assertEqual(len(result), 2)

        # Verify fields
        sample_testplan = result[0]
        sample_fields = set([name for name in sample_testplan.keys()])
        test_fields = set(self.test_fields)
        test_result = list(sample_fields ^ test_fields)
        self.assertEqual(test_result, [])

        result = dict([(item['plan_id'], item) for item in result])

        plan = result[self.plan_pks[0]]
        sample_plan = TestPlan.objects.get(pk=self.plan_pks[0])

        self.assertEqual(plan['default_product_version'],
                         sample_plan.default_product_version)
        self.assertEqual(plan['name'], sample_plan.name)
        self.assertEqual(plan['is_active'], sample_plan.is_active)

        components = plan['component']
        components.sort()
        sample_components = [item.pk for item in sample_plan.component.all()]
        sample_components.sort()
        self.assertEqual(components, sample_components)

        plan = result[self.plan_pks[1]]
        sample_plan = TestPlan.objects.get(pk=self.plan_pks[1])

        self.assertEqual(plan['default_product_version'],
                         sample_plan.default_product_version)
        self.assertEqual(plan['name'], sample_plan.name)
        self.assertEqual(plan['is_active'], sample_plan.is_active)
Exemple #3
0
def ajax_search(request, template_name='plan/common/json_plans.txt'):
    """Display all testplans"""
    # Define the default sub module
    SUB_MODULE_NAME = 'plans'

    # If it's not a search the page will be blank
    tps = TestPlan.objects.none()
    query_result = False
    # if it's a search request the page will be fill
    if request.REQUEST.items():
        search_form = SearchPlanForm(request.REQUEST)
        if request.REQUEST.get('product'):
            search_form.populate(product_id=request.REQUEST['product'])
        else:
            search_form.populate()
        if search_form.is_valid():
            # Detemine the query is the user's plans and change the sub module value
            if request.REQUEST.get('author__email__startswith') and len(search_form.changed_data) == 1:
                if request.user.is_authenticated():
                    if request.REQUEST['author__email__startswith'] == request.user.username \
                    or request.REQUEST['author__email__startswith'] == request.user.email:
                        user_email = request.REQUEST['author__email__startswith']
                        tps = TestPlan.objects.filter(Q(author__email__startswith=user_email)
                                                    | Q(owner__email__startswith=user_email)).distinct()
            else:
                tps = TestPlan.list(search_form.cleaned_data)
                tps = tps.select_related('author', 'type', 'product')

            query_result = True

            # 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,
            })
    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})
    #columnIndexNameMap is required for correct sorting behavior, 5 should be product, but we use run.build.product
    columnIndexNameMap = { 0: '', 1: 'plan_id', 2: 'name', 3: 'author__username', 4: 'owner__username',
                          5: 'product', 6: 'default_product_version', 7: 'type', 8: 'num_cases',
                          9: 'num_runs', 10: ''}
    return ajax_response(request, tps, columnIndexNameMap, jsonTemplatePath='plan/common/json_plans.txt')
Exemple #4
0
def get_plans(request, case_id):
    """
    Description: Get the list of plans that this case is linked to.

    Params:      $case_id - Integer/String: An integer representing the ID in the database

    Returns:     Array: An array of test plan object hashes.

    Example:
    >>> TestCase.get_plans(12345)
    """
    from tcms.apps.testplans.models import TestPlan
    try:
        tc = TestCase.objects.get(case_id = case_id)
    except:
        raise

    plan_ids = tc.plan.values_list('plan_id', flat = True)
    query = {'plan_id__in': plan_ids}
    return TestPlan.to_xmlrpc(query)
Exemple #5
0
def get_plans(request, product):
    """
    Description: Get the list of plans associated with this product.

    Params:      $product - Integer/String
                            Integer: product_id of the product in the Database
                            String: Product name

    Returns:     Array: Returns an array of Test Plan objects.

    Example:
    # Get with product id
    >>> Product.get_plans(61)
    # Get with product name
    >>> Product.get_plans('Red Hat Enterprise Linux 5')
    """
    from tcms.apps.testplans.models import TestPlan
    p = pre_check_product(values = product)
    query = {'product': p}
    return TestPlan.to_xmlrpc(query)
Exemple #6
0
def unlink_plan(requst, case_id, plan_id):
    """
    Description: Unlink a test case from the given plan. If only one plan is linked, this will delete
                 the test case.

    Params:      $case_ids - Integer/String: An integer or alias representing the ID in the database.
                 $plan_id  - Integer: An integer representing the ID in the database.

    Returns:     Array: Array of plans hash still linked if any, empty if not.

    Example:
    >>> TestCase.unlink_plan(12345, 137)
    """
    sql = 'DELETE FROM test_case_plans WHERE plan_id = %s and case_id = %s'
    cursor = connection.cursor()
    cursor.execute(sql, [int(plan_id), int(case_id)])
    transaction.commit_unless_managed()

    plan_pks = TestCasePlan.objects.filter(case=case_id).values_list('plan',
                                                                     flat=True)
    return TestPlan.to_xmlrpc(query={'pk__in': plan_pks})
Exemple #7
0
def filter(request, values = {}):
    """
    Description: Performs a search and returns the resulting list of test plans.

    Params:      $values - Hash: keys must match valid search fields.

        +------------------------------------------------------------+
        |                   Plan Search Parameters                   |
        +----------------------------------------------------------+
        |        Key              |          Valid Values            |
        | author                  | ForeignKey: Auth.User            |
        | attachment              | ForeignKey: Attachment           |
        | case                    | ForeignKey: Test Case            |
        | create_date             | DateTime                         |
        | default_product_version | String                           |
        | env_group               | ForeignKey: Environment Group    |
        | name                    | String                           |
        | plan_id                 | Integer                          |
        | product                 | ForeignKey: Product              |
        | tag                     | ForeignKey: Tag                  |
        | text                    | ForeignKey: Test Plan Text       |
        | type                    | ForeignKey: Test Plan Type       |
        +------------------------------------------------------------+

    Returns:     Array: Matching test plans are retuned in a list of plan object hashes.

    Example:
    # Get all of plans contain 'TCMS' in name
    >>> TestPlan.filter({'name__icontain': 'TCMS'})
    # Get all of plans create by xkuang
    >>> TestPlan.filter({'author__username': '******'})
    # Get all of plans the author name starts with x
    >>> TestPlan.filter({'author__username__startswith': 'x'})
    # Get plans contain the case ID 12345, 23456, 34567
    >>> TestPlan.filter({'case__case_id__in': [12345, 23456, 34567]})
    """
    return TestPlan.to_xmlrpc(values)
Exemple #8
0
def update(request, plan_ids, values):
    """
    Description: Updates the fields of the selected test plan.

    Params:      $plan_ids - Integer: A single TestPlan ID.

                 $values - Hash of keys matching TestPlan fields and the new values
                           to set each field to.
       +------------------------+----------------+------------------------------------+
      | Field                   | Type           | Description                        |
      +-------------------------+----------------+------------------------------------+
      | product                 | Integer        | ID of product                      |
      | name                    | String         |                                    |
      | type                    | Integer        | ID of plan type                    |
      | default_product_version | Integer        |                                    |
      | parent                  | Integer        | Parent plan ID                     |
      | is_active               | Boolean        | True/False                         |
      | env_group               | Integer        |                                    |
      +-------------------------+----------------+------------------------------------+

    Returns:     Hash: The updated test plan object.

    Example:
    # Update product to 61 for plan 207 and 208
    >>> TestPlan.update([207, 208], {'product': 61})
    """
    from tcms.core import forms
    from tcms.apps.testplans.forms import XMLRPCEditPlanForm

    if values.get('is_active') in (False, True):
        if values.get('is_active') == False:
            values['is_active'] = 0
        else:
            values['is_active'] = 1

    form = XMLRPCEditPlanForm(values)
    if values.get('default_product_version') and not values.get('product'):
        raise ValueError('Product value is required by default product version')

    if values.get('default_product_version') and values.get('product'):
        form.populate(product_id = values['product'])

    tps = TestPlan.objects.filter(pk__in = pre_process_ids(value = plan_ids))

    if form.is_valid():
        if form.cleaned_data['name']:
            tps.update(name = form.cleaned_data['name'])

        if form.cleaned_data['type']:
            tps.update(type = form.cleaned_data['type'])

        if form.cleaned_data['product']:
            tps.update(product = form.cleaned_data['product'])

        if form.cleaned_data['default_product_version']:
            tps.update(default_product_version = form.cleaned_data['default_product_version'])

        if form.cleaned_data['parent']:
            tps.update(parent = form.cleaned_data['parent'])

        if isinstance(form.cleaned_data['is_active'], int):
            tps.update(is_active = form.cleaned_data['is_active'])

        if form.cleaned_data['env_group']:
            for tp in tps:
                tp.clear_env_groups()
                tp.add_env_group(form.cleaned_data['env_group'])
    else:
        return forms.errors_to_list(form)

    query = {'pk__in': tps.values_list('pk', flat = True)}
    return TestPlan.to_xmlrpc(query)
Exemple #9
0
def update(request, plan_ids, values):
    """
    Description: Updates the fields of the selected test plan.

    Params:      $plan_ids - Integer: A single TestPlan ID.

                 $values - Hash of keys matching TestPlan fields and the new values
                           to set each field to.
       +------------------------+----------------+------------------------------------+
      | Field                   | Type           | Description                        |
      +-------------------------+----------------+------------------------------------+
      | product                 | Integer        | ID of product                      |
      | name                    | String         |                                    |
      | type                    | Integer        | ID of plan type                    |
      | default_product_version | Integer        |                                    |
      | parent                  | Integer        | Parent plan ID                     |
      | is_active               | Boolean        | True/False                         |
      | env_group               | Integer        |                                    |
      +-------------------------+----------------+------------------------------------+

    Returns:     Hash: The updated test plan object.

    Example:
    # Update product to 61 for plan 207 and 208
    >>> TestPlan.update([207, 208], {'product': 61})
    """
    from tcms.core import forms
    from tcms.apps.testplans.forms import XMLRPCEditPlanForm

    if values.get('is_active') in (False, True):
        if values.get('is_active') == False:
            values['is_active'] = 0
        else:
            values['is_active'] = 1

    form = XMLRPCEditPlanForm(values)
    if values.get('default_product_version') and not values.get('product'):
        raise ValueError(
            'Product value is required by default product version')

    if values.get('default_product_version') and values.get('product'):
        form.populate(product_id=values['product'])

    tps = TestPlan.objects.filter(pk__in=pre_process_ids(value=plan_ids))

    if form.is_valid():
        _values = dict()
        if form.cleaned_data['name']:
            _values['name'] = form.cleaned_data['name']

        if form.cleaned_data['type']:
            _values['type'] = form.cleaned_data['type']

        if form.cleaned_data['product']:
            _values['product'] = form.cleaned_data['product']

        if form.cleaned_data['default_product_version']:
            _values['default_product_version'] = form.cleaned_data[
                'default_product_version']

        if form.cleaned_data['parent']:
            _values['parent'] = form.cleaned_data['parent']

        if isinstance(form.cleaned_data['is_active'], int):
            _values['is_active'] = form.cleaned_data['is_active']

        tps.update(**_values)

        if form.cleaned_data['env_group']:
            for tp in tps.iterator():
                tp.clear_env_groups()
                tp.add_env_group(form.cleaned_data['env_group'])
    else:
        raise ValueError(forms.errors_to_list(form))

    query = {'pk__in': tps.values_list('pk', flat=True)}
    return TestPlan.to_xmlrpc(query)
Exemple #10
0
def all(request, template_name='plan/all.html'):
    """Display all testplans"""
    # Define the default sub module
    SUB_MODULE_NAME = 'plans'

    # If it's not a search the page will be blank
    tps = TestPlan.objects.none()
    query_result = False
    order_by = request.REQUEST.get('order_by', 'create_date')
    asc = bool(request.REQUEST.get('asc', None))
    # if it's a search request the page will be fill
    if request.REQUEST.items():
        search_form = SearchPlanForm(request.REQUEST)
        if request.REQUEST.get('product'):
            search_form.populate(product_id=request.REQUEST['product'])
        else:
            search_form.populate()

        if search_form.is_valid():
            # Detemine the query is the user's plans and change the sub module value
            if request.REQUEST.get('author'):
                if request.user.is_authenticated():
                    if request.REQUEST['author'] == request.user.username \
                    or request.REQUEST['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.REQUEST.get('action') == 'clone_case':
        template_name = 'case/clone_select_plan.html'
        tps = tps.order_by('name')

    if request.REQUEST.get('t') == 'ajax':
        return HttpResponse(serializers.serialize(
            request.REQUEST.get('f', 'json'),
            tps,
            extras=('num_cases','num_runs', 'num_children', 'get_url_path')
        ))

    if request.REQUEST.get('t') == 'html':
        if request.REQUEST.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.REQUEST.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')
    return direct_to_template(request, template_name, {
        '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
    })