| #!/usr/bin/env python |
| # -*- coding: UTF-8 -*- |
| |
| # Licensed to the Apache Software Foundation (ASF) under one |
| # or more contributor license agreements. See the NOTICE file |
| # distributed with this work for additional information |
| # regarding copyright ownership. The ASF licenses this file |
| # to you under the Apache License, Version 2.0 (the |
| # "License"); you may not use this file except in compliance |
| # with the License. You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, |
| # software distributed under the License is distributed on an |
| # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| # KIND, either express or implied. See the License for the |
| # specific language governing permissions and limitations |
| # under the License. |
| |
| |
| r"""Project dashboard for Apache(TM) Bloodhound |
| |
| In this file you'll find part of the tests written to ensure that |
| widgets displaying contents generated by TracReports behave as expected. |
| |
| Only the tests requiring minimal setup effort are included below. |
| This means that the environment used to run these tests contains the |
| barely minimal information included in an environment (i.e. only the |
| data specified by `trac.db_default.get_data`.). |
| |
| Once the tests are started all built-in components (except |
| trac.versioncontrol.* ) as well as widget system and extensions |
| are loaded. Besides the following values are (auto-magically) |
| made available in the global namespace (i.e. provided that |
| the test name be written like `|widget_name: Descriptive message`): |
| |
| - __tester__ An instance of `unittest.TestCase` representing the |
| test case for the statement under test. Useful |
| when specific assertions (e.g. `assertEquals`) |
| are needed. |
| - req A dummy request object setup for anonymous access. |
| - auth_req A dummy request object setup like if user `murphy` was |
| accessing the site. |
| - env the Trac environment used as a stub for testing purposes. |
| This object is an instance of |
| `bhdashboard.tests.EnvironmentStub`. |
| - widget the widget provider under test. |
| - ctx context used to render widget for anonymous user. |
| - ctx_auth context used to render widget for `murphy` user. |
| - ticket_data A set of tickets used for testing purposes. |
| """ |
| |
| #------------------------------------------------------ |
| # Test artifacts |
| #------------------------------------------------------ |
| |
| from bhdashboard.tests import trac_version, trac_tags |
| |
| def test_suite(): |
| from doctest import NORMALIZE_WHITESPACE, ELLIPSIS, REPORT_UDIFF |
| from dutest import MultiTestLoader |
| from unittest import defaultTestLoader |
| |
| from bhdashboard.tests import DocTestWidgetLoader, ticket_data |
| |
| magic_vars = dict(ticket_data=ticket_data) |
| if trac_version < (0, 13): # FIXME: Should it be (0, 12) ? |
| kwargs = {'enable': ['trac.[a-uw-z]*', 'tracrpc.*', 'bhdashboard.*']} |
| else: |
| kwargs = { |
| 'enable': ['trac.*', 'tracrpc.*', 'bhdashboard.*'], |
| 'disable': ['trac.versioncontrol.*'] |
| } |
| |
| l = MultiTestLoader( |
| [defaultTestLoader, \ |
| DocTestWidgetLoader(extraglobs=magic_vars, \ |
| default_data=True, \ |
| optionflags=ELLIPSIS | REPORT_UDIFF | \ |
| NORMALIZE_WHITESPACE, \ |
| **kwargs) \ |
| ]) |
| |
| import sys |
| return l.loadTestsFromModule(sys.modules[__name__]) |
| |
| #------------------------------------------------------ |
| # Helper functions |
| #------------------------------------------------------ |
| |
| from datetime import datetime, time, date |
| from itertools import izip |
| from pprint import pprint |
| |
| from bhdashboard.tests import clear_perm_cache |
| |
| def print_report_metadata(report_desc): |
| for attrnm in ('id', 'title', 'description', 'query'): |
| print attrnm.capitalize() |
| print '-' * len(attrnm) |
| print report_desc[attrnm] |
| |
| def print_report_columns(cols): |
| for coldsc in cols: |
| print 'Column:', coldsc[0], 'Type:', coldsc[1] or '_', \ |
| 'Label:', |
| try : |
| print coldsc[2] or '_' |
| except IndexError : |
| print '_' |
| |
| def print_report_result(cols, data): |
| for i, row in enumerate(data): |
| print '= Row', i, '=' |
| for coldsc in cols: |
| colnm = coldsc[0] |
| print 'Column:', colnm, 'Value:', row.get(colnm) or None, '' |
| |
| TICKET_ATTRS = ('summary', 'description', 'priority', \ |
| 'milestone', 'type', 'owner', 'status', \ |
| 'component', 'version') |
| |
| def prepare_ticket_workflow(tcktrpc, ticket_data, auth_req): |
| r"""Set ticket status considering the actions defined in standard |
| ticket workflow. Needed for TracRpc>=1.0.6 |
| """ |
| from time import sleep |
| |
| TICKET_ACTIONS = {'accepted': 'accept', 'closed' : 'resolve', |
| 'assigned': 'reassign'} |
| sleep(1) |
| for idx, (_, __, td) in enumerate(ticket_data) : |
| action = TICKET_ACTIONS.get(td.get('status')) |
| if action is not None : |
| aux_attrs = {'action' : action} |
| aux_attrs.update(td) |
| tcktrpc.update(auth_req, idx + 1, "", aux_attrs) |
| sleep(1) |
| for idx, (_, __, td) in enumerate(ticket_data) : |
| tcktrpc.update(auth_req, idx + 1, "", td) |
| |
| __test__ = { |
| 'Initialization: Report widgets' : r""" |
| >>> from trac.core import ComponentMeta |
| >>> from bhdashboard.api import IWidgetProvider |
| >>> from bhdashboard.widgets.report import * |
| >>> allcls = ComponentMeta._registry.get(IWidgetProvider, []) |
| >>> [wpcls in allcls for wpcls in (TicketReportWidget,)] |
| [True] |
| """, |
| '|TicketReport: Metadata' : r""" |
| >>> list(widget.get_widgets()) |
| ['TicketReport'] |
| >>> params = widget.get_widget_params('TicketReport') |
| >>> pprint(params) |
| {'id': {'desc': 'Report number', |
| 'required': True, |
| 'type': <type 'int'>}, |
| 'page': {'default': 1, |
| 'desc': 'Retrieve results in given page.', |
| 'type': <type 'int'>}, |
| 'user': {'desc': 'Render the report for a given user.'}} |
| """, |
| '|TicketReport: Render My Tickets report' : r""" |
| |
| Add tickets |
| |
| >>> from tracrpc.ticket import TicketRPC |
| >>> tcktrpc = TicketRPC(env) |
| >>> for td in ticket_data : |
| ... tcktrpc.create(auth_req, *td) |
| ... |
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
| 7 |
| 8 |
| 9 |
| |
| >>> if all(tcktrpc.get(auth_req, tid)[-1].get('status') == 'new' \ |
| ... for tid in xrange(1, 10)): |
| ... # RPC considers ticket workflow |
| ... prepare_ticket_workflow(tcktrpc, ticket_data, auth_req) |
| ... |
| |
| Check everything is ok with tickets |
| |
| >>> for tid in xrange(1, 10): |
| ... d = tcktrpc.get(auth_req, tid)[-1] |
| ... print tuple(d.get(attr) or '' for attr in TICKET_ATTRS) |
| ... |
| (u'Ticket 1', u'Description 1', u'major', u'milestone1', |
| u'defect', u'murphy', u'accepted', u'component1', u'1.0') |
| (u'Ticket 2', u'Description 2', u'major', u'milestone4', |
| u'task', u'murphy', u'accepted', '', '') |
| (u'Ticket 3', u'Description 3', u'critical', u'milestone3', |
| u'enhancement', u'tester', u'new', '', u'2.0') |
| (u'Ticket 4', u'Description 4', u'minor', u'milestone3', |
| u'task', u'murphy', u'closed', u'component1', u'1.0') |
| (u'Ticket 5', u'Description 5', u'minor', u'milestone3', |
| u'task', u'murphy', u'new', '', u'2.0') |
| (u'Ticket 6', u'Description 6', u'minor', u'milestone1', |
| u'task', u'tester', u'assigned', u'component2', u'1.0') |
| (u'Ticket 7', u'Description 7', u'critical', '', u'enhancement', |
| u'murphy', u'closed', '', '') |
| (u'Ticket 8', u'Description 8', u'major', '', u'task', |
| u'murphy', u'closed', u'component1', '') |
| (u'Ticket 9', u'Description 9', u'minor', '', u'enhancement', |
| u'tester', u'closed', '', u'2.0') |
| |
| >>> pprint(widget.render_widget('TicketReport', ctx, { |
| ... 'args' : {'id' : 7} |
| ... })) |
| ... |
| ('widget_grid.html', |
| {'data': {'action': 'view', |
| 'args': {'USER': 'anonymous'}, |
| 'context': <...Context <Resource u'report:7'>>, |
| 'description': u'\nThis report demonstrates the use of the automatically set \nUSER dynamic variable, replaced with the username of the\nlogged in user when executed.\n', |
| 'email_map': {}, |
| 'header_groups': [[{'asc': False, |
| 'col': u'__color__', |
| 'hidden': True, |
| 'title': u'Color'}, |
| {'asc': False, |
| 'col': u'__group__', |
| 'hidden': True, |
| 'title': u'Group'}, |
| {'asc': False, |
| 'col': u'ticket', |
| 'hidden': False, |
| 'title': u'Ticket'}, |
| {'asc': False, |
| 'col': u'summary', |
| 'hidden': False, |
| 'title': u'Summary'}, |
| {'asc': False, |
| 'col': u'component', |
| 'hidden': False, |
| 'title': u'Component'}, |
| {'asc': False, |
| 'col': u'version', |
| 'hidden': False, |
| 'title': u'Version'}, |
| {'asc': False, |
| 'col': u'milestone', |
| 'hidden': False, |
| 'title': u'Milestone'}, |
| {'asc': False, |
| 'col': u'type', |
| 'hidden': False, |
| 'title': u'Type'}, |
| {'asc': False, |
| 'col': u'priority', |
| 'hidden': False, |
| 'title': u'Priority'}, |
| {'asc': False, |
| 'col': u'created', |
| 'hidden': False, |
| 'title': u'Created'}, |
| {'asc': False, |
| 'col': u'_changetime', |
| 'hidden': True, |
| 'title': u'Changetime'}, |
| {'asc': False, |
| 'col': u'_description', |
| 'hidden': True, |
| 'title': u'Description'}, |
| {'asc': False, |
| 'col': u'_reporter', |
| 'hidden': True, |
| 'title': u'Reporter'}]], |
| 'message': None, |
| 'numrows': 0, |
| 'paginator': <trac.util.presentation.Paginator object at ...>, |
| 'report': {'id': 7, 'resource': <Resource u'report:7'>}, |
| 'row_groups': [], |
| 'sorting_enabled': False, |
| 'title': u'{7} My Tickets'}, |
| 'title': <Element "a">}, |
| <...Context <Resource u'report:7'>>) |
| |
| >>> template, data, rptctx = widget.render_widget('TicketReport', auth_ctx, { |
| ... 'args' : {'id' : 7} |
| ... }) |
| ... |
| >>> data = data['data'] |
| >>> template |
| 'widget_grid.html' |
| >>> rptctx.parent is auth_ctx |
| True |
| |
| In Trac=0.13 (0.12 ?) My Tickets report adds another group |
| So perform common check in here ... |
| |
| >>> reported_tickets = None |
| >>> for x in data['row_groups']: |
| ... if x[0] == 'Reported': |
| ... reported_tickets = x |
| ... break |
| ... |
| >>> if reported_tickets: |
| ... data['row_groups'].remove(reported_tickets) |
| ... |
| >>> pprint(data) |
| {'action': 'view', |
| 'args': {'USER': 'murphy'}, |
| 'context': <Context <Resource u'report:7'>>, |
| 'description': u'\nThis report demonstrates the use of the automatically set \nUSER dynamic variable, replaced with the username of the\nlogged in user when executed.\n', |
| 'email_map': {}, |
| 'header_groups': [[{'asc': False, |
| 'col': u'__color__', |
| 'hidden': True, |
| 'title': u'Color'}, |
| {'asc': False, |
| 'col': u'__group__', |
| 'hidden': True, |
| 'title': u'Group'}, |
| {'asc': False, |
| 'col': u'ticket', |
| 'hidden': False, |
| 'title': u'Ticket'}, |
| {'asc': False, |
| 'col': u'summary', |
| 'hidden': False, |
| 'title': u'Summary'}, |
| {'asc': False, |
| 'col': u'component', |
| 'hidden': False, |
| 'title': u'Component'}, |
| {'asc': False, |
| 'col': u'version', |
| 'hidden': False, |
| 'title': u'Version'}, |
| {'asc': False, |
| 'col': u'milestone', |
| 'hidden': False, |
| 'title': u'Milestone'}, |
| {'asc': False, |
| 'col': u'type', |
| 'hidden': False, |
| 'title': u'Type'}, |
| {'asc': False, |
| 'col': u'priority', |
| 'hidden': False, |
| 'title': u'Priority'}, |
| {'asc': False, |
| 'col': u'created', |
| 'hidden': False, |
| 'title': u'Created'}, |
| {'asc': False, |
| 'col': u'_changetime', |
| 'hidden': True, |
| 'title': u'Changetime'}, |
| {'asc': False, |
| 'col': u'_description', |
| 'hidden': True, |
| 'title': u'Description'}, |
| {'asc': False, |
| 'col': u'_reporter', |
| 'hidden': True, |
| 'title': u'Reporter'}]], |
| 'message': None, |
| 'numrows': 3, |
| 'paginator': <trac.util.presentation.Paginator object at ...>, |
| 'report': {'id': 7, 'resource': <Resource u'report:7'>}, |
| 'row_groups': [(u'Accepted', |
| [{u'__color__': u'3', |
| '__idx__': 0, |
| 'cell_groups': [[{'header': {'asc': False, |
| 'col': u'__color__', |
| 'hidden': True, |
| 'title': u'Color'}, |
| 'index': 0, |
| 'value': u'3'}, |
| {'header': {'asc': False, |
| 'col': u'__group__', |
| 'hidden': True, |
| 'title': u'Group'}, |
| 'index': 1, |
| 'value': u'Accepted'}, |
| {'header': {'asc': False, |
| 'col': u'ticket', |
| 'hidden': False, |
| 'title': u'Ticket'}, |
| 'index': 2, |
| 'value': u'1'}, |
| {'header': {'asc': False, |
| 'col': u'summary', |
| 'hidden': False, |
| 'title': u'Summary'}, |
| 'index': 3, |
| 'value': u'Ticket 1'}, |
| {'header': {'asc': False, |
| 'col': u'component', |
| 'hidden': False, |
| 'title': u'Component'}, |
| 'index': 4, |
| 'value': u'component1'}, |
| {'header': {'asc': False, |
| 'col': u'version', |
| 'hidden': False, |
| 'title': u'Version'}, |
| 'index': 5, |
| 'value': u'1.0'}, |
| {'header': {'asc': False, |
| 'col': u'milestone', |
| 'hidden': False, |
| 'title': u'Milestone'}, |
| 'index': 6, |
| 'value': u'milestone1'}, |
| {'header': {'asc': False, |
| 'col': u'type', |
| 'hidden': False, |
| 'title': u'Type'}, |
| 'index': 7, |
| 'value': u'defect'}, |
| {'header': {'asc': False, |
| 'col': u'priority', |
| 'hidden': False, |
| 'title': u'Priority'}, |
| 'index': 8, |
| 'value': u'major'}, |
| {'header': {'asc': False, |
| 'col': u'created', |
| 'hidden': False, |
| 'title': u'Created'}, |
| 'index': 9, |
| 'value': u'...'}, |
| {'header': {'asc': False, |
| 'col': u'_changetime', |
| 'hidden': True, |
| 'title': u'Changetime'}, |
| 'index': 10, |
| 'value': u'...'}, |
| {'header': {'asc': False, |
| 'col': u'_description', |
| 'hidden': True, |
| 'title': u'Description'}, |
| 'index': 11, |
| 'value': u'Description 1'}, |
| {'header': {'asc': False, |
| 'col': u'_reporter', |
| 'hidden': True, |
| 'title': u'Reporter'}, |
| 'index': 12, |
| 'value': u'murphy'}]], |
| 'id': u'1', |
| 'resource': <Resource u'ticket:1'>}, |
| {u'__color__': u'3', |
| '__idx__': 1, |
| 'cell_groups': [[{'header': {'asc': False, |
| 'col': u'__color__', |
| 'hidden': True, |
| 'title': u'Color'}, |
| 'index': 0, |
| 'value': u'3'}, |
| {'header': {'asc': False, |
| 'col': u'__group__', |
| 'hidden': True, |
| 'title': u'Group'}, |
| 'index': 1, |
| 'value': u'Accepted'}, |
| {'header': {'asc': False, |
| 'col': u'ticket', |
| 'hidden': False, |
| 'title': u'Ticket'}, |
| 'index': 2, |
| 'value': u'2'}, |
| {'header': {'asc': False, |
| 'col': u'summary', |
| 'hidden': False, |
| 'title': u'Summary'}, |
| 'index': 3, |
| 'value': u'Ticket 2'}, |
| {'header': {'asc': False, |
| 'col': u'component', |
| 'hidden': False, |
| 'title': u'Component'}, |
| 'index': 4, |
| 'value': ''}, |
| {'header': {'asc': False, |
| 'col': u'version', |
| 'hidden': False, |
| 'title': u'Version'}, |
| 'index': 5, |
| 'value': ''}, |
| {'header': {'asc': False, |
| 'col': u'milestone', |
| 'hidden': False, |
| 'title': u'Milestone'}, |
| 'index': 6, |
| 'value': u'milestone4'}, |
| {'header': {'asc': False, |
| 'col': u'type', |
| 'hidden': False, |
| 'title': u'Type'}, |
| 'index': 7, |
| 'value': u'task'}, |
| {'header': {'asc': False, |
| 'col': u'priority', |
| 'hidden': False, |
| 'title': u'Priority'}, |
| 'index': 8, |
| 'value': u'major'}, |
| {'header': {'asc': False, |
| 'col': u'created', |
| 'hidden': False, |
| 'title': u'Created'}, |
| 'index': 9, |
| 'value': u'...'}, |
| {'header': {'asc': False, |
| 'col': u'_changetime', |
| 'hidden': True, |
| 'title': u'Changetime'}, |
| 'index': 10, |
| 'value': u'...'}, |
| {'header': {'asc': False, |
| 'col': u'_description', |
| 'hidden': True, |
| 'title': u'Description'}, |
| 'index': 11, |
| 'value': u'Description 2'}, |
| {'header': {'asc': False, |
| 'col': u'_reporter', |
| 'hidden': True, |
| 'title': u'Reporter'}, |
| 'index': 12, |
| 'value': u'murphy'}]], |
| 'id': u'2', |
| 'resource': <Resource u'ticket:2'>}]), |
| (u'Owned', |
| [{u'__color__': u'4', |
| '__idx__': 2, |
| 'cell_groups': [[{'header': {'asc': False, |
| 'col': u'__color__', |
| 'hidden': True, |
| 'title': u'Color'}, |
| 'index': 0, |
| 'value': u'4'}, |
| {'header': {'asc': False, |
| 'col': u'__group__', |
| 'hidden': True, |
| 'title': u'Group'}, |
| 'index': 1, |
| 'value': u'Owned'}, |
| {'header': {'asc': False, |
| 'col': u'ticket', |
| 'hidden': False, |
| 'title': u'Ticket'}, |
| 'index': 2, |
| 'value': u'5'}, |
| {'header': {'asc': False, |
| 'col': u'summary', |
| 'hidden': False, |
| 'title': u'Summary'}, |
| 'index': 3, |
| 'value': u'Ticket 5'}, |
| {'header': {'asc': False, |
| 'col': u'component', |
| 'hidden': False, |
| 'title': u'Component'}, |
| 'index': 4, |
| 'value': ''}, |
| {'header': {'asc': False, |
| 'col': u'version', |
| 'hidden': False, |
| 'title': u'Version'}, |
| 'index': 5, |
| 'value': u'2.0'}, |
| {'header': {'asc': False, |
| 'col': u'milestone', |
| 'hidden': False, |
| 'title': u'Milestone'}, |
| 'index': 6, |
| 'value': u'milestone3'}, |
| {'header': {'asc': False, |
| 'col': u'type', |
| 'hidden': False, |
| 'title': u'Type'}, |
| 'index': 7, |
| 'value': u'task'}, |
| {'header': {'asc': False, |
| 'col': u'priority', |
| 'hidden': False, |
| 'title': u'Priority'}, |
| 'index': 8, |
| 'value': u'minor'}, |
| {'header': {'asc': False, |
| 'col': u'created', |
| 'hidden': False, |
| 'title': u'Created'}, |
| 'index': 9, |
| 'value': u'...'}, |
| {'header': {'asc': False, |
| 'col': u'_changetime', |
| 'hidden': True, |
| 'title': u'Changetime'}, |
| 'index': 10, |
| 'value': u'...'}, |
| {'header': {'asc': False, |
| 'col': u'_description', |
| 'hidden': True, |
| 'title': u'Description'}, |
| 'index': 11, |
| 'value': u'Description 5'}, |
| {'header': {'asc': False, |
| 'col': u'_reporter', |
| 'hidden': True, |
| 'title': u'Reporter'}, |
| 'index': 12, |
| 'value': u'murphy'}]], |
| 'id': u'5', |
| 'resource': <Resource u'ticket:5'>}])], |
| 'sorting_enabled': False, |
| 'title': u'{7} My Tickets'} |
| |
| ... and check for Trac=0.13 in here ;) |
| |
| >>> if trac_version < trac_tags[0]: |
| ... __tester__.assertEquals(reported_tickets, None) |
| ... else: |
| ... __tester__.assertEquals( |
| ... [x['ticket'] for x in reported_tickets[1]], |
| ... [3, 6] |
| ... ) |
| ... |
| """, |
| '|TicketReport: Render a subset of My Tickets report' : r""" |
| |
| Add tickets |
| |
| >>> from tracrpc.ticket import TicketRPC |
| >>> tcktrpc = TicketRPC(env) |
| >>> for td in ticket_data : |
| ... tcktrpc.create(auth_req, *td) |
| ... |
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
| 7 |
| 8 |
| 9 |
| |
| >>> if all(tcktrpc.get(auth_req, tid)[-1].get('status') == 'new' \ |
| ... for tid in xrange(1, 10)): |
| ... # RPC considers ticket workflow |
| ... prepare_ticket_workflow(tcktrpc, ticket_data, auth_req) |
| ... |
| |
| Check everything is ok with tickets |
| |
| >>> for tid in xrange(1, 10): |
| ... d = tcktrpc.get(auth_req, tid)[-1] |
| ... print tuple(d.get(attr) or '' for attr in TICKET_ATTRS) |
| (u'Ticket 1', u'Description 1', u'major', u'milestone1', |
| u'defect', u'murphy', u'accepted', u'component1', u'1.0') |
| (u'Ticket 2', u'Description 2', u'major', u'milestone4', |
| u'task', u'murphy', u'accepted', '', '') |
| (u'Ticket 3', u'Description 3', u'critical', u'milestone3', |
| u'enhancement', u'tester', u'new', '', u'2.0') |
| (u'Ticket 4', u'Description 4', u'minor', u'milestone3', |
| u'task', u'murphy', u'closed', u'component1', u'1.0') |
| (u'Ticket 5', u'Description 5', u'minor', u'milestone3', |
| u'task', u'murphy', u'new', '', u'2.0') |
| (u'Ticket 6', u'Description 6', u'minor', u'milestone1', |
| u'task', u'tester', u'assigned', u'component2', u'1.0') |
| (u'Ticket 7', u'Description 7', u'critical', '', u'enhancement', |
| u'murphy', u'closed', '', '') |
| (u'Ticket 8', u'Description 8', u'major', '', u'task', |
| u'murphy', u'closed', u'component1', '') |
| (u'Ticket 9', u'Description 9', u'minor', '', u'enhancement', |
| u'tester', u'closed', '', u'2.0') |
| |
| >>> pprint(widget.render_widget('TicketReport', auth_ctx, { |
| ... 'args' : {'id' : 7, 'limit' : 2} |
| ... })) |
| ... |
| ('widget_grid.html', |
| {'data': {'action': 'view', |
| 'args': {'USER': 'murphy'}, |
| 'context': <...Context <Resource u'report:7'>>, |
| 'description': u'\nThis report demonstrates the use of the automatically set \nUSER dynamic variable, replaced with the username of the\nlogged in user when executed.\n', |
| 'email_map': {}, |
| 'header_groups': [[{'asc': False, |
| 'col': u'__color__', |
| 'hidden': True, |
| 'title': u'Color'}, |
| {'asc': False, |
| 'col': u'__group__', |
| 'hidden': True, |
| 'title': u'Group'}, |
| {'asc': False, |
| 'col': u'ticket', |
| 'hidden': False, |
| 'title': u'Ticket'}, |
| {'asc': False, |
| 'col': u'summary', |
| 'hidden': False, |
| 'title': u'Summary'}, |
| {'asc': False, |
| 'col': u'component', |
| 'hidden': False, |
| 'title': u'Component'}, |
| {'asc': False, |
| 'col': u'version', |
| 'hidden': False, |
| 'title': u'Version'}, |
| {'asc': False, |
| 'col': u'milestone', |
| 'hidden': False, |
| 'title': u'Milestone'}, |
| {'asc': False, |
| 'col': u'type', |
| 'hidden': False, |
| 'title': u'Type'}, |
| {'asc': False, |
| 'col': u'priority', |
| 'hidden': False, |
| 'title': u'Priority'}, |
| {'asc': False, |
| 'col': u'created', |
| 'hidden': False, |
| 'title': u'Created'}, |
| {'asc': False, |
| 'col': u'_changetime', |
| 'hidden': True, |
| 'title': u'Changetime'}, |
| {'asc': False, |
| 'col': u'_description', |
| 'hidden': True, |
| 'title': u'Description'}, |
| {'asc': False, |
| 'col': u'_reporter', |
| 'hidden': True, |
| 'title': u'Reporter'}]], |
| 'message': None, |
| 'numrows': 3, |
| 'paginator': <trac.util.presentation.Paginator object at ...>, |
| 'report': {'id': 7, 'resource': <Resource u'report:7'>}, |
| 'row_groups': [(u'Accepted', |
| [{u'__color__': u'3', |
| '__idx__': 0, |
| 'cell_groups': [[{'header': {'asc': False, |
| 'col': u'__color__', |
| 'hidden': True, |
| 'title': u'Color'}, |
| 'index': 0, |
| 'value': u'3'}, |
| {'header': {'asc': False, |
| 'col': u'__group__', |
| 'hidden': True, |
| 'title': u'Group'}, |
| 'index': 1, |
| 'value': u'Accepted'}, |
| {'header': {'asc': False, |
| 'col': u'ticket', |
| 'hidden': False, |
| 'title': u'Ticket'}, |
| 'index': 2, |
| 'value': u'1'}, |
| {'header': {'asc': False, |
| 'col': u'summary', |
| 'hidden': False, |
| 'title': u'Summary'}, |
| 'index': 3, |
| 'value': u'Ticket 1'}, |
| {'header': {'asc': False, |
| 'col': u'component', |
| 'hidden': False, |
| 'title': u'Component'}, |
| 'index': 4, |
| 'value': u'component1'}, |
| {'header': {'asc': False, |
| 'col': u'version', |
| 'hidden': False, |
| 'title': u'Version'}, |
| 'index': 5, |
| 'value': u'1.0'}, |
| {'header': {'asc': False, |
| 'col': u'milestone', |
| 'hidden': False, |
| 'title': u'Milestone'}, |
| 'index': 6, |
| 'value': u'milestone1'}, |
| {'header': {'asc': False, |
| 'col': u'type', |
| 'hidden': False, |
| 'title': u'Type'}, |
| 'index': 7, |
| 'value': u'defect'}, |
| {'header': {'asc': False, |
| 'col': u'priority', |
| 'hidden': False, |
| 'title': u'Priority'}, |
| 'index': 8, |
| 'value': u'major'}, |
| {'header': {'asc': False, |
| 'col': u'created', |
| 'hidden': False, |
| 'title': u'Created'}, |
| 'index': 9, |
| 'value': u'...'}, |
| {'header': {'asc': False, |
| 'col': u'_changetime', |
| 'hidden': True, |
| 'title': u'Changetime'}, |
| 'index': 10, |
| 'value': u'...'}, |
| {'header': {'asc': False, |
| 'col': u'_description', |
| 'hidden': True, |
| 'title': u'Description'}, |
| 'index': 11, |
| 'value': u'Description 1'}, |
| {'header': {'asc': False, |
| 'col': u'_reporter', |
| 'hidden': True, |
| 'title': u'Reporter'}, |
| 'index': 12, |
| 'value': u'murphy'}]], |
| 'id': u'1', |
| 'resource': <Resource u'ticket:1'>}, |
| {u'__color__': u'3', |
| '__idx__': 1, |
| 'cell_groups': [[{'header': {'asc': False, |
| 'col': u'__color__', |
| 'hidden': True, |
| 'title': u'Color'}, |
| 'index': 0, |
| 'value': u'3'}, |
| {'header': {'asc': False, |
| 'col': u'__group__', |
| 'hidden': True, |
| 'title': u'Group'}, |
| 'index': 1, |
| 'value': u'Accepted'}, |
| {'header': {'asc': False, |
| 'col': u'ticket', |
| 'hidden': False, |
| 'title': u'Ticket'}, |
| 'index': 2, |
| 'value': u'2'}, |
| {'header': {'asc': False, |
| 'col': u'summary', |
| 'hidden': False, |
| 'title': u'Summary'}, |
| 'index': 3, |
| 'value': u'Ticket 2'}, |
| {'header': {'asc': False, |
| 'col': u'component', |
| 'hidden': False, |
| 'title': u'Component'}, |
| 'index': 4, |
| 'value': ''}, |
| {'header': {'asc': False, |
| 'col': u'version', |
| 'hidden': False, |
| 'title': u'Version'}, |
| 'index': 5, |
| 'value': ''}, |
| {'header': {'asc': False, |
| 'col': u'milestone', |
| 'hidden': False, |
| 'title': u'Milestone'}, |
| 'index': 6, |
| 'value': u'milestone4'}, |
| {'header': {'asc': False, |
| 'col': u'type', |
| 'hidden': False, |
| 'title': u'Type'}, |
| 'index': 7, |
| 'value': u'task'}, |
| {'header': {'asc': False, |
| 'col': u'priority', |
| 'hidden': False, |
| 'title': u'Priority'}, |
| 'index': 8, |
| 'value': u'major'}, |
| {'header': {'asc': False, |
| 'col': u'created', |
| 'hidden': False, |
| 'title': u'Created'}, |
| 'index': 9, |
| 'value': u'...'}, |
| {'header': {'asc': False, |
| 'col': u'_changetime', |
| 'hidden': True, |
| 'title': u'Changetime'}, |
| 'index': 10, |
| 'value': u'...'}, |
| {'header': {'asc': False, |
| 'col': u'_description', |
| 'hidden': True, |
| 'title': u'Description'}, |
| 'index': 11, |
| 'value': u'Description 2'}, |
| {'header': {'asc': False, |
| 'col': u'_reporter', |
| 'hidden': True, |
| 'title': u'Reporter'}, |
| 'index': 12, |
| 'value': u'murphy'}]], |
| 'id': u'2', |
| 'resource': <Resource u'ticket:2'>}]), |
| (u'Owned', |
| [{u'__color__': u'4', |
| '__idx__': 2, |
| 'cell_groups': [[{'header': {'asc': False, |
| 'col': u'__color__', |
| 'hidden': True, |
| 'title': u'Color'}, |
| 'index': 0, |
| 'value': u'4'}, |
| {'header': {'asc': False, |
| 'col': u'__group__', |
| 'hidden': True, |
| 'title': u'Group'}, |
| 'index': 1, |
| 'value': u'Owned'}, |
| {'header': {'asc': False, |
| 'col': u'ticket', |
| 'hidden': False, |
| 'title': u'Ticket'}, |
| 'index': 2, |
| 'value': u'5'}, |
| {'header': {'asc': False, |
| 'col': u'summary', |
| 'hidden': False, |
| 'title': u'Summary'}, |
| 'index': 3, |
| 'value': u'Ticket 5'}, |
| {'header': {'asc': False, |
| 'col': u'component', |
| 'hidden': False, |
| 'title': u'Component'}, |
| 'index': 4, |
| 'value': ''}, |
| {'header': {'asc': False, |
| 'col': u'version', |
| 'hidden': False, |
| 'title': u'Version'}, |
| 'index': 5, |
| 'value': u'2.0'}, |
| {'header': {'asc': False, |
| 'col': u'milestone', |
| 'hidden': False, |
| 'title': u'Milestone'}, |
| 'index': 6, |
| 'value': u'milestone3'}, |
| {'header': {'asc': False, |
| 'col': u'type', |
| 'hidden': False, |
| 'title': u'Type'}, |
| 'index': 7, |
| 'value': u'task'}, |
| {'header': {'asc': False, |
| 'col': u'priority', |
| 'hidden': False, |
| 'title': u'Priority'}, |
| 'index': 8, |
| 'value': u'minor'}, |
| {'header': {'asc': False, |
| 'col': u'created', |
| 'hidden': False, |
| 'title': u'Created'}, |
| 'index': 9, |
| 'value': u'...'}, |
| {'header': {'asc': False, |
| 'col': u'_changetime', |
| 'hidden': True, |
| 'title': u'Changetime'}, |
| 'index': 10, |
| 'value': u'...'}, |
| {'header': {'asc': False, |
| 'col': u'_description', |
| 'hidden': True, |
| 'title': u'Description'}, |
| 'index': 11, |
| 'value': u'Description 5'}, |
| {'header': {'asc': False, |
| 'col': u'_reporter', |
| 'hidden': True, |
| 'title': u'Reporter'}, |
| 'index': 12, |
| 'value': u'murphy'}]], |
| 'id': u'5', |
| 'resource': <Resource u'ticket:5'>}])], |
| 'sorting_enabled': False, |
| 'title': u'{7} My Tickets'}, |
| 'title': <Element "a">}, |
| <...Context <Resource u'report:7'>>) |
| """, |
| '|TicketReport: Invalid widget name' : r""" |
| >>> widget.render_widget('OlkswSk', ctx, { |
| ... 'args' : {'id' : 1, 'limit' : 8} |
| ... }) |
| ... |
| Traceback (most recent call last): |
| ... |
| InvalidIdentifier: Widget name MUST match any of TicketReport |
| """, |
| '|TicketReport: Invalid report ID in arguments' : r""" |
| >>> widget.render_widget('TicketReport', ctx, { |
| ... 'args' : {'id' : 99999} |
| ... }) |
| ... |
| Traceback (most recent call last): |
| ... |
| InvalidIdentifier: Report 99999 does not exist. |
| """, |
| '|TicketReport: Missing required arguments' : r""" |
| >>> widget.render_widget('TicketReport', ctx, { |
| ... 'args' : {} |
| ... }) |
| ... |
| Traceback (most recent call last): |
| ... |
| InvalidWidgetArgument: Invalid argument `id`. Required parameter expected |
| |
| >>> widget.render_widget('TicketReport', ctx, { |
| ... 'args' : {'limit' : 4} |
| ... }) |
| ... |
| Traceback (most recent call last): |
| ... |
| InvalidWidgetArgument: Invalid argument `id`. Required parameter expected |
| """, |
| '|TicketReport: Invalid widget parameter' : r""" |
| |
| Add tickets |
| |
| >>> from tracrpc.ticket import TicketRPC |
| >>> tcktrpc = TicketRPC(env) |
| >>> for td in ticket_data : |
| ... tcktrpc.create(auth_req, *td) |
| ... |
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
| 7 |
| 8 |
| 9 |
| |
| >>> if all(tcktrpc.get(auth_req, tid)[-1].get('status') == 'new' \ |
| ... for tid in xrange(1, 10)): |
| ... # RPC considers ticket workflow |
| ... prepare_ticket_workflow(tcktrpc, ticket_data, auth_req) |
| ... |
| |
| Check everything is ok with tickets |
| |
| >>> for tid in xrange(1, 10): |
| ... d = tcktrpc.get(auth_req, tid)[-1] |
| ... print tuple(d.get(attr) or '' for attr in TICKET_ATTRS) |
| (u'Ticket 1', u'Description 1', u'major', u'milestone1', |
| u'defect', u'murphy', u'accepted', u'component1', u'1.0') |
| (u'Ticket 2', u'Description 2', u'major', u'milestone4', |
| u'task', u'murphy', u'accepted', '', '') |
| (u'Ticket 3', u'Description 3', u'critical', u'milestone3', |
| u'enhancement', u'tester', u'new', '', u'2.0') |
| (u'Ticket 4', u'Description 4', u'minor', u'milestone3', |
| u'task', u'murphy', u'closed', u'component1', u'1.0') |
| (u'Ticket 5', u'Description 5', u'minor', u'milestone3', |
| u'task', u'murphy', u'new', '', u'2.0') |
| (u'Ticket 6', u'Description 6', u'minor', u'milestone1', |
| u'task', u'tester', u'assigned', u'component2', u'1.0') |
| (u'Ticket 7', u'Description 7', u'critical', '', u'enhancement', |
| u'murphy', u'closed', '', '') |
| (u'Ticket 8', u'Description 8', u'major', '', u'task', |
| u'murphy', u'closed', u'component1', '') |
| (u'Ticket 9', u'Description 9', u'minor', '', u'enhancement', |
| u'tester', u'closed', '', u'2.0') |
| |
| >>> pprint(widget.render_widget('TicketReport', auth_ctx, { |
| ... 'args' : {'newjums' : 7, 'id' : 7, 'limit' : 1} |
| ... })) |
| ... |
| ('widget_grid.html', |
| {'data': {'action': 'view', |
| 'args': {'USER': 'murphy'}, |
| 'context': <...Context <Resource u'report:7'>>, |
| 'description': u'\nThis report demonstrates the use of the automatically set \nUSER dynamic variable, replaced with the username of the\nlogged in user when executed.\n', |
| 'email_map': {}, |
| 'header_groups': [[{'asc': False, |
| 'col': u'__color__', |
| 'hidden': True, |
| 'title': u'Color'}, |
| {'asc': False, |
| 'col': u'__group__', |
| 'hidden': True, |
| 'title': u'Group'}, |
| {'asc': False, |
| 'col': u'ticket', |
| 'hidden': False, |
| 'title': u'Ticket'}, |
| {'asc': False, |
| 'col': u'summary', |
| 'hidden': False, |
| 'title': u'Summary'}, |
| {'asc': False, |
| 'col': u'component', |
| 'hidden': False, |
| 'title': u'Component'}, |
| {'asc': False, |
| 'col': u'version', |
| 'hidden': False, |
| 'title': u'Version'}, |
| {'asc': False, |
| 'col': u'milestone', |
| 'hidden': False, |
| 'title': u'Milestone'}, |
| {'asc': False, |
| 'col': u'type', |
| 'hidden': False, |
| 'title': u'Type'}, |
| {'asc': False, |
| 'col': u'priority', |
| 'hidden': False, |
| 'title': u'Priority'}, |
| {'asc': False, |
| 'col': u'created', |
| 'hidden': False, |
| 'title': u'Created'}, |
| {'asc': False, |
| 'col': u'_changetime', |
| 'hidden': True, |
| 'title': u'Changetime'}, |
| {'asc': False, |
| 'col': u'_description', |
| 'hidden': True, |
| 'title': u'Description'}, |
| {'asc': False, |
| 'col': u'_reporter', |
| 'hidden': True, |
| 'title': u'Reporter'}]], |
| 'message': None, |
| 'numrows': 3, |
| 'paginator': <trac.util.presentation.Paginator object at ...>, |
| 'report': {'id': 7, 'resource': <Resource u'report:7'>}, |
| 'row_groups': [(u'Accepted', |
| [{u'__color__': u'3', |
| '__idx__': 0, |
| 'cell_groups': [[{'header': {'asc': False, |
| 'col': u'__color__', |
| 'hidden': True, |
| 'title': u'Color'}, |
| 'index': 0, |
| 'value': u'3'}, |
| {'header': {'asc': False, |
| 'col': u'__group__', |
| 'hidden': True, |
| 'title': u'Group'}, |
| 'index': 1, |
| 'value': u'Accepted'}, |
| {'header': {'asc': False, |
| 'col': u'ticket', |
| 'hidden': False, |
| 'title': u'Ticket'}, |
| 'index': 2, |
| 'value': u'1'}, |
| {'header': {'asc': False, |
| 'col': u'summary', |
| 'hidden': False, |
| 'title': u'Summary'}, |
| 'index': 3, |
| 'value': u'Ticket 1'}, |
| {'header': {'asc': False, |
| 'col': u'component', |
| 'hidden': False, |
| 'title': u'Component'}, |
| 'index': 4, |
| 'value': u'component1'}, |
| {'header': {'asc': False, |
| 'col': u'version', |
| 'hidden': False, |
| 'title': u'Version'}, |
| 'index': 5, |
| 'value': u'1.0'}, |
| {'header': {'asc': False, |
| 'col': u'milestone', |
| 'hidden': False, |
| 'title': u'Milestone'}, |
| 'index': 6, |
| 'value': u'milestone1'}, |
| {'header': {'asc': False, |
| 'col': u'type', |
| 'hidden': False, |
| 'title': u'Type'}, |
| 'index': 7, |
| 'value': u'defect'}, |
| {'header': {'asc': False, |
| 'col': u'priority', |
| 'hidden': False, |
| 'title': u'Priority'}, |
| 'index': 8, |
| 'value': u'major'}, |
| {'header': {'asc': False, |
| 'col': u'created', |
| 'hidden': False, |
| 'title': u'Created'}, |
| 'index': 9, |
| 'value': u'...'}, |
| {'header': {'asc': False, |
| 'col': u'_changetime', |
| 'hidden': True, |
| 'title': u'Changetime'}, |
| 'index': 10, |
| 'value': u'...'}, |
| {'header': {'asc': False, |
| 'col': u'_description', |
| 'hidden': True, |
| 'title': u'Description'}, |
| 'index': 11, |
| 'value': u'Description 1'}, |
| {'header': {'asc': False, |
| 'col': u'_reporter', |
| 'hidden': True, |
| 'title': u'Reporter'}, |
| 'index': 12, |
| 'value': u'murphy'}]], |
| 'id': u'1', |
| 'resource': <Resource u'ticket:1'>}, |
| {u'__color__': u'3', |
| '__idx__': 1, |
| 'cell_groups': [[{'header': {'asc': False, |
| 'col': u'__color__', |
| 'hidden': True, |
| 'title': u'Color'}, |
| 'index': 0, |
| 'value': u'3'}, |
| {'header': {'asc': False, |
| 'col': u'__group__', |
| 'hidden': True, |
| 'title': u'Group'}, |
| 'index': 1, |
| 'value': u'Accepted'}, |
| {'header': {'asc': False, |
| 'col': u'ticket', |
| 'hidden': False, |
| 'title': u'Ticket'}, |
| 'index': 2, |
| 'value': u'2'}, |
| {'header': {'asc': False, |
| 'col': u'summary', |
| 'hidden': False, |
| 'title': u'Summary'}, |
| 'index': 3, |
| 'value': u'Ticket 2'}, |
| {'header': {'asc': False, |
| 'col': u'component', |
| 'hidden': False, |
| 'title': u'Component'}, |
| 'index': 4, |
| 'value': ''}, |
| {'header': {'asc': False, |
| 'col': u'version', |
| 'hidden': False, |
| 'title': u'Version'}, |
| 'index': 5, |
| 'value': ''}, |
| {'header': {'asc': False, |
| 'col': u'milestone', |
| 'hidden': False, |
| 'title': u'Milestone'}, |
| 'index': 6, |
| 'value': u'milestone4'}, |
| {'header': {'asc': False, |
| 'col': u'type', |
| 'hidden': False, |
| 'title': u'Type'}, |
| 'index': 7, |
| 'value': u'task'}, |
| {'header': {'asc': False, |
| 'col': u'priority', |
| 'hidden': False, |
| 'title': u'Priority'}, |
| 'index': 8, |
| 'value': u'major'}, |
| {'header': {'asc': False, |
| 'col': u'created', |
| 'hidden': False, |
| 'title': u'Created'}, |
| 'index': 9, |
| 'value': u'...'}, |
| {'header': {'asc': False, |
| 'col': u'_changetime', |
| 'hidden': True, |
| 'title': u'Changetime'}, |
| 'index': 10, |
| 'value': u'...'}, |
| {'header': {'asc': False, |
| 'col': u'_description', |
| 'hidden': True, |
| 'title': u'Description'}, |
| 'index': 11, |
| 'value': u'Description 2'}, |
| {'header': {'asc': False, |
| 'col': u'_reporter', |
| 'hidden': True, |
| 'title': u'Reporter'}, |
| 'index': 12, |
| 'value': u'murphy'}]], |
| 'id': u'2', |
| 'resource': <Resource u'ticket:2'>}]), |
| (u'Owned', |
| [{u'__color__': u'4', |
| '__idx__': 2, |
| 'cell_groups': [[{'header': {'asc': False, |
| 'col': u'__color__', |
| 'hidden': True, |
| 'title': u'Color'}, |
| 'index': 0, |
| 'value': u'4'}, |
| {'header': {'asc': False, |
| 'col': u'__group__', |
| 'hidden': True, |
| 'title': u'Group'}, |
| 'index': 1, |
| 'value': u'Owned'}, |
| {'header': {'asc': False, |
| 'col': u'ticket', |
| 'hidden': False, |
| 'title': u'Ticket'}, |
| 'index': 2, |
| 'value': u'5'}, |
| {'header': {'asc': False, |
| 'col': u'summary', |
| 'hidden': False, |
| 'title': u'Summary'}, |
| 'index': 3, |
| 'value': u'Ticket 5'}, |
| {'header': {'asc': False, |
| 'col': u'component', |
| 'hidden': False, |
| 'title': u'Component'}, |
| 'index': 4, |
| 'value': ''}, |
| {'header': {'asc': False, |
| 'col': u'version', |
| 'hidden': False, |
| 'title': u'Version'}, |
| 'index': 5, |
| 'value': u'2.0'}, |
| {'header': {'asc': False, |
| 'col': u'milestone', |
| 'hidden': False, |
| 'title': u'Milestone'}, |
| 'index': 6, |
| 'value': u'milestone3'}, |
| {'header': {'asc': False, |
| 'col': u'type', |
| 'hidden': False, |
| 'title': u'Type'}, |
| 'index': 7, |
| 'value': u'task'}, |
| {'header': {'asc': False, |
| 'col': u'priority', |
| 'hidden': False, |
| 'title': u'Priority'}, |
| 'index': 8, |
| 'value': u'minor'}, |
| {'header': {'asc': False, |
| 'col': u'created', |
| 'hidden': False, |
| 'title': u'Created'}, |
| 'index': 9, |
| 'value': u'...'}, |
| {'header': {'asc': False, |
| 'col': u'_changetime', |
| 'hidden': True, |
| 'title': u'Changetime'}, |
| 'index': 10, |
| 'value': u'...'}, |
| {'header': {'asc': False, |
| 'col': u'_description', |
| 'hidden': True, |
| 'title': u'Description'}, |
| 'index': 11, |
| 'value': u'Description 5'}, |
| {'header': {'asc': False, |
| 'col': u'_reporter', |
| 'hidden': True, |
| 'title': u'Reporter'}, |
| 'index': 12, |
| 'value': u'murphy'}]], |
| 'id': u'5', |
| 'resource': <Resource u'ticket:5'>}])], |
| 'sorting_enabled': False, |
| 'title': u'{7} My Tickets'}, |
| 'title': <Element "a">}, |
| <...Context <Resource u'report:7'>>) |
| """, |
| '|TicketReport: Invalid report definition' : r""" |
| >>> raise NotImplementedError() |
| """, |
| } |
| |