def install(self, project): """Create repo object for this tool""" super(ForgeGitApp, self).install(project) repo = GM.Repository(name=self.config.options.mount_point + ".git", tool="git", status="initializing") ThreadLocalORMSession.flush_all() cloned_from_project_id = self.config.options.get("cloned_from_project_id") cloned_from_repo_id = self.config.options.get("cloned_from_repo_id") init_from_url = self.config.options.get("init_from_url") init_from_path = self.config.options.get("init_from_path") if cloned_from_project_id is not None: cloned_from = GM.Repository.query.get(_id=cloned_from_repo_id) allura.tasks.repo_tasks.clone.post( cloned_from_path=cloned_from.full_fs_path, cloned_from_name=cloned_from.app.config.script_name(), cloned_from_url=cloned_from.full_fs_path, copy_hooks=self.config.options.get("copy_hooks", False), ) elif init_from_url or init_from_path: allura.tasks.repo_tasks.clone.post( cloned_from_path=init_from_path, cloned_from_name=None, cloned_from_url=init_from_url, copy_hooks=self.config.options.get("copy_hooks", False), ) else: allura.tasks.repo_tasks.init.post()
def test_milestone_rename(self): self.new_ticket(summary='test milestone rename') self.app.post('/bugs/1/update_ticket',{ 'summary':'test milestone rename', 'description':'', 'status':'', '_milestone':'1.0', 'assigned_to':'', 'labels':'', 'labels_old':'', 'comment': '' }) ThreadLocalORMSession.flush_all() M.MonQTask.run_ready() ThreadLocalORMSession.flush_all() ticket_view = self.app.get('/p/test/bugs/1/') assert 'Milestone' in ticket_view assert '1.0' in ticket_view assert 'zzzé' not in ticket_view r = self.app.post('/bugs/update_milestones',{ 'field_name':'_milestone', 'milestones-0.old_name':'1.0', 'milestones-0.new_name':'zzzé', 'milestones-0.description':'', 'milestones-0.complete':'Open', 'milestones-0.due_date':'' }) ticket_view = self.app.get('/p/test/bugs/1/') assert '1.0' not in ticket_view assert 'zzzé' in ticket_view
def test_request_token_valid(self, Request, Server): M.OAuthConsumerToken.consumer = mock.Mock() user = M.User.by_username('test-user') consumer_token = M.OAuthConsumerToken( api_key='api_key', user_id=user._id, ) ThreadLocalORMSession.flush_all() req = Request.from_request.return_value = { 'oauth_consumer_key': 'api_key' } r = self.app.post('/rest/oauth/request_token', params={'key': 'value'}) Request.from_request.assert_called_once_with( 'POST', 'http://localhost/rest/oauth/request_token', headers={ 'Host': 'localhost:80', 'Content-Type': 'application/x-www-form-urlencoded; charset="utf-8"' }, parameters={'key': 'value'}, query_string='') Server().verify_request.assert_called_once_with( req, consumer_token.consumer, None) request_token = M.OAuthRequestToken.query.get( consumer_token_id=consumer_token._id) assert_is_not_none(request_token) assert_equal(r.body, request_token.to_string())
def test_artifactlink(): pg = WM.Page(title='TestPage2') q = M.Shortlink.query.find( dict(project_id=c.project._id, app_config_id=c.app.config._id, link=pg.shorthand_id())) assert q.count() == 0 ThreadLocalORMSession.flush_all() M.MonQTask.run_ready() ThreadLocalORMSession.flush_all() assert q.count() == 1 assert M.Shortlink.lookup('[TestPage2]') assert M.Shortlink.lookup('[wiki:TestPage2]') assert M.Shortlink.lookup('[test:wiki:TestPage2]') assert not M.Shortlink.lookup('[test:wiki:TestPage2:foo]') assert not M.Shortlink.lookup('[Wiki:TestPage2]') assert not M.Shortlink.lookup('[TestPage2_no_such_page]') c.project.uninstall_app('wiki') ThreadLocalORMSession.flush_all() assert not M.Shortlink.lookup('[wiki:TestPage2]') pg.delete() ThreadLocalORMSession.flush_all() M.MonQTask.run_ready() ThreadLocalORMSession.flush_all() assert q.count() == 0
def test_interactive(self, Request, Server): M.OAuthConsumerToken.consumer = mock.Mock() user = M.User.by_username('test-admin') consumer_token = M.OAuthConsumerToken( api_key='api_key', user_id=user._id, description='ctok_desc', ) ThreadLocalORMSession.flush_all() req = Request.from_request.return_value = { 'oauth_consumer_key': 'api_key', 'oauth_callback': 'http://my.domain.com/callback', } r = self.app.post('/rest/oauth/request_token', params={}) rtok = parse_qs(r.body)['oauth_token'][0] r = self.app.post('/rest/oauth/authorize', params={'oauth_token': rtok}) r = r.forms[0].submit('yes') assert r.location.startswith('http://my.domain.com/callback') pin = parse_qs(urlparse(r.location).query)['oauth_verifier'][0] #pin = r.html.find(text=re.compile('^PIN: ')).split()[1] req = Request.from_request.return_value = { 'oauth_consumer_key': 'api_key', 'oauth_token': rtok, 'oauth_verifier': pin, } r = self.app.get('/rest/oauth/access_token') atok = parse_qs(r.body) assert_equal(len(atok['oauth_token']), 1) assert_equal(len(atok['oauth_token_secret']), 1)
def test_ticket_move_with_users_not_in_project(self): app1 = c.project.app_instance('bugs') app2 = c.project.app_instance('bugs2') app1.globals.custom_fields.extend([ {'name': '_user_field', 'type': 'user', 'label': 'User field'}, {'name': '_user_field_2', 'type': 'user', 'label': 'User field 2'}]) app2.globals.custom_fields.extend([ {'name': '_user_field', 'type': 'user', 'label': 'User field'}, {'name': '_user_field_2', 'type': 'user', 'label': 'User field 2'}]) ThreadLocalORMSession.flush_all() ThreadLocalORMSession.close_all() from allura.websetup import bootstrap bootstrap.create_user('test-user-0') with h.push_context(c.project._id, app_config_id=app1.config._id): ticket = Ticket.new() ticket.summary = 'test ticket' ticket.description = 'test description' ticket.custom_fields['_user_field'] = 'test-user' # in project ticket.custom_fields['_user_field_2'] = 'test-user-0' # not in project ticket.assigned_to_id = User.by_username('test-user-0')._id # not in project t = ticket.move(app2.config) assert_equal(t.assigned_to_id, None) assert_equal(t.custom_fields['_user_field'], 'test-user') assert_equal(t.custom_fields['_user_field_2'], '') post = Post.query.find(dict(thread_id=ticket.discussion_thread._id)).first() assert post is not None, 'No comment about ticket moving' message = 'Ticket moved from /p/test/bugs/1/' message += '\n\nCan\'t be converted:\n' message += '\n- **_user_field_2**: test-user-0 (user not in project)' message += '\n- **assigned_to**: test-user-0 (user not in project)' assert_equal(post.text, message)
def test_prefs(self): r = self.app.get('/auth/preferences/', extra_environ=dict(username='******')) assert '*****@*****.**' not in r r = self.app.post('/auth/preferences/update', params={ 'preferences.display_name':'Test Admin', 'new_addr.addr':'*****@*****.**', 'new_addr.claim':'Claim Address', 'primary_addr':'*****@*****.**', 'preferences.email_format':'plain'}, extra_environ=dict(username='******')) r = self.app.get('/auth/preferences/') assert '*****@*****.**' in r r = self.app.post('/auth/preferences/update', params={ 'preferences.display_name':'Test Admin', 'addr-1.ord':'1', 'addr-2.ord':'1', 'addr-2.delete':'on', 'new_addr.addr':'', 'primary_addr':'*****@*****.**', 'preferences.email_format':'plain'}, extra_environ=dict(username='******')) r = self.app.get('/auth/preferences/') assert '*****@*****.**' not in r ea = M.EmailAddress.query.get(_id='*****@*****.**') ea.confirmed = True ThreadLocalORMSession.flush_all() r = self.app.post('/auth/preferences/update', params={ 'preferences.display_name':'Test Admin', 'new_addr.addr':'*****@*****.**', 'new_addr.claim':'Claim Address', 'primary_addr':'*****@*****.**', 'preferences.email_format':'plain'}, extra_environ=dict(username='******'))
def private_project(self): ''' Returns the personal user-project for the user ''' if self.disabled or self.pending: return None from allura import model as M n = self.neighborhood auth_provider = plugin.AuthenticationProvider.get(request) project_shortname = auth_provider.user_project_shortname(self) p = M.Project.query.get( shortname=project_shortname, neighborhood_id=n._id) if p and p.deleted: # really delete it, since registering a new project would conflict # with the "deleted" one log.info( 'completely deleting user project (was already flagged as deleted) %s', project_shortname) p.delete() ThreadLocalORMSession.flush_all() p = None if not p and not self.is_anonymous(): # create user-project on demand if it is missing p = n.register_project( project_shortname, user=self, user_project=True) return p
def test_user_project_does_not_create_on_demand_for_openid_user(): u = M.User.register({'username': ''}, make_project=False) ThreadLocalORMSession.flush_all() assert not u.private_project() assert not M.Project.query.get(shortname='u/') assert not M.Project.query.get(shortname='u/anonymous') assert not M.Project.query.get(shortname='u/*anonymous')
def test_that_label_counts_are_local_to_tool(self): """Test that label queries return only artifacts from the specified tool. """ # create a ticket in two different tools, with the same label from allura.tests import decorators as td @td.with_tool('test', 'Tickets', 'bugs', username='******') def _test_ticket(): return Ticket(ticket_num=1, summary="ticket1", labels=["mylabel"]) @td.with_tool('test', 'Tickets', 'bugs2', username='******') def _test_ticket2(): return Ticket(ticket_num=2, summary="ticket2", labels=["mylabel"]) # create and save the tickets t1 = _test_ticket() t2 = _test_ticket2() ThreadLocalORMSession.flush_all() # test label query results label_count1 = t1.artifacts_labeled_with( "mylabel", t1.app_config).count() label_count2 = t2.artifacts_labeled_with( "mylabel", t2.app_config).count() assert 1 == label_count1 == label_count2
def make_artifact(self, ticket_dict): remapped = {} for f, v in ticket_dict.iteritems(): transform = self.FIELD_MAP.get(f, ()) if transform is None: continue elif transform is True: remapped[f] = v elif callable(transform): transform(remapped, f, v) elif transform is (): self.custom(remapped, f, v) else: new_f, conv = transform remapped[new_f] = conv(v) ticket_num = ticket_dict['id'] existing_ticket = TM.Ticket.query.get(app_config_id=c.app.config._id, ticket_num=ticket_num) if existing_ticket: ticket_num = c.app.globals.next_ticket_num() self.warnings.append('Ticket #%s: Ticket with this id already exists, using next available id: %s' % (ticket_dict['id'], ticket_num)) else: if c.app.globals.last_ticket_num < ticket_num: c.app.globals.last_ticket_num = ticket_num ThreadLocalORMSession.flush_all() ticket = TM.Ticket( app_config_id=c.app.config._id, custom_fields=dict(), ticket_num=ticket_num, import_id=c.api_token.api_key) ticket.update(remapped) return ticket
def test_user(): assert c.user.url() .endswith('/u/test-admin/') assert c.user.script_name .endswith('/u/test-admin/') assert_equal(set(p.shortname for p in c.user.my_projects()), set(['test', 'test2', 'u/test-admin', 'adobe-1', '--init--'])) # delete one of the projects and make sure it won't appear in my_projects() p = M.Project.query.get(shortname='test2') p.deleted = True ThreadLocalORMSession.flush_all() assert_equal(set(p.shortname for p in c.user.my_projects()), set(['test', 'u/test-admin', 'adobe-1', '--init--'])) u = M.User.register(dict( username='******')) ThreadLocalORMSession.flush_all() assert_equal(u.private_project().shortname, 'u/nosetest-user') roles = g.credentials.user_roles( u._id, project_id=u.private_project().root_project._id) assert len(roles) == 3, roles u.set_password('foo') provider = plugin.LocalAuthenticationProvider(Request.blank('/')) assert provider._validate_password(u, 'foo') assert not provider._validate_password(u, 'foobar') u.set_password('foobar') assert provider._validate_password(u, 'foobar') assert not provider._validate_password(u, 'foo')
def install(self, project): '''Create repo object for this tool''' super(ForgeGitApp, self).install(project) repo = GM.Repository(name=self.config.options.mount_point + '.git', tool='git', status='initializing') ThreadLocalORMSession.flush_all() cloned_from_project_id = self.config.options.get( 'cloned_from_project_id') cloned_from_repo_id = self.config.options.get('cloned_from_repo_id') init_from_url = self.config.options.get('init_from_url') init_from_path = self.config.options.get('init_from_path') if cloned_from_project_id is not None: cloned_from = GM.Repository.query.get(_id=cloned_from_repo_id) allura.tasks.repo_tasks.clone.post( cloned_from_path=cloned_from.full_fs_path, cloned_from_name=cloned_from.app.config.script_name(), cloned_from_url=cloned_from.full_fs_path, copy_hooks=self.config.options.get('copy_hooks', False)) elif init_from_url or init_from_path: allura.tasks.repo_tasks.clone.post( cloned_from_path=init_from_path, cloned_from_name=None, cloned_from_url=init_from_url, copy_hooks=self.config.options.get('copy_hooks', False)) else: allura.tasks.repo_tasks.init.post()
def test_user_backfill_login_details(): with h.push_config(request, user_agent='TestBrowser/55'): # these shouldn't match h.auditlog_user('something happened') h.auditlog_user('blah blah Password changed') with h.push_config(request, user_agent='TestBrowser/56'): # these should all match, but only one entry created for this ip/ua h.auditlog_user('Account activated') h.auditlog_user('Successful login') h.auditlog_user('Password changed') with h.push_config(request, user_agent='TestBrowser/57'): # this should match too h.auditlog_user('Set up multifactor TOTP') ThreadLocalORMSession.flush_all() auth_provider = plugin.AuthenticationProvider.get(None) c.user.backfill_login_details(auth_provider) details = M.UserLoginDetails.query.find({ 'user_id': c.user._id }).sort('ua').all() assert_equal(len(details), 2, details) assert_equal(details[0].ip, '127.0.0.1') assert_equal(details[0].ua, 'TestBrowser/56') assert_equal(details[1].ip, '127.0.0.1') assert_equal(details[1].ua, 'TestBrowser/57')
def test_related_links(self): response = self.app.get('/wiki/TEST/').follow() assert 'Edit TEST' in response assert 'Related' not in response self.app.post('/wiki/TEST/update', params={ 'title': 'TEST', 'text': 'sometext', 'labels': '', 'viewable_by-0.id': 'all'}) self.app.post('/wiki/aaa/update', params={ 'title': 'aaa', 'text': '', 'labels': '', 'viewable_by-0.id': 'all'}) self.app.post('/wiki/bbb/update', params={ 'title': 'bbb', 'text': '', 'labels': '', 'viewable_by-0.id': 'all'}) h.set_context('test', 'wiki', neighborhood='Projects') a = model.Page.query.find(dict(title='aaa')).first() a.text = '\n[TEST]\n' b = model.Page.query.find(dict(title='TEST')).first() b.text = '\n[bbb]\n' ThreadLocalORMSession.flush_all() M.MonQTask.run_ready() ThreadLocalORMSession.flush_all() ThreadLocalORMSession.close_all() response = self.app.get('/wiki/TEST/') assert 'Related' in response assert 'aaa' in response assert 'bbb' in response
def private_project(self): ''' Returns the personal user-project for the user ''' if self.disabled or self.pending: return None from allura import model as M n = self.neighborhood auth_provider = plugin.AuthenticationProvider.get(request) project_shortname = auth_provider.user_project_shortname(self) p = M.Project.query.get( shortname=project_shortname, neighborhood_id=n._id) if p and p.deleted: # really delete it, since registering a new project would conflict # with the "deleted" one log.info( 'completely deleting user project (was already flagged as deleted) %s', project_shortname) p.delete() ThreadLocalORMSession.flush_all() p = None if not p and not self.is_anonymous(): # create user-project on demand if it is missing p = n.register_project( project_shortname, user=self, user_project=True) return p
def test_interactive(self, Request, Server): M.OAuthConsumerToken.consumer = mock.Mock() user = M.User.by_username('test-admin') consumer_token = M.OAuthConsumerToken( api_key='api_key', user_id=user._id, description='ctok_desc', ) ThreadLocalORMSession.flush_all() req = Request.from_request.return_value = { 'oauth_consumer_key': 'api_key', 'oauth_callback': 'http://my.domain.com/callback', } r = self.app.post('/rest/oauth/request_token', params={}) rtok = parse_qs(r.body)['oauth_token'][0] r = self.app.post('/rest/oauth/authorize', params={'oauth_token': rtok}) r = r.forms[0].submit('yes') assert r.location.startswith('http://my.domain.com/callback') pin = parse_qs(urlparse(r.location).query)['oauth_verifier'][0] #pin = r.html.find(text=re.compile('^PIN: ')).split()[1] req = Request.from_request.return_value = { 'oauth_consumer_key': 'api_key', 'oauth_token': rtok, 'oauth_verifier': pin, } r = self.app.get('/rest/oauth/access_token') atok = parse_qs(r.body) assert_equal(len(atok['oauth_token']), 1) assert_equal(len(atok['oauth_token_secret']), 1)
def test_user_project_does_not_create_on_demand_for_openid_user(): u = M.User.register({'username': ''}, make_project=False) ThreadLocalORMSession.flush_all() assert not u.private_project() assert not M.Project.query.get(shortname='u/') assert not M.Project.query.get(shortname='u/anonymous') assert not M.Project.query.get(shortname='u/*anonymous')
def test_screenshot_unicode_serialization(): p = M.Project.query.get(shortname='test') screenshot_unicode = M.ProjectFile(project_id=p._id, category='screenshot', caption="ConSelección", filename='ConSelección.jpg') screenshot_ascii = M.ProjectFile(project_id=p._id, category='screenshot', caption='test-screenshot', filename='test_file.jpg') ThreadLocalORMSession.flush_all() serialized = p.__json__() screenshots = sorted(serialized['screenshots'], key=lambda k: k['caption']) assert len(screenshots) == 2 assert screenshots[0][ 'url'] == 'http://localhost/p/test/screenshot/ConSelecci%C3%B3n.jpg' assert screenshots[0]['caption'] == "ConSelección" assert screenshots[0][ 'thumbnail_url'] == 'http://localhost/p/test/screenshot/ConSelecci%C3%B3n.jpg/thumb' assert screenshots[1][ 'url'] == 'http://localhost/p/test/screenshot/test_file.jpg' assert screenshots[1]['caption'] == 'test-screenshot' assert screenshots[1][ 'thumbnail_url'] == 'http://localhost/p/test/screenshot/test_file.jpg/thumb'
def test_pull_rss_feeds(parsefeed): html_content = ( "<p>1. foo</p>\n" "\n" "<p>\n" "#foo bar <a href='baz'>baz</a>\n" "foo bar\n" "</p>\n" "\n" "<p>#foo bar <a href='http://other.com/baz'>\n" "baz\n" "</a></p>\n" ) rendered_html_content = "\n".join([ r"1\. foo", "", r"\#foo bar [baz](http://example.com/baz) foo bar", "", r"\#foo bar [ baz ](http://other.com/baz)", "", " [link](http://example.com/)", ]) parsefeed.return_value = _mock_feed( dict(title='Test', subtitle='test', summary='This is a test'), dict(content_type='text/plain', content='Test feed'), dict(content_type='text/html', content=html_content), dict(summary_detail=dict(type='text/html', value=html_content)), ) base_app = M.AppConfig.query.find().all()[0] tmp_app = M.AppConfig( tool_name='Blog', discussion_id=base_app.discussion_id, project_id=base_app.project_id, options={'ordinal': 0, 'show_right_bar': True, 'project_name': base_app.project.name, 'mount_point': 'blog', 'mount_label': 'Blog'}) new_external_feeds = ['http://example.com/news/feed/'] BM.Globals(app_config_id=tmp_app._id, external_feeds=new_external_feeds) ThreadLocalORMSession.flush_all() from forgeblog.command import rssfeeds # importing this sets html2text.BODY_WIDTH to a value this test expects cmd = rssfeeds.RssFeedsCommand('pull-rss-feeds') cmd.run([test_config, '-a', tmp_app._id]) cmd.command() parsefeed.assert_called_with('http://example.com/news/feed/') posts = BM.BlogPost.query.find( {'app_config_id': tmp_app._id}).sort('timestamp', 1) assert_equal(posts.count(), 4) posts = posts.all() assert_equal(posts[0].title, 'Test') assert_equal(posts[0].text, 'This is a test [link](http://example.com/)') assert_equal(posts[1].title, 'Default Title 2') assert_equal(posts[1].text, 'Test feed [link](http://example.com/)') assert_equal(posts[2].title, 'Default Title 3') assert_equal(posts[2].text, rendered_html_content) assert_equal(posts[3].title, 'Default Title 4') assert_equal(posts[3].text, rendered_html_content)
def test_artifactlink(): pg = WM.Page(title='TestPage2') q = M.Shortlink.query.find(dict( project_id=c.project._id, app_config_id=c.app.config._id, link=pg.shorthand_id())) assert q.count() == 0 ThreadLocalORMSession.flush_all() M.MonQTask.run_ready() ThreadLocalORMSession.flush_all() assert q.count() == 1 assert M.Shortlink.lookup('[TestPage2]') assert M.Shortlink.lookup('[wiki:TestPage2]') assert M.Shortlink.lookup('[test:wiki:TestPage2]') assert not M.Shortlink.lookup('[test:wiki:TestPage2:foo]') assert not M.Shortlink.lookup('[Wiki:TestPage2]') assert not M.Shortlink.lookup('[TestPage2_no_such_page]') c.project.uninstall_app('wiki') ThreadLocalORMSession.flush_all() assert not M.Shortlink.lookup('[wiki:TestPage2]') pg.delete() ThreadLocalORMSession.flush_all() M.MonQTask.run_ready() ThreadLocalORMSession.flush_all() assert q.count() == 0
def check_custom_field(self, field, value, ticket_status): field = c.app.globals.get_custom_field(field) if (field['type'] == 'select') and value: field_options = h.split_select_field_options( h.really_unicode(field['options'])) if value not in field_options: field['options'] = ' '.join([field['options'], value]) elif (field['type'] == 'milestone') and value: milestones = field['milestones'] for milestone in milestones: if milestone['name'] == value: if ticket_status in c.app.globals.open_status_names: milestone['complete'] = False break else: milestone = { 'due_date': '', 'complete': not ticket_status in c.app.globals.open_status_names, 'description': '', 'name': value, 'old_name': value } field['milestones'].append(milestone) ThreadLocalORMSession.flush_all()
def test_that_label_counts_are_local_to_tool(self): """Test that label queries return only artifacts from the specified tool. """ # create a ticket in two different tools, with the same label from allura.tests import decorators as td @td.with_tool('test', 'Tickets', 'bugs', username='******') def _test_ticket(): return Ticket(ticket_num=1, summary="ticket1", labels=["mylabel"]) @td.with_tool('test', 'Tickets', 'bugs2', username='******') def _test_ticket2(): return Ticket(ticket_num=2, summary="ticket2", labels=["mylabel"]) # create and save the tickets t1 = _test_ticket() t2 = _test_ticket2() ThreadLocalORMSession.flush_all() # test label query results label_count1 = t1.artifacts_labeled_with( "mylabel", t1.app_config).count() label_count2 = t2.artifacts_labeled_with( "mylabel", t2.app_config).count() assert 1 == label_count1 == label_count2
def install(self, project): '''Create repo object for this tool''' super(ForgeHgApp, self).install(project) HM.Repository( name=self.config.options.mount_point, tool='hg', status='initializing') ThreadLocalORMSession.flush_all() cloned_from_project_id = self.config.options.get('cloned_from_project_id') cloned_from_repo_id = self.config.options.get('cloned_from_repo_id') init_from_url = self.config.options.get('init_from_url') init_from_path = self.config.options.get('init_from_path') if cloned_from_project_id is not None: cloned_from = HM.Repository.query.get(_id=cloned_from_repo_id) allura.tasks.repo_tasks.clone.post( cloned_from_path=cloned_from.full_fs_path, cloned_from_name=cloned_from.app.config.script_name(), cloned_from_url=cloned_from.full_fs_path, copy_hooks=self.config.options.get('copy_hooks', False)) elif init_from_url or init_from_path: allura.tasks.repo_tasks.clone.post( cloned_from_path=init_from_path, cloned_from_name=None, cloned_from_url=init_from_url, copy_hooks=self.config.options.get('copy_hooks', False)) else: allura.tasks.repo_tasks.init.post()
def test_ticket_move_with_users_not_in_project(self): app1 = c.project.app_instance('bugs') app2 = c.project.app_instance('bugs2') app1.globals.custom_fields.extend([ {'name': '_user_field', 'type': 'user', 'label': 'User field'}, {'name': '_user_field_2', 'type': 'user', 'label': 'User field 2'}]) app2.globals.custom_fields.extend([ {'name': '_user_field', 'type': 'user', 'label': 'User field'}, {'name': '_user_field_2', 'type': 'user', 'label': 'User field 2'}]) ThreadLocalORMSession.flush_all() ThreadLocalORMSession.close_all() from allura.websetup import bootstrap bootstrap.create_user('test-user-0') with h.push_context(c.project._id, app_config_id=app1.config._id): ticket = Ticket.new() ticket.summary = 'test ticket' ticket.description = 'test description' ticket.custom_fields['_user_field'] = 'test-user' # in project # not in project ticket.custom_fields['_user_field_2'] = 'test-user-0' # not in project ticket.assigned_to_id = User.by_username('test-user-0')._id t = ticket.move(app2.config) assert_equal(t.assigned_to_id, None) assert_equal(t.custom_fields['_user_field'], 'test-user') assert_equal(t.custom_fields['_user_field_2'], '') post = Post.query.find( dict(thread_id=ticket.discussion_thread._id)).first() assert post is not None, 'No comment about ticket moving' message = 'Ticket moved from /p/test/bugs/1/' message += '\n\nCan\'t be converted:\n' message += '\n- **_user_field_2**: test-user-0 (user not in project)' message += '\n- **assigned_to**: test-user-0 (user not in project)' assert_equal(post.text, message)
def test_ticket_move_with_different_custom_fields(self): app1 = c.project.app_instance('bugs') app2 = c.project.app_instance('bugs2') app1.globals.custom_fields.extend([ {'name': '_test', 'type': 'string', 'label': 'Test field'}, {'name': '_test2', 'type': 'string', 'label': 'Test field 2'}]) app2.globals.custom_fields.append( {'name': '_test', 'type': 'string', 'label': 'Test field'}) ThreadLocalORMSession.flush_all() ThreadLocalORMSession.close_all() with h.push_context(c.project._id, app_config_id=app1.config._id): ticket = Ticket.new() ticket.summary = 'test ticket' ticket.description = 'test description' ticket.custom_fields['_test'] = 'test val' ticket.custom_fields['_test2'] = 'test val 2' t = ticket.move(app2.config) assert_equal(t.summary, 'test ticket') assert_equal(t.description, 'test description') assert_equal(t.custom_fields['_test'], 'test val') post = Post.query.find(dict(thread_id=ticket.discussion_thread._id)).first() assert post is not None, 'No comment about ticket moving' message = 'Ticket moved from /p/test/bugs/1/' message += '\n\nCan\'t be converted:\n' message += '\n- **_test2**: test val 2' assert_equal(post.text, message)
def test_ticket_move_with_different_custom_fields(self): app1 = c.project.app_instance('bugs') app2 = c.project.app_instance('bugs2') app1.globals.custom_fields.extend([ {'name': '_test', 'type': 'string', 'label': 'Test field'}, {'name': '_test2', 'type': 'string', 'label': 'Test field 2'}]) app2.globals.custom_fields.append( {'name': '_test', 'type': 'string', 'label': 'Test field'}) ThreadLocalORMSession.flush_all() ThreadLocalORMSession.close_all() with h.push_context(c.project._id, app_config_id=app1.config._id): ticket = Ticket.new() ticket.summary = 'test ticket' ticket.description = 'test description' ticket.custom_fields['_test'] = 'test val' ticket.custom_fields['_test2'] = 'test val 2' t = ticket.move(app2.config) assert_equal(t.summary, 'test ticket') assert_equal(t.description, 'test description') assert_equal(t.custom_fields['_test'], 'test val') post = Post.query.find( dict(thread_id=ticket.discussion_thread._id)).first() assert post is not None, 'No comment about ticket moving' message = 'Ticket moved from /p/test/bugs/1/' message += '\n\nCan\'t be converted:\n' message += '\n- **_test2**: test val 2' assert_equal(post.text, message)
def install(self, project): '''Create repo object for this tool''' super(ForgeGitApp, self).install(project) repo = GM.Repository( name=self.config.options.mount_point + '.git', tool='git', status='initializing', fs_path=self.config.options.get('fs_path')) ThreadLocalORMSession.flush_all() cloned_from_project_id = self.config.options.get('cloned_from_project_id') cloned_from_repo_id = self.config.options.get('cloned_from_repo_id') init_from_url = self.config.options.get('init_from_url') init_from_path = self.config.options.get('init_from_path') if cloned_from_project_id is not None: cloned_from = GM.Repository.query.get(_id=cloned_from_repo_id) repo.default_branch_name = cloned_from.default_branch_name repo.additional_viewable_extensions = cloned_from.additional_viewable_extensions allura.tasks.repo_tasks.clone.post( cloned_from_path=cloned_from.full_fs_path, cloned_from_name=cloned_from.app.config.script_name(), cloned_from_url=cloned_from.full_fs_path) elif init_from_url or init_from_path: allura.tasks.repo_tasks.clone.post( cloned_from_path=init_from_path, cloned_from_name=None, cloned_from_url=init_from_url) else: allura.tasks.repo_tasks.init.post()
def test_related_links(self): response = self.app.get('/wiki/TEST/').follow() assert 'Edit TEST' in response assert 'Related' not in response self.app.post('/wiki/TEST/update', params={ 'title': 'TEST', 'text': 'sometext', 'labels': '', 'viewable_by-0.id': 'all'}) self.app.post('/wiki/aaa/update', params={ 'title': 'aaa', 'text': '', 'labels': '', 'viewable_by-0.id': 'all'}) self.app.post('/wiki/bbb/update', params={ 'title': 'bbb', 'text': '', 'labels': '', 'viewable_by-0.id': 'all'}) h.set_context('test', 'wiki', neighborhood='Projects') a = model.Page.query.find(dict(title='aaa')).first() a.text = '\n[TEST]\n' b = model.Page.query.find(dict(title='TEST')).first() b.text = '\n[bbb]\n' ThreadLocalORMSession.flush_all() M.MonQTask.run_ready() ThreadLocalORMSession.flush_all() ThreadLocalORMSession.close_all() response = self.app.get('/wiki/TEST/') assert 'Related' in response assert 'aaa' in response assert 'bbb' in response
def test_disable_user(self): user = Mock(disabled=False, __ming__=Mock(), is_anonymous=lambda: False, _id=ObjectId()) c.user = Mock(username='******') with audits('Account disabled', user=True, actor='test-admin'): self.provider.disable_user(user) ThreadLocalORMSession.flush_all() assert_equal(user.disabled, True)
def main(): test = sys.argv[-1] == 'test' num_projects_examined = 0 log.info('Examining subroles in all non-user projects.') n_users = M.Neighborhood.query.get(name='Users') project_filter = dict(neighborhood_id={'$ne': n_users._id}) for some_projects in utils.chunked_find(M.Project, project_filter): for project in some_projects: project_name = '%s.%s' % ( project.neighborhood.name, project.shortname) project_roles = {} for parent, child in [('Admin', 'Developer'), ('Developer', 'Member')]: parent_role = M.ProjectRole.by_name(parent, project=project) child_role = M.ProjectRole.by_name(child, project=project) project_roles[parent] = parent_role project_roles[child] = child_role if not (parent_role and child_role): break if len(parent_role.roles) != 1 or parent_role.roles[0] != child_role._id: if test: log.info('Would reset %s subroles for project "%s".' % (parent, project_name)) log.info('- Existing %s subrole(s): %s' % (parent, parent_role.roles)) else: log.info('Resetting %s subroles for project "%s".' % (parent, project_name)) parent_role.roles = [child_role._id] ThreadLocalORMSession.flush_all() if not (project_roles['Admin'] and project_roles['Developer'] and project_roles['Member']): log.info( 'Skipping "%s": missing Admin, Developer, or Member roles' % project_name) continue for user in project.users(): pr = user.project_role(project=project) if not pr.roles: continue for parent, children in [('Admin', ('Developer', 'Member')), ('Developer', ('Member',))]: if project_roles[parent]._id not in pr.roles: continue for role_name in children: extra_role = project_roles[role_name] if extra_role._id in pr.roles: if test: log.info('Would remove %s role from user "%s" in project "%s" (already has %s role).' % (role_name, user.username, project_name, parent)) pr.roles.remove(extra_role._id) else: log.info('Removing %s role from user "%s" in project "%s" (already has %s role).' % (role_name, user.username, project_name, parent)) pr.roles.remove(extra_role._id) ThreadLocalORMSession.flush_all() num_projects_examined += 1 session(project).clear() log.info('%s projects examined.' % num_projects_examined)
def command(self): self.basic_setup() self.hostname = socket.gethostname() self.taskd_status_log = self.args[1] self.stuck_pids = [] self.error_tasks = [] self.suspicious_tasks = [] taskd_pids = self._taskd_pids() base.log.info('Taskd processes on %s: %s' % (self.hostname, taskd_pids)) # find stuck taskd processes base.log.info('Seeking for stuck taskd processes') for pid in taskd_pids: base.log.info('...sending USR1 to %s and watching status log' % (pid)) status = self._check_taskd_status(int(pid)) if status != 'OK': base.log.info('...taskd pid %s has stuck' % pid) self.stuck_pids.append(pid) if self.options.kill: base.log.info('...-k is set. Killing %s' % pid) self._kill_stuck_taskd(pid) else: base.log.info('...%s' % status) # find 'forsaken' tasks base.log.info('Seeking for forsaken busy tasks') tasks = [t for t in self._busy_tasks() if t not in self.error_tasks] # skip seen tasks base.log.info('Found %s busy tasks on %s' % (len(tasks), self.hostname)) for task in tasks: base.log.info('Verifying task %s' % task) pid = task.process.split()[-1] if pid not in taskd_pids: # 'forsaken' task base.log.info('Task is forsaken ' '(can\'t find taskd with given pid). ' 'Setting state to \'error\'') task.state = 'error' task.result = 'Can\'t find taskd with given pid' self.error_tasks.append(task) else: # check if taskd with given pid really processing this task now: base.log.info('Checking that taskd pid %s is really processing task %s' % (pid, task._id)) status = self._check_task(pid, task) if status != 'OK': # maybe task moved quickly and now is complete # so we need to check such tasks later # and mark incomplete ones as 'error' self.suspicious_tasks.append(task) base.log.info('...NO. Adding task to suspisious list') else: base.log.info('...OK') # check suspicious task and mark incomplete as error base.log.info('Checking suspicious list for incomplete tasks') self._check_suspicious_tasks() ThreadLocalORMSession.flush_all() self.print_summary()
def test_pull_rss_feeds(parsefeed): html_content = ( "<p>1. foo</p>\n" "\n" "<p>\n" "#foo bar <a href='baz'>baz</a>\n" "foo bar\n" "</p>\n" "\n" "<p>#foo bar <a href='baz'>\n" "baz\n" "</a></p>\n" ) rendered_html_content = "\n".join([ r"1\. foo", "", r"\#foo bar [baz](baz) foo bar ", "", r"\#foo bar [ baz ](baz)", " [link](http://example.com/)", ]) parsefeed.return_value = _mock_feed( dict(title='Test', subtitle='test', summary='This is a test'), dict(content_type='text/plain', content='Test feed'), dict(content_type='text/html', content=html_content), dict(summary_detail=dict(type='text/html', value=html_content)), ) base_app = M.AppConfig.query.find().all()[0] tmp_app = M.AppConfig( tool_name=u'Blog', discussion_id=base_app.discussion_id, project_id=base_app.project_id, options={u'ordinal': 0, u'show_right_bar': True, u'project_name': base_app.project.name, u'mount_point': u'blog', u'mount_label': u'Blog'}) new_external_feeds = ['http://example.com/news/feed/'] BM.Globals(app_config_id=tmp_app._id, external_feeds=new_external_feeds) ThreadLocalORMSession.flush_all() from forgeblog.command import rssfeeds cmd = rssfeeds.RssFeedsCommand('pull-rss-feeds') cmd.run([test_config, '-a', tmp_app._id]) cmd.command() parsefeed.assert_called_with('http://example.com/news/feed/') posts = BM.BlogPost.query.find( {'app_config_id': tmp_app._id}).sort('timestamp', 1) assert_equal(posts.count(), 4) posts = posts.all() assert_equal(posts[0].title, 'Test') assert_equal(posts[0].text, 'This is a test [link](http://example.com/)') assert_equal(posts[1].title, 'Default Title 2') assert_equal(posts[1].text, 'Test feed [link](http://example.com/)') assert_equal(posts[2].title, 'Default Title 3') assert_equal(posts[2].text, rendered_html_content) assert_equal(posts[3].title, 'Default Title 4') assert_equal(posts[3].text, rendered_html_content)
def main(): test = sys.argv[-1] == 'test' num_projects_examined = 0 log.info('Examining subroles in all non-user projects.') n_users = M.Neighborhood.query.get(name='Users') project_filter = dict(neighborhood_id={'$ne': n_users._id}) for some_projects in utils.chunked_find(M.Project, project_filter): for project in some_projects: project_name = '%s.%s' % (project.neighborhood.name, project.shortname) project_roles = {} for parent, child in [('Admin', 'Developer'), ('Developer', 'Member')]: parent_role = M.ProjectRole.by_name(parent, project=project) child_role = M.ProjectRole.by_name(child, project=project) project_roles[parent] = parent_role project_roles[child] = child_role if not (parent_role and child_role): break if len(parent_role.roles ) != 1 or parent_role.roles[0] != child_role._id: if test: log.info('Would reset %s subroles for project "%s".' % (parent, project_name)) log.info('- Existing %s subrole(s): %s' % (parent, parent_role.roles)) else: log.info('Resetting %s subroles for project "%s".' % (parent, project_name)) parent_role.roles = [child_role._id] ThreadLocalORMSession.flush_all() if not (project_roles['Admin'] and project_roles['Developer'] \ and project_roles['Member']): log.info( 'Skipping "%s": missing Admin, Developer, or Member roles' % project_name) continue for user in project.users(): pr = user.project_role(project=project) if not pr.roles: continue for parent, children in [('Admin', ('Developer', 'Member')), ('Developer', ('Member', ))]: if project_roles[parent]._id not in pr.roles: continue for role_name in children: extra_role = project_roles[role_name] if extra_role._id in pr.roles: if test: log.info('Would remove %s role from user "%s" in project "%s" (already has %s role).' \ % (role_name, user.username, project_name, parent)) pr.roles.remove(extra_role._id) else: log.info('Removing %s role from user "%s" in project "%s" (already has %s role).' \ % (role_name, user.username, project_name, parent)) pr.roles.remove(extra_role._id) ThreadLocalORMSession.flush_all() num_projects_examined += 1 session(project).clear() log.info('%s projects examined.' % num_projects_examined)
def main(): broken_posts = BM.BlogPost.query.find(dict(neighborhood_id=None)).all() for post in broken_posts: c.project = post.app.project c.app = post.app post.neighborhood_id = post.app.project.neighborhood_id ThreadLocalORMSession.flush_all() ThreadLocalORMSession.close_all()
def load(self): artifact_orm_session._get().skip_mod_date = True self.load_pages() self.project.notifications_disabled = False artifact_orm_session._get().skip_mod_date = False ThreadLocalORMSession.flush_all() ThreadLocalORMSession.close_all() allura_base.log.info('Loading wiki done')
def main(): M.TroveCategory(trove_cat_id=670, trove_parent_id=14, shortname="agpl", fullname="Affero GNU Public License", fullpath="License :: OSI-Approved Open Source :: Affero GNU Public License") ThreadLocalORMSession.flush_all() ThreadLocalORMSession.close_all()
def load(self): artifact_orm_session._get().skip_mod_date = True self.load_pages() self.project.notifications_disabled = False artifact_orm_session._get().skip_mod_date = False ThreadLocalORMSession.flush_all() ThreadLocalORMSession.close_all() allura_base.log.info('Loading wiki done')
def test_admin_stats_del_count(self): neighborhood = M.Neighborhood.query.get(name='Adobe') proj = M.Project.query.get(neighborhood_id=neighborhood._id) proj.deleted = True ThreadLocalORMSession.flush_all() r = self.app.get('/adobe/_admin/stats/', extra_environ=dict(username='******')) assert 'Deleted: 1' in r assert 'Private: 0' in r
def test_admin_stats_del_count(self): neighborhood = M.Neighborhood.query.get(name='Adobe') proj = M.Project.query.get(neighborhood_id=neighborhood._id) proj.deleted = True ThreadLocalORMSession.flush_all() r = self.app.get('/adobe/_admin/stats/', extra_environ=dict(username='******')) assert 'Deleted: 1' in r assert 'Private: 0' in r
def main(): M.TroveCategory(trove_cat_id=670, trove_parent_id=14, shortname="agpl", fullname="Affero GNU Public License", fullpath="License :: OSI-Approved Open Source :: Affero GNU Public License") ThreadLocalORMSession.flush_all() ThreadLocalORMSession.close_all()
def main(): M.TroveCategory(trove_cat_id=862, trove_parent_id=14, shortname="lppl", fullname="LaTeX Project Public License", fullpath="License :: OSI-Approved Open Source :: LaTeX Project Public License") M.TroveCategory(trove_cat_id=655, trove_parent_id=432, shortname="win64", fullname="64-bit MS Windows", fullpath="Operating System :: Grouping and Descriptive Categories :: 64-bit MS Windows") M.TroveCategory(trove_cat_id=657, trove_parent_id=418, shortname="vista", fullname="Vista", fullpath="Operating System :: Modern (Vendor-Supported) Desktop Operating Systems :: Vista") M.TroveCategory(trove_cat_id=851, trove_parent_id=418, shortname="win7", fullname="Windows 7", fullpath="Operating System :: Modern (Vendor-Supported) Desktop Operating Systems :: Windows 7") M.TroveCategory(trove_cat_id=728, trove_parent_id=315, shortname="android", fullname="Android", fullpath="Operating System :: Handheld/Embedded Operating Systems :: Android") M.TroveCategory(trove_cat_id=780, trove_parent_id=315, shortname="ios", fullname="Apple iPhone", fullpath="Operating System :: Handheld/Embedded Operating Systems :: Apple iPhone") M.TroveCategory(trove_cat_id=863, trove_parent_id=534, shortname="architects", fullname="Architects", fullpath="Intended Audience :: by End-User Class :: Architects") M.TroveCategory(trove_cat_id=864, trove_parent_id=534, shortname="auditors", fullname="Auditors", fullpath="Intended Audience :: by End-User Class :: Auditors") M.TroveCategory(trove_cat_id=865, trove_parent_id=534, shortname="testers", fullname="Testers", fullpath="Intended Audience :: by End-User Class :: Testers") M.TroveCategory(trove_cat_id=866, trove_parent_id=534, shortname="secpros", fullname="Security Professionals", fullpath="Intended Audience :: by End-User Class :: Security Professionals") M.TroveCategory(trove_cat_id=867, trove_parent_id=535, shortname="secindustry", fullname="Security", fullpath="Intended Audience :: by Industry or Sector :: Security") ThreadLocalORMSession.flush_all() ThreadLocalORMSession.close_all()
def main(): M.TroveCategory(trove_cat_id=862, trove_parent_id=14, shortname="lppl", fullname="LaTeX Project Public License", fullpath="License :: OSI-Approved Open Source :: LaTeX Project Public License") M.TroveCategory(trove_cat_id=655, trove_parent_id=432, shortname="win64", fullname="64-bit MS Windows", fullpath="Operating System :: Grouping and Descriptive Categories :: 64-bit MS Windows") M.TroveCategory(trove_cat_id=657, trove_parent_id=418, shortname="vista", fullname="Vista", fullpath="Operating System :: Modern (Vendor-Supported) Desktop Operating Systems :: Vista") M.TroveCategory(trove_cat_id=851, trove_parent_id=418, shortname="win7", fullname="Windows 7", fullpath="Operating System :: Modern (Vendor-Supported) Desktop Operating Systems :: Windows 7") M.TroveCategory(trove_cat_id=728, trove_parent_id=315, shortname="android", fullname="Android", fullpath="Operating System :: Handheld/Embedded Operating Systems :: Android") M.TroveCategory(trove_cat_id=780, trove_parent_id=315, shortname="ios", fullname="Apple iPhone", fullpath="Operating System :: Handheld/Embedded Operating Systems :: Apple iPhone") M.TroveCategory(trove_cat_id=863, trove_parent_id=534, shortname="architects", fullname="Architects", fullpath="Intended Audience :: by End-User Class :: Architects") M.TroveCategory(trove_cat_id=864, trove_parent_id=534, shortname="auditors", fullname="Auditors", fullpath="Intended Audience :: by End-User Class :: Auditors") M.TroveCategory(trove_cat_id=865, trove_parent_id=534, shortname="testers", fullname="Testers", fullpath="Intended Audience :: by End-User Class :: Testers") M.TroveCategory(trove_cat_id=866, trove_parent_id=534, shortname="secpros", fullname="Security Professionals", fullpath="Intended Audience :: by End-User Class :: Security Professionals") M.TroveCategory(trove_cat_id=867, trove_parent_id=535, shortname="secindustry", fullname="Security", fullpath="Intended Audience :: by Industry or Sector :: Security") ThreadLocalORMSession.flush_all() ThreadLocalORMSession.close_all()
def test_snapshot_from_username(): s = M.Snapshot(author={'username': '******', 'display_name': 'John Doe', 'logged_ip': '1.2.3.4'}) s = M.Snapshot(author={'username': '******', 'display_name': 'John Doe', 'logged_ip': '1.2.3.4'}) ThreadLocalORMSession.flush_all() assert_equal(len(M.Snapshot.from_username('johndoe')), 1)
def test_feed_from_username(): M.Feed(author_name='John Doe', author_link='/u/johndoe/', title='Something') M.Feed(author_name='John Smith', author_link='/u/johnsmith/', title='Something') ThreadLocalORMSession.flush_all() assert_equal(len(M.Feed.from_username('johndoe')), 1)
def test_project_disabled_users(): p = M.Project.query.get(shortname="test") users = p.users() assert users[0].username == "test-admin" user = M.User.by_username("test-admin") user.disabled = True ThreadLocalORMSession.flush_all() users = p.users() assert users == []
def test_project_disabled_users(): p = M.Project.query.get(shortname='test') users = p.users() assert users[0].username == 'test-admin' user = M.User.by_username('test-admin') user.disabled = True ThreadLocalORMSession.flush_all() users = p.users() assert users == []
def test_user_project_already_deleted_creates_on_demand(): u = M.User.register(dict(username='******'), make_project=True) p = M.Project.query.get(shortname='u/foobar123') p.deleted = True ThreadLocalORMSession.flush_all() assert not M.Project.query.get(shortname='u/foobar123', deleted=False) assert u.private_project() ThreadLocalORMSession.flush_all() assert M.Project.query.get(shortname='u/foobar123', deleted=False)
def test_user_disabled(self, gen_message_id, sendmail): user = M.User.query.get(username='******') email = M.EmailAddress.query.find( {'claimed_by_user_id': user._id}).first() user.disabled = True ThreadLocalORMSession.flush_all() self.app.post('/auth/password_recovery_hash', {'email': email._id}) hash = user.get_tool_data('AuthPasswordReset', 'hash') assert hash is None
def custom(self, ticket, field, value): field = '_' + field if not c.app.has_custom_field(field): log.warning('Custom field %s is not defined, defining as string', field) c.app.globals.custom_fields.append(dict(name=field, label=field[1:].capitalize(), type='string')) ThreadLocalORMSession.flush_all() if 'custom_fields' not in ticket: ticket['custom_fields'] = {} ticket['custom_fields'][field] = value
def test_related_artifacts(self): self._post(title='one') d = self._blog_date() self._post(title='two', text='[blog:%s/one]' % d) M.MonQTask.run_ready() ThreadLocalORMSession.flush_all() r = self.app.get('/blog/%s/one/' % d) assert 'Related' in r assert 'Blog: %s/two' % d in r
def test_user_project_already_deleted_creates_on_demand(): u = M.User.register(dict(username='******'), make_project=True) p = M.Project.query.get(shortname='u/foobar123') p.deleted = True ThreadLocalORMSession.flush_all() assert not M.Project.query.get(shortname='u/foobar123', deleted=False) assert u.private_project() ThreadLocalORMSession.flush_all() assert M.Project.query.get(shortname='u/foobar123', deleted=False)
def test_related_artifacts(self): self._post(title='one') d = self._blog_date() self._post(title='two', text='[blog:%s/one]' % d) M.MonQTask.run_ready() ThreadLocalORMSession.flush_all() r = self.app.get('/blog/%s/one/' % d) assert 'Related' in r assert 'Blog Post: %s/two' % d in r
def test_user_subproject_home_not_profile(self): u_proj = M.Project.query.get(shortname='u/test-admin') u_proj.new_subproject('sub1') from ming.orm.ormsession import ThreadLocalORMSession ThreadLocalORMSession.flush_all() r = self.app.get('/u/test-admin/sub1/') assert r.location.endswith('admin/'), r.location assert_not_in('Profile', r.follow().body)
def test_user_subproject_home_not_profile(self): u_proj = M.Project.query.get(shortname='u/test-admin') u_proj.new_subproject('sub1') from ming.orm.ormsession import ThreadLocalORMSession ThreadLocalORMSession.flush_all() r = self.app.get('/u/test-admin/sub1/') assert r.location.endswith('admin/'), r.location r.follow()