def test_replay_attacks_do_not_succeed(self): browser = Browser(mech_browser=MyMechanizeBrowser()) browser.open('%s/+login' % self.layer.appserver_root_url()) # On a JS-enabled browser this page would've been auto-submitted # (thanks to the onload handler), but here we have to do it manually. self.assertIn('body onload', browser.contents) browser.getControl('Continue').click() self.assertEquals('Login', browser.title) fill_login_form_and_submit(browser, '*****@*****.**') login_status = extract_text( find_tag_by_id(browser.contents, 'logincontrol')) self.assertIn('Sample Person (name12)', login_status) # Now we look up (in urls_redirected_to) the +openid-callback URL that # was used to complete the authentication and open it on a different # browser with a fresh set of cookies. replay_browser = Browser() [callback_url] = [ url for url in urls_redirected_to if '+openid-callback' in url] self.assertIsNot(None, callback_url) replay_browser.open(callback_url) login_status = extract_text( find_tag_by_id(replay_browser.contents, 'logincontrol')) self.assertEquals('Log in / Register', login_status) error_msg = find_tags_by_class(replay_browser.contents, 'error')[0] self.assertEquals('Nonce already used or out of range', extract_text(error_msg))
def test_has_bugtracker_external_is_true(self): bug_target = self._makeBugTargetProduct(bug_tracker='external') user = self.factory.makePerson() view = create_initialized_view(bug_target, '+bugs', principal=user) self.assertEqual(True, view.has_bugtracker) markup = view.render() self.assertIsNone(find_tag_by_id(markup, 'bugs-search-form')) self.assertIsNone(find_tag_by_id(markup, 'bugs-table-listings'))
def test_feature_page_can_view(self): """User that can only view the rules do not see the form.""" browser = self.getUserBrowserAsTeamMember( [getUtility(ILaunchpadCelebrities).registry_experts]) browser.open(self.getFeatureRulesViewURL()) content = find_main_content(browser.contents) self.assertEqual(None, find_tag_by_id(content, 'field.feature_rules')) self.assertEqual(None, find_tag_by_id(content, 'field.actions.change')) self.assertTrue(find_tag_by_id(content, 'feature-rules'))
def test_assignments_are_batched(self): product = self.factory.makeProduct() self.factory.makeSpecification(product=product) self.factory.makeSpecification(product=product) view = create_initialized_view(product, name='+assignments', query_string="batch=1") content = view.render() self.assertEqual('next', find_tag_by_id(content, 'upper-batch-nav-batchnav-next')['class']) self.assertEqual('next', find_tag_by_id(content, 'lower-batch-nav-batchnav-next')['class'])
def test_portlets_shown_for_HOSTED(self): # If the BranchUsage is HOSTED then the portlets are shown. product, branch = self.makeProductAndDevelopmentFocusBranch() self.assertEqual(ServiceUsage.LAUNCHPAD, product.codehosting_usage) browser = self.getUserBrowser(canonical_url(product, rootsite='code')) contents = browser.contents self.assertIsNot(None, find_tag_by_id(contents, 'branch-portlet')) self.assertIsNot(None, find_tag_by_id(contents, 'privacy')) self.assertIsNot(None, find_tag_by_id(contents, 'involvement')) self.assertIsNot(None, find_tag_by_id( contents, 'portlet-product-codestatistics'))
def test_portlet_not_shown_for_UNKNOWN(self): # If the BranchUsage is UNKNOWN then the portlets are not shown. product = self.factory.makeProduct() self.assertEqual(ServiceUsage.UNKNOWN, product.codehosting_usage) browser = self.getUserBrowser(canonical_url(product, rootsite='code')) contents = browser.contents self.assertIs(None, find_tag_by_id(contents, 'branch-portlet')) self.assertIs(None, find_tag_by_id(contents, 'privacy')) self.assertIs(None, find_tag_by_id(contents, 'involvement')) self.assertIs(None, find_tag_by_id( contents, 'portlet-product-codestatistics'))
def test_traverse_view_private_team_archive_subscriber(self): # A subscriber can traverse and view the archive. with person_logged_in(self.owner): self.archive.newSubscription(self.subscriber, registrant=self.archive.owner) with person_logged_in(self.subscriber): url = canonical_url(self.archive) browser = setupBrowserForUser(self.subscriber) browser.open(url) content = find_tag_by_id(browser.contents, 'document') self.assertIsNotNone(find_tag_by_id(content, 'ppa-install'))
def test_portlet_not_shown_for_UNKNOWN(self): # If the BranchUsage is UNKNOWN then the portlets are not shown. product = self.factory.makeProduct() self.assertEqual(ServiceUsage.UNKNOWN, product.codehosting_usage) browser = self.getUserBrowser(canonical_url(product, rootsite='code')) contents = browser.contents self.assertIs(None, find_tag_by_id(contents, 'branch-portlet')) self.assertIs(None, find_tag_by_id(contents, 'privacy')) self.assertIs(None, find_tag_by_id(contents, 'involvement')) self.assertIs( None, find_tag_by_id(contents, 'portlet-product-branchstatistics'))
def test_portlets_shown_for_HOSTED(self): # If the BranchUsage is HOSTED then the portlets are shown. product, branch = self.makeProductAndDevelopmentFocusBranch() self.assertEqual(ServiceUsage.LAUNCHPAD, product.codehosting_usage) browser = self.getUserBrowser(canonical_url(product, rootsite='code')) contents = browser.contents self.assertIsNot(None, find_tag_by_id(contents, 'branch-portlet')) self.assertIsNot(None, find_tag_by_id(contents, 'privacy')) self.assertIsNot(None, find_tag_by_id(contents, 'involvement')) self.assertIsNot( None, find_tag_by_id(contents, 'portlet-product-branchstatistics'))
def test_traverse_view_private_team_archive_subscriber(self): # A subscriber can traverse and view the archive. with person_logged_in(self.owner): self.archive.newSubscription( self.subscriber, registrant=self.archive.owner) with person_logged_in(self.subscriber): url = canonical_url(self.archive) browser = setupBrowserForUser(self.subscriber) browser.open(url) content = find_tag_by_id(browser.contents, 'document') self.assertIsNotNone(find_tag_by_id(content, 'ppa-install'))
def test_portlets_shown_for_EXTERNAL(self): # If the BranchUsage is EXTERNAL then the portlets are shown. url = "http://example.com/mybranch" product, branch = self.makeProductAndDevelopmentFocusBranch( branch_type=BranchType.MIRRORED, url=url) browser = self.getUserBrowser(canonical_url(product, rootsite='code')) contents = browser.contents self.assertIsNot(None, find_tag_by_id(contents, 'branch-portlet')) self.assertIsNot(None, find_tag_by_id(contents, 'privacy')) self.assertIsNot(None, find_tag_by_id(contents, 'involvement')) self.assertIsNot(None, find_tag_by_id( contents, 'portlet-product-codestatistics'))
def test_feature_page_can_view(self): """User that can only view the rules do not see the form.""" browser = self.getUserBrowserAsTeamMember( [getUtility(ILaunchpadCelebrities).registry_experts]) browser.open(self.getFeatureRulesViewURL()) content = find_main_content(browser.contents) self.assertEqual( None, find_tag_by_id(content, 'field.feature_rules')) self.assertEqual( None, find_tag_by_id(content, 'field.actions.change')) self.assertTrue( find_tag_by_id(content, 'feature-rules'))
def test_portlets_shown_for_EXTERNAL(self): # If the BranchUsage is EXTERNAL then the portlets are shown. url = "http://example.com/mybranch" product, branch = self.makeProductAndDevelopmentFocusBranch( branch_type=BranchType.MIRRORED, url=url) browser = self.getUserBrowser(canonical_url(product, rootsite='code')) contents = browser.contents self.assertIsNot(None, find_tag_by_id(contents, 'branch-portlet')) self.assertIsNot(None, find_tag_by_id(contents, 'privacy')) self.assertIsNot(None, find_tag_by_id(contents, 'involvement')) self.assertIsNot( None, find_tag_by_id(contents, 'portlet-product-branchstatistics'))
def test_assignments_are_batched(self): product = self.factory.makeProduct() self.factory.makeSpecification(product=product) self.factory.makeSpecification(product=product) view = create_initialized_view(product, name='+assignments', query_string="batch=1") content = view.render() self.assertEqual( 'next', find_tag_by_id(content, 'upper-batch-nav-batchnav-next')['class']) self.assertEqual( 'next', find_tag_by_id(content, 'lower-batch-nav-batchnav-next')['class'])
def test_public_achive_message_without_list(self): # Public teams have public archives. team = self.factory.makeTeam() view = create_initialized_view( team, name='+mailinglist', principal=team.teamowner,) element = find_tag_by_id(view(), 'mailing-list-archive') self.assertEqual('public', extract_text(element))
def test_user_without_launchpad_view(self): # When the user does not have launchpad.View on the context, user = self.factory.makePerson() owner = self.factory.makePerson() with person_logged_in(owner): team = self.factory.makeTeam( displayname='Waffles', owner=owner, visibility=PersonVisibility.PRIVATE) archive = self.factory.makeArchive(private=True, owner=team) archive.newSubscription(user, registrant=owner) with person_logged_in(user): for rootsite, view_name in [ (None, '+index'), ('code', '+branches'), ('bugs', '+bugs'), ('blueprints', '+specs'), ('answers', '+questions'), ('translations', '+translations')]: view = create_initialized_view( team, name=view_name, path_info='', principal=user, server_url=canonical_url(team, rootsite=rootsite), rootsite=rootsite) document = find_tag_by_id(view(), 'document') self.assertIsNone(document.find(True, id='side-portlets')) self.assertIsNone(document.find(True, id='registration')) self.assertEndsWith( extract_text(document.find(True, id='maincontent')), 'The information in this page is not shared with you.')
def test_bug_filing_view_with_dupe_search_enabled(self): # When a user files a bug for a product where searching for # duplicate bugs is enabled, they are asked to provide a # summary of the bug. This summary is used to find possible # existing duplicates f this bug. product = self.factory.makeProduct() login_person(product.owner) product.official_malone = True product.enable_bugfiling_duplicate_search = True user = self.factory.makePerson() login_person(user) view = create_initialized_view(product, name='+filebug', principal=user) html = view.render() self.assertIsNot(None, find_tag_by_id(html, 'filebug-search-form')) # The main bug filing form is rendered but hidden inside an invisible # filebug-container. main_content = find_main_content(html) filebug_form = main_content.find(id='filebug-form') self.assertIsNot(None, filebug_form) filebug_form_container = filebug_form.findParents( id='filebug-form-container')[0] class_attrs = [ item.strip() for item in filebug_form_container['class'].split(" ") ] self.assertTrue('hidden' in class_attrs)
def test_bug_filing_view_with_dupe_search_disabled(self): # When a user files a bug for a product where searching for # duplicate bugs is disabled, he can directly enter all # details of the bug. product = self.factory.makeProduct() login_person(product.owner) product.official_malone = True product.enable_bugfiling_duplicate_search = False user = self.factory.makePerson() login_person(user) view = create_initialized_view( product, name='+filebug', principal=user) html = view.render() self.assertIsNot(None, find_tag_by_id(html, 'filebug-form')) # The search form to fing possible duplicates is not shown. self.assertIs(None, find_tag_by_id(html, 'filebug-search-form'))
def test_staging_message_is_demo(self): config.push(self.id(), '') self.addCleanup(config.pop, self.id()) self.useFixture(DemoMode()) view = create_initialized_view(self.product_set, '+new') message = find_tag_by_id(view.render(), 'staging-message') self.assertEqual(None, message)
def test_user_without_launchpad_view(self): # When the user does not have launchpad.View on the context, # base-layout does not render the main slot and side slot. owner = self.factory.makePerson() with person_logged_in(owner): team = self.factory.makeTeam(displayname='Waffles', owner=owner, visibility=PersonVisibility.PRIVATE) archive = self.factory.makeArchive(private=True, owner=team) archive.newSubscription(self.user, registrant=owner) with person_logged_in(self.user): view = self.makeTemplateView('main_side', context=team) content = BeautifulSoup(view()) self.assertIs(None, content.find(text=' Extra head content ')) self.verify_base_layout_html_element(content) self.verify_base_layout_head_parts(view, content) document = find_tag_by_id(content, 'document') self.verify_base_layout_body_parts(document) self.verify_watermark(document) # These parts are unique to the case without launchpad.View. self.assertIsNone(document.find(True, id='side-portlets')) self.assertIsNone(document.find(True, id='registration')) self.assertEndsWith( extract_text(document.find(True, id='maincontent')), 'The information in this page is not shared with you.')
def test_user_without_launchpad_view(self): # When the user does not have launchpad.View on the context, # base-layout does not render the main slot and side slot. owner = self.factory.makePerson() with person_logged_in(owner): team = self.factory.makeTeam( displayname='Waffles', owner=owner, visibility=PersonVisibility.PRIVATE) archive = self.factory.makeArchive(private=True, owner=team) archive.newSubscription(self.user, registrant=owner) with person_logged_in(self.user): view = self.makeTemplateView('main_side', context=team) content = BeautifulSoup(view()) self.assertIs(None, content.find(text=' Extra head content ')) self.verify_base_layout_html_element(content) self.verify_base_layout_head_parts(view, content) document = find_tag_by_id(content, 'document') self.verify_base_layout_body_parts(document) self.verify_watermark(document) # These parts are unique to the case without launchpad.View. self.assertIsNone(document.find(True, id='side-portlets')) self.assertIsNone(document.find(True, id='registration')) self.assertEndsWith( extract_text(document.find(True, id='maincontent')), 'The information in this page is not shared with you.')
def test_bug_filing_view_with_dupe_search_enabled(self): # When a user files a bug for a product where searching for # duplicate bugs is enabled, he is asked to provide a # summary of the bug. This summary is used to find possible # existing duplicates f this bug. product = self.factory.makeProduct() login_person(product.owner) product.official_malone = True product.enable_bugfiling_duplicate_search = True user = self.factory.makePerson() login_person(user) view = create_initialized_view( product, name='+filebug', principal=user) html = view.render() self.assertIsNot(None, find_tag_by_id(html, 'filebug-search-form')) # The main bug filing form is rendered but hidden inside an invisible # filebug-container. main_content = find_main_content(html) filebug_form = main_content.find(id='filebug-form') self.assertIsNot(None, filebug_form) filebug_form_container = filebug_form.findParents( id='filebug-form-container')[0] class_attrs = [item.strip() for item in filebug_form_container['class'].split(" ")] self.assertTrue('hidden' in class_attrs)
def test_also_affects_links_product_bug(self): # We expect that both Also Affects links (for project and distro) are # disallowed. owner = self.factory.makePerson() product = self.factory.makeProduct( bug_sharing_policy=BugSharingPolicy.PROPRIETARY) bug = self.factory.makeBug( target=product, owner=owner, information_type=InformationType.PROPRIETARY) url = canonical_url(bug, rootsite="bugs") browser = self.getUserBrowser(url, user=owner) also_affects = find_tag_by_id(browser.contents, 'also-affects-product') self.assertIn('private-disallow', also_affects['class'].split(' ')) also_affects = find_tag_by_id(browser.contents, 'also-affects-package') self.assertIn('private-disallow', also_affects['class'].split(' '))
def test_comment_owner_sees_hide_control(self): # The comment owner sees the hide control. user = self.factory.makePerson() context = self.getContext(comment_owner=user) view = self.getView(context=context, user=user) hide_link = find_tag_by_id(view.contents, self.control_text) self.assertIsNot(None, hide_link)
def test_committers_count_private_branch_non_subscriber(self): # Test that calling committer_count will return the proper value # for a private branch. fsm = self.factory.makePerson(email='*****@*****.**') product, branch = self.makeProductAndDevelopmentFocusBranch( owner=fsm, information_type=InformationType.USERDATA) date_generator = time_counter( datetime.now(pytz.UTC) - timedelta(days=30), timedelta(days=1)) login_person(fsm) self.factory.makeRevisionsForBranch(branch, author='*****@*****.**', date_generator=date_generator) getUtility(IRevisionSet).updateRevisionCacheForBranch(branch) observer = self.factory.makePerson() login_person(observer) view = create_initialized_view(product, '+branch-summary', rootsite='code', principal=observer) self.assertEqual(view.branch_count, 0) self.assertEqual(view.committer_count, 1) view = create_initialized_view(product, '+portlet-product-branchstatistics', rootsite='code', principal=observer) commit_section = find_tag_by_id(view.render(), 'commits') self.assertIs(None, commit_section)
def test_user_without_launchpad_view(self): # When the user does not have launchpad.View on the context, user = self.factory.makePerson() owner = self.factory.makePerson() with person_logged_in(owner): team = self.factory.makeTeam(displayname='Waffles', owner=owner, visibility=PersonVisibility.PRIVATE) archive = self.factory.makeArchive(private=True, owner=team) archive.newSubscription(user, registrant=owner) with person_logged_in(user): for rootsite, view_name in [(None, '+index'), ('code', '+branches'), ('bugs', '+bugs'), ('blueprints', '+specs'), ('answers', '+questions'), ('translations', '+translations')]: view = create_initialized_view(team, name=view_name, path_info='', principal=user, server_url=canonical_url( team, rootsite=rootsite), rootsite=rootsite) document = find_tag_by_id(view(), 'document') self.assertIsNone(document.find(True, id='side-portlets')) self.assertIsNone(document.find(True, id='registration')) self.assertEndsWith( extract_text(document.find(True, id='maincontent')), 'The information in this page is not shared with you.')
def test_product_without_packaging_also_in_ubuntu_is_none(self): bug_target = self._makeBugTargetProduct(bug_tracker='launchpad') login_person(bug_target.owner) view = create_initialized_view(bug_target, '+bugs', principal=bug_target.owner) self.assertEqual(None, find_tag_by_id(view(), 'also-in-ubuntu'))
def test_page_batched_changes(self): self.makeFeatureFlagChanges() member = login_celebrity('admin') view = create_view( self.root, name='+feature-changelog', principal=member) tag = find_tag_by_id(view.render(), 'changes') self.assertTrue('table', tag.name)
def test_contact_support_logged_in(self): # The support link points to /support when the user is logged in. view = self.makeTemplateView('main_only') view._user = self.user content = BeautifulSoup(view()) footer = find_tag_by_id(content, 'footer') link = footer.find('a', text='Contact Launchpad Support').parent self.assertEqual('/support', link['href'])
def test_subscribe_control_renders(self): login_person(self.user) view = create_view(self.b_team, name='+index', principal=self.user, server_url='http://launchpad.dev', path_info='/~%s' % self.b_team.name) content = view.render() link_tag = find_tag_by_id(content, "link-list-subscribe") self.assertNotEqual(None, link_tag)
def test_bug_filing_view_with_dupe_search_disabled(self): # When a user files a bug for a product where searching for # duplicate bugs is disabled, they can directly enter all # details of the bug. product = self.factory.makeProduct() login_person(product.owner) product.official_malone = True product.enable_bugfiling_duplicate_search = False user = self.factory.makePerson() login_person(user) view = create_initialized_view(product, name='+filebug', principal=user) html = view.render() self.assertIsNot(None, find_tag_by_id(html, 'filebug-form')) # The search form to fing possible duplicates is not shown. self.assertIs(None, find_tag_by_id(html, 'filebug-search-form'))
def test_private_message_message_with_list(self): # Private teams have private archives. team = self.makeTeamWithMailingList( visibility=PersonVisibility.PRIVATE) view = create_initialized_view( team, name='+mailinglist', principal=team.teamowner) element = find_tag_by_id(view(), 'mailing-list-archive') self.assertEqual('private', extract_text(element))
def test_user_with_launchpad_view(self): # Users with launchpad.View do not see the sharing explanation. # See the main_side, main_only, and searchless tests to know # what content is provides to the user who can view. view = self.makeTemplateView('main_side') content = extract_text(find_tag_by_id(view(), 'maincontent')) self.assertNotIn( 'The information in this page is not shared with you.', content)
def test_public_archive(self): # Public teams have public archives. team = self.makeTeamWithMailingList() view = create_view( team, name='+portlet-mailinglist', server_url='http://launchpad.dev', path_info='/~%s' % team.name) link = find_tag_by_id(view(), 'mailing-list-archive') self.assertEqual('View public archive', extract_text(link))
def test_sourcepackage_unknown_bugtracker_no_tags(self): # A SourcePackage whose Distro does not use Launchpad for bug # tracking should not show links to search by bug tags. sp = self._makeSourcePackage() url = canonical_url(sp, rootsite='bugs') browser = self.getUserBrowser(url) self.assertIs(None, find_tag_by_id(browser.contents, 'portlet-tags'), "portlet-tags should not be shown.")
def test_contact_support_anonymous(self): # The support link points to /feedback when the user is anonymous. view = self.makeTemplateView('main_only') view._user = None content = BeautifulSoup(view()) footer = find_tag_by_id(content, 'footer') link = footer.find('a', text='Contact Launchpad Support').parent self.assertEqual('/feedback', link['href'])
def test_page_batched_changes(self): self.makeFeatureFlagChanges() member = login_celebrity('admin') view = create_view(self.root, name='+feature-changelog', principal=member) tag = find_tag_by_id(view.render(), 'changes') self.assertTrue('table', tag.name)
def test_private_bugs_are_not_linked_without_permission(self): bug = self.makeDupeOfPrivateBug() url = canonical_url(bug, rootsite="bugs") browser = self.getUserBrowser(url) dupe_warning = find_tag_by_id(browser.contents, 'warning-comment-on-duplicate') # There is no link in the dupe_warning. self.assertTrue('href' not in dupe_warning)
def test_private_team_membership_for_non_member(self): # Make sure that private teams are not shown (or attempted to be # shown) for people who can not see the private teams. private_team, member, branch = self._make_branch_for_private_team() browser = self.getUserBrowser(canonical_url(member, rootsite='code')) branches = find_tag_by_id(browser.contents, 'portlet-team-branches') # Since there are no teams with branches that the user can see, the # portlet isn't shown. self.assertIs(None, branches)
def test_sourcepackage_unknown_bugtracker_no_button(self): # A SourcePackage whose Distro does not use Launchpad for bug # tracking should not show the "Report a bug" button. sp = self._makeSourcePackage() url = canonical_url(sp, rootsite='bugs') browser = self.getUserBrowser(url) self.assertIs(None, find_tag_by_id(browser.contents, 'involvement'), "Involvement portlet with Report-a-bug button should " "not be shown")
def test_distributionsourcepackage_unknown_bugtracker_no_tags(self): # A DistributionSourcePackage whose Distro does not use # Launchpad for bug tracking should not show links to search by # bug tags. dsp = self._makeDistributionSourcePackage() url = canonical_url(dsp, rootsite='bugs') browser = self.getUserBrowser(url) self.assertIs(None, find_tag_by_id(browser.contents, 'portlet-tags'), "portlet-tags should not be shown.")
def test_private_archive(self): # Private teams have private archives. team = self.makeTeamWithMailingList( visibility=PersonVisibility.PRIVATE) view = create_view( team, name='+portlet-mailinglist', server_url='http://launchpad.dev', path_info='/~%s' % team.name) link = find_tag_by_id(view(), 'mailing-list-archive') self.assertEqual('View private archive', extract_text(link))
def test_branches_get_listing(self): # If a product has a branch, then the project view has a branch # listing. product = self.factory.makeProduct(project=self.project) self.factory.makeProductBranch(product=product) view = create_initialized_view( self.project, name='+branches', rootsite='code') table = find_tag_by_id(view(), "branchtable") self.assertIsNot(None, table)
def test_private_bugs_are_not_linked_without_permission(self): bug = self.makeDupeOfPrivateBug() url = canonical_url(bug, rootsite="bugs") browser = self.getUserBrowser(url) dupe_warning = find_tag_by_id( browser.contents, 'warning-comment-on-duplicate') # There is no link in the dupe_warning. self.assertTrue('href' not in dupe_warning)
def test_project_license_info_data(self): # The projects with the OTHER_* licenese will show license_info data. product = self.factory.makeProduct(name='fnord') with person_logged_in(product.owner): product.licenses = [License.OTHER_OPEN_SOURCE] view = create_initialized_view( self.product_set, '+review-licenses', principal=self.user) content = find_tag_by_id(view.render(), 'project-fnord') self.assertTrue(content.find(id='fnord-license-info') is not None)
def test_cscvs_svn_import(self): # The branch page for a cscvs-imported svn branch contains a summary # of the import details. bzr_svn_import = self.factory.makeCodeImport( rcs_type=RevisionControlSystems.SVN) browser = self.getUserBrowser(canonical_url(bzr_svn_import.branch)) svn_details = find_tag_by_id(browser.contents, 'svn-import-details') self.assertSvnDetailsDisplayed( svn_details, RevisionControlSystems.SVN)