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)
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)
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)
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
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())
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))
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')))
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')
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
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')
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)
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)
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)
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)
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')
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
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)
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
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"')
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()
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")
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
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
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)
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)
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)))
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)
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')
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