Exemple #1
0
    def test_insert_into_multiple_products(self):
        # UIDs are global, autoincremented
        # IDs are product-scoped, incremented in the SQL translator
        self.env = ProductEnvironment(self.global_env, self.default_product)

        tid = self._insert_ticket('hello kitty', reporter='admin')
        ticket = Ticket(self.env, tid)
        self.assertEqual(tid, 1)
        self.assertEqual(self._get_ticket_uid(tid), 1)
        self.assertEqual(ticket.id, tid)
        tid = self._insert_ticket('hello kitteh', reporter='admin')
        ticket = Ticket(self.env, tid)
        self.assertEqual(tid, 2)
        self.assertEqual(self._get_ticket_uid(tid), 2)
        self.assertEqual(ticket.id, tid)

        p2 = Product(self.global_env)
        p2.prefix = 'p2'
        p2.name = 'product, too'
        p2.owner = 'admin'
        p2.insert()
        self.env = ProductEnvironment(self.global_env, p2)

        tid = self._insert_ticket('hello catty', reporter='admin')
        ticket = Ticket(self.env, tid)
        self.assertEqual(tid, 1)
        self.assertEqual(self._get_ticket_uid(tid), 3)
        self.assertEqual(ticket.id, tid)
        tid = self._insert_ticket('hello ocelot', reporter='admin')
        ticket = Ticket(self.env, tid)
        self.assertEqual(tid, 2)
        self.assertEqual(self._get_ticket_uid(tid), 4)
        self.assertEqual(ticket.id, tid)
Exemple #2
0
    def setUp(self):
        self._mp_setup()
        self.global_env = self.env
        self._load_product_from_data(self.global_env, u'xü')

        self.env = ProductEnvironment(self.global_env, self.default_product)
        self.env1 = ProductEnvironment(self.global_env, u'xü')

        self._load_default_data(self.global_env)
        self._load_default_data(self.env1)

        # Enable product system component in product context
        self.env.enable_component(MultiProductSystem)
Exemple #3
0
    def resource_created(self, resource, context):
        import trac.db_default
        from multiproduct.env import EnvironmentStub

        # Don't populate product database when running from within test
        # environment stub as test cases really don't expect that ...
        if isinstance(self.env, EnvironmentStub):
            return

        product = resource
        self.log.debug("Adding product info (%s) to tables:" % product.prefix)
        with self.env.db_direct_transaction as db:
            # create the default entries for this Product from defaults
            for table in trac.db_default.get_data(db):
                if not table[0] in self.PRODUCT_POPULATE_TABLES:
                    continue

                self.log.debug("  -> %s" % table[0])
                cols = table[1] + ('product', )
                rows = [p + (product.prefix, ) for p in table[2]]
                db.executemany(
                    "INSERT INTO %s (%s) VALUES (%s)" %
                    (table[0], ','.join(cols), ','.join(['%s' for c in cols])),
                    rows)

        # Import default pages in product wiki
        wikiadmin = WikiAdmin(ProductEnvironment(self.env, product.prefix))
        pages = ('TitleIndex', 'RecentChanges', 'InterTrac', 'InterWiki')
        for page in pages:
            filename = resource_filename('trac.wiki', 'default-pages/' + page)
            wikiadmin.import_page(filename, page)
Exemple #4
0
    def find_ticket(self, ticket_spec):
        ticket = None
        m = re.match(r'#?(?P<tid>\d+)', ticket_spec)
        if m:
            tid = m.group('tid')
            try:
                ticket = Ticket(self.env, tid)
            except ResourceNotFound:
                # ticket not found in current product, try all other products
                for p in Product.select(self.env):
                    if p.prefix != self.env.product.prefix:
                        # TODO: check for PRODUCT_VIEW permissions
                        penv = ProductEnvironment(self.env.parent, p.prefix)
                        try:
                            ticket = Ticket(penv, tid)
                        except ResourceNotFound:
                            pass
                        else:
                            break

        # ticket still not found, use fallback for <prefix>:ticket:<id> syntax
        if ticket is None:
            try:
                resource = ResourceIdSerializer.get_resource_by_id(ticket_spec)
                ticket = self._create_ticket_by_full_id(resource)
            except:
                raise NoSuchTicketError
        return ticket
Exemple #5
0
    def add_template_data(self, req, data, tickets):
        if isinstance(self.env, ProductEnvironment):
            super(ProductBatchModifyModule, self).add_template_data(req, data,
                                                                    tickets)
            return

        data['batch_modify'] = True
        data['query_href'] = req.session['query_href'] or req.href.query()

        tickets_by_product = {}
        for t in tickets:
            tickets_by_product.setdefault(t['product'], []).append(t)

        data['action_controls'] = []
        global_env = ProductEnvironment.lookup_global_env(self.env)
        cache = {}
        for k, v in tickets_by_product.iteritems():
            batch_module = cache.get(k or '')
            if batch_module is None:
                env = ProductEnvironment(global_env, k) if k else global_env
                cache[k] = batch_module = ProductBatchModifyModule(env)
            data['action_controls'] += batch_module._get_action_controls(req,
                                                                         v)
        batch_list_modes = [
            {'name': _("add"), 'value': "+"},
            {'name': _("remove"), 'value': "-"},
            {'name': _("add / remove"), 'value': "+-"},
            {'name': _("set to"), 'value': "="},
        ]
        add_script_data(req, batch_list_modes=batch_list_modes,
                        batch_list_properties=self._get_list_fields())
Exemple #6
0
    def create(self, req, summary, description, attributes={}, notify=False):
        """ Create a new ticket, returning the ticket ID.

        PS: Borrowed from XmlRpcPlugin.
        """
        if 'product' in attributes:
            env = self.env.parent or self.env
            if attributes['product']:
                env = ProductEnvironment(env, attributes['product'])
        else:
            env = self.env

        t = Ticket(env)
        t['summary'] = summary
        t['description'] = description
        t['reporter'] = req.authname
        for k, v in attributes.iteritems():
            t[k] = v
        t['status'] = 'new'
        t['resolution'] = ''
        t.insert()

        if notify:
            try:
                tn = TicketNotifyEmail(env)
                tn.notify(t, newticket=True)
            except Exception, e:
                self.log.exception("Failure sending notification on creation "
                                   "of ticket #%s: %s" % (t.id, e))
Exemple #7
0
    def test_env_isolation(self):
        global_env = self.global_env
        env = self.env

        self._load_product_from_data(self.global_env, 'tp2')
        env1 = ProductEnvironment(self.global_env, 'tp2')

        global_store = perm.DefaultPermissionStore(global_env)
        store = perm.DefaultPermissionStore(env)
        store1 = perm.DefaultPermissionStore(env1)

        global_env.db_transaction.executemany(
            "INSERT INTO permission VALUES (%s,%s)",
            [('dev', 'WIKI_MODIFY'),
             ('dev', 'REPORT_ADMIN'),
             ('john', 'dev')])
        env.db_transaction.executemany(
            "INSERT INTO permission VALUES (%s,%s)",
            [('dev', 'WIKI_VIEW'),
             ('dev', 'REPORT_VIEW'),
             ('john', 'dev')])
        env1.db_transaction.executemany(
            "INSERT INTO permission VALUES (%s,%s)",
            [('dev', 'TICKET_CREATE'),
             ('dev', 'MILESTONE_VIEW'),
             ('john', 'dev')])

        self.assertEquals(['REPORT_ADMIN', 'WIKI_MODIFY'],
                          sorted(global_store.get_user_permissions('john')))
        self.assertEquals(['REPORT_VIEW', 'WIKI_VIEW'],
                          sorted(store.get_user_permissions('john')))
        self.assertEquals(['MILESTONE_VIEW', 'TICKET_CREATE'],
                          sorted(store1.get_user_permissions('john')))
Exemple #8
0
    def setUp(self):
        self._mp_setup()
        self.global_env = self.env
        self.env = ProductEnvironment(self.global_env, self.default_product)

        # Product name inserted in RSS feed
        self.env.product._data['name'] = 'My Project'

        self.env.config.set(
            'trac', 'templates_dir',
            os.path.join(os.path.dirname(self.env.path), 'templates'))
        self.ticket_module = ProductTicketModule(self.env)
        self.mimeview = Mimeview(self.env)
        self.req = Mock(base_path='/trac.cgi',
                        path_info='',
                        href=Href('/trac.cgi'),
                        chrome={'logo': {}},
                        abs_href=Href('http://example.org/trac.cgi'),
                        environ={},
                        perm=[],
                        authname='-',
                        args={},
                        tz=None,
                        locale='',
                        session=None,
                        form_token=None)
    def setUp(self):
        self._prepare_env()

        self._setup_test_log(self.global_env)
        formatter.WikiTestCase.setUp(self)
        if self.context.req:
            self.context.req.session = FakeSession()
        if self.mpctx:
            candidates = set(
                self.mpctx.get('load_products', []) +
                [self.mpctx.get('main_product')])
            candidates -= set(
                [self.default_product, None,
                 self.mpctx.get('setup_product')])
            for prefix in candidates:
                self._load_product_from_data(self.env, prefix)

            prefix = self.mpctx.get('main_product', NotImplemented)
            if prefix is None:
                self.env = self.global_env
            elif prefix is not NotImplemented \
                    and (self.env is self.global_env or
                         prefix != self.env.product.prefix):
                self.env = ProductEnvironment(self.global_env, prefix)
            # Enable multi-product components
            self.env.config.set('components', 'multiproduct.*', 'enabled')
Exemple #10
0
    def setUp(self):
        self._mp_setup(create_folder=True)
        self.global_env = self.env
        self.env = ProductEnvironment(self.global_env, self.default_product)

        # Random component class
        self.component_class = self.DummyAdminCommand
Exemple #11
0
 def process_request(self, req):
     product = req.args.get('product')
     fields_to_update = req.args.get('fields_to_update[]');
     env = ProductEnvironment(self.env.parent, req.args.get('product'))
     ticket_fields = TicketSystem(env).get_ticket_fields()
     data = dict([f['name'], f['options']]  for f in ticket_fields
         if f['type'] == 'select' and f['name'] in fields_to_update)
     req.send(to_json(data), 'application/json')
Exemple #12
0
    def setUp(self):
        self.global_env = self._setup_test_env(create_folder=True)
        self._upgrade_mp(self.global_env)
        self._setup_test_log(self.global_env)
        self._load_product_from_data(self.global_env, self.default_product)

        self.env = ProductEnvironment(self.global_env, self.default_product)
        self._load_default_data(self.env)
Exemple #13
0
    def setUp(self):
        self.global_env = self._setup_test_env()
        self._upgrade_mp(self.global_env)
        self._setup_test_log(self.global_env)
        self._load_product_from_data(self.env, self.default_product)
        self.env = ProductEnvironment(self.env, self.default_product)

        self.store = perm.DefaultPermissionStore(self.env)
Exemple #14
0
 def setUp(self):
     self.global_env = self._setup_test_env(create_folder=True,
                                            path=os.path.join(
                                                tempfile.gettempdir(),
                                                'trac-tempenv'))
     self._upgrade_mp(self.global_env)
     self._setup_test_log(self.global_env)
     self._load_product_from_data(self.global_env, self.default_product)
     self.env = ProductEnvironment(self.global_env, self.default_product)
Exemple #15
0
 def check_permission(self, doc, context):
     product, doctype, id = doc['product'], doc['type'], doc['id']
     username = context.req.authname
     env = self.env
     if product:
         env = ProductEnvironment(self.env, product)
     perm = PermissionSystem(env)
     action = self._required_permissions[doctype]
     return perm.check_permission(action, username, id)
Exemple #16
0
    def setUp(self):
        self._mp_setup()
        self.global_env = self.env
        self.env = ProductEnvironment(self.global_env, self.default_product)
        self._load_default_data(self.env)

        self.env.config.set('ticket-custom', 'foo', 'text')
        self.env.config.set('ticket-custom', 'cbon', 'checkbox')
        self.env.config.set('ticket-custom', 'cboff', 'checkbox')
Exemple #17
0
    def _get_product_info(self, product, href, resource, max_):
        penv = ProductEnvironment(self.env, product.prefix)
        results = []

        # some queries return a list/tuple, some a generator,
        # hence count() to get the result length
        def count(iter_):
            try:
                return len(iter_)
            except TypeError:
                return sum(1 for _ in iter_)

        query = resource['type'].select(penv)
        for q in itertools.islice(query, max_):
            q.url = href(resource['name'], q.name) \
                if resource.get('hrefurl') \
                else Query.from_string(penv,
                    '%s=%s&%s&col=%s' % (resource['name'], q.name,
                                         self.COMMON_QUERY, resource['name'])
            ).get_href(href)
            q.ticket_count = penv.db_query("""
                SELECT COUNT(*) FROM ticket WHERE ticket.%s='%s'
                AND ticket.status <> 'closed'
                """ % (resource['name'], q.name))[0][0]

            results.append(q)

        # add a '(No <milestone/component/version>)' entry if there are
        # tickets without an assigned resource in the product
        ticket_count = penv.db_query(
            """SELECT COUNT(*) FROM ticket WHERE %s=''
               AND status <> 'closed'""" % (resource['name'],))[0][0]
        if ticket_count != 0:
            q = resource['type'](penv)
            q.name = '(No %s)' % (resource['name'],)
            q.url = Query.from_string(penv,
               'status=!closed&col=id&col=summary&col=owner'
               '&col=status&col=priority&order=priority&%s='
               % (resource['name'],)
            ).get_href(href)
            q.ticket_count = ticket_count
            results.append(q)

        results.sort(key=lambda x: x.ticket_count, reverse=True)

        # add a link to the resource list if there are
        # more than max resources defined
        if count(query) > max_:
            q = resource['type'](penv)
            q.name = _('... more')
            q.ticket_count = None
            q.url = href(resource['name']) if resource.get('hrefurl') \
                else href.dashboard()
            results.append(q)

        return results
Exemple #18
0
 def setUp(self):
     self._mp_setup()
     self.env.abs_href = Href('http://globalenv.com/trac.cgi')
     url_pattern = getattr(
         getattr(self, self._testMethodName).im_func, 'product_base_url',
         '')
     self.env.config.set('multiproduct', 'product_base_url', url_pattern)
     self.env.config.set('trac', 'base_url',
                         'http://globalenv.com/trac.cgi')
     self.product_env = ProductEnvironment(self.env, self.default_product)
Exemple #19
0
 def env(self):
     env = getattr(self, '_env', None)
     if env is None:
         self.global_env = self._setup_test_env(enable=[AuthzSourcePolicy])
         self._upgrade_mp(self.global_env)
         self._setup_test_log(self.global_env)
         self._load_product_from_data(self.global_env, self.default_product)
         self._env = env = ProductEnvironment(self.global_env,
                                              self.default_product)
     return env
Exemple #20
0
    def test_creating_new_product_calls_environment_created(self):
        self._enable_component(DummyPlugin)
        self._enable_multiproduct()
        self.env.upgrade()

        prod = Product(self.env)
        prod.update_field_dict(dict(prefix='p1'))
        ProductEnvironment(self.env, prod, create=True)
        with self.env.db_direct_transaction as db:
            db('SELECT * FROM "p1_dummy_table"')
Exemple #21
0
    def setUp(self):
        self.global_env = self._setup_test_env(create_folder=False)
        self._upgrade_mp(self.global_env)
        self._setup_test_log(self.global_env)
        self._load_product_from_data(self.global_env, self.default_product)
        self.env = ProductEnvironment(self.global_env, self.default_product)

        self.perm = PermissionSystem(self.env)
        self.ticket_system = TicketSystem(self.env)
        self.req = Mock()
Exemple #22
0
    def test_parent_must_be_in_same_product(self):
        ticket1 = self._insert_and_load_ticket("A1")
        product2 = "tp2"
        self._load_product_from_data(self.global_env, product2)
        p2_env = ProductEnvironment(self.global_env, product2)
        ticket2 = self._insert_and_load_ticket_with_env(p2_env, "A2")

        self.assertRaises(ValidationError, self.relations_system.add, ticket1,
                          ticket2, "parent")
        self.assertRaises(ValidationError, self.relations_system.add, ticket1,
                          ticket2, "children")
Exemple #23
0
 def env(self):
     env = getattr(self, '_env', None)
     if env is None:
         self.global_env = self._setup_test_env(create_folder=False)
         self._upgrade_mp(self.global_env)
         self._setup_test_log(self.global_env)
         self._load_product_from_data(self.global_env, self.default_product)
         self._env = env = ProductEnvironment(self.global_env,
                                              self.default_product)
         self._load_default_data(env)
     return env
Exemple #24
0
 def env(self):
     env = getattr(self, '_env', None)
     if env is None:
         self.global_env = self._setup_test_env(
             enable=[Chrome, PatchRenderer])
         self._upgrade_mp(self.global_env)
         self._setup_test_log(self.global_env)
         self._load_product_from_data(self.global_env, self.default_product)
         self._env = env = ProductEnvironment(self.global_env,
                                              self.default_product)
     return env
Exemple #25
0
    def test_can_find_ticket_by_id_from_different_env(self):
        """ Can find ticket from different env given #id"""
        product2 = "tp2"
        self._load_product_from_data(self.global_env, product2)
        p2_env = ProductEnvironment(self.global_env, product2)
        t1 = self._insert_and_load_ticket_with_env(p2_env, "T1")
        trs = TicketRelationsSpecifics(self.env)

        ticket = trs.find_ticket("#%d" % t1.id)

        self.assertEqual(ticket.id, 1)
Exemple #26
0
    def test_can_find_ticket_by_product_and_id(self):
        """ Can find ticket given #prefix-id"""
        product2 = "tp2"
        self._load_product_from_data(self.global_env, product2)
        p2_env = ProductEnvironment(self.global_env, product2)
        t1 = self._insert_and_load_ticket_with_env(p2_env, "T1")
        trs = TicketRelationsSpecifics(self.env)

        ticket = trs.find_ticket("#%s-%d" % (product2, t1.id))

        self.assertEqual(ticket.id, 1)
Exemple #27
0
    def test_can_add_multi_product_relations(self):

        ticket1 = self._insert_and_load_ticket("A1")
        product2 = "tp2"
        self._load_product_from_data(self.global_env, product2)
        p2_env = ProductEnvironment(self.global_env, product2)
        ticket2 = self._insert_and_load_ticket_with_env(p2_env, "A2")

        self.add_relation(ticket1, MULTIPRODUCT_REL, ticket2)

        self.assertEqual(1, len(self.get_relations(ticket1)))
        self.assertEqual(1, len(self.get_relations(ticket2)))
Exemple #28
0
    def test_typecheck(self):
        """Testing env.__init__"""
        self._load_product_from_data(self.env, 'tp2')
        with self.assertRaises(TypeError) as cm_test:
            new_env = ProductEnvironment(self.product_env, 'tp2')

        msg = str(cm_test.exception)
        expected_msg = "Initializer must be called with " \
                       "trac.env.Environment instance as first argument " \
                       "(got multiproduct.env.ProductEnvironment instance " \
                       "instead)"
        self.assertEqual(msg, expected_msg)
Exemple #29
0
    def _render_link(self, context, name, label, extra='', prefix=None):
        """Render link to product page.
        """
        product_env = product = None
        env = self.env
        if isinstance(env, ProductEnvironment):
            if (prefix is not None and env.product.prefix == prefix) \
                    or (prefix is None and env.name == name):
                product_env = env
            env = env.parent
        try:
            if product_env is None:
                if prefix is not None:
                    product_env = ProductEnvironment(env, to_unicode(prefix))
                else:
                    product = Product.select(env,
                                             where={'name' : to_unicode(name)})
                    if not product:
                        raise LookupError("Missing product")
                    product_env = ProductEnvironment(env,
                                                     to_unicode(product[0]))
        except LookupError:
            pass

        if product_env is not None:
            product = product_env.product
            href = resolve_product_href(to_env=product_env, at_env=self.env)
            if 'PRODUCT_VIEW' in context.perm(product.resource):
                return tag.a(label, class_='product', href=href() + extra,
                             title=product.name)
        if 'PRODUCT_CREATE' in context.perm('product', name):
            params = [('action', 'new')]
            if prefix:
                params.append( ('prefix', prefix) )
            if name:
                params.append( ('name', name) )
            return tag.a(label, class_='missing product',
                    href=env.href('products', params),
                    rel='nofollow')
        return tag.a(label, class_='missing product')
Exemple #30
0
 def env(self):
     env = getattr(self, '_env', None)
     if env is None:
         self.global_env = self._setup_test_env(enable=[
             '%s.%s' % (MimeviewTestCase.__module__, c)
             for c in ['Converter0', 'Converter1', 'Converter2']
         ])
         self._upgrade_mp(self.global_env)
         self._setup_test_log(self.global_env)
         self._load_product_from_data(self.global_env, self.default_product)
         self._env = env = ProductEnvironment(self.global_env,
                                              self.default_product)
     return env