def test_discharge_macaroon_missing(self): # If a discharge macaroon was requested but not received, the login # error page is shown. test_email = '*****@*****.**' person = self.factory.makePerson(email=test_email) identifier = ITestOpenIDPersistentIdentity( person.account).openid_identity_url openid_response = FakeOpenIDResponse(identifier, status=SUCCESS, message='', email=test_email, full_name='Foo User') form = { 'starting_url': 'http://launchpad.dev/after-login', 'discharge_macaroon_action': 'field.actions.complete', 'discharge_macaroon_field': 'field.discharge_macaroon', } with SRegResponse_fromSuccessResponse_stubbed(): with MacaroonResponse_fromSuccessResponse_stubbed(): view, html = self._createAndRenderView(openid_response, form=form) self.assertFalse(view.login_called) main_content = extract_text(find_main_content(html)) self.assertIn( "OP didn't include a macaroon extension in the response.", main_content)
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 extract_bugtasks(text, show_heat=None): """Extracts a list of strings for all the bugtasks in the text.""" main_content = find_main_content(text) listing = main_content.find('div', {'id': 'bugs-table-listing'}) if listing is None: return [] rows = [] for bugtask in listing('div', {'class': 'buglisting-row'}): bug_nr = extract_text( bugtask.find(None, {'class': 'bugnumber'})).replace('#', '') title = extract_text(bugtask.find(None, {'class': 'bugtitle'})) status = extract_text( bugtask.find(None, {'class': re.compile('status')})) importance = extract_text( bugtask.find(None, {'class': re.compile('importance')})) affects = extract_text( bugtask.find( None, {'class': re.compile( 'None|(sprite product|distribution|package-source) field') })) row_items = [bug_nr, title, affects, importance, status] if show_heat: heat = extract_text( bugtask.find(None, {'class': 'bug-heat-icons'})) row_items.append(heat) rows.append(' '.join(row_items)) return rows
def test_edit_livefs(self): archive = self.factory.makeArchive() old_series = self.factory.makeDistroSeries( distribution=archive.distribution, status=SeriesStatus.CURRENT) livefs = self.factory.makeLiveFS(registrant=self.person, owner=self.person, distroseries=old_series) self.factory.makeTeam(name="new-team", displayname="New Team", members=[self.person]) new_series = self.factory.makeDistroSeries( distribution=archive.distribution, status=SeriesStatus.DEVELOPMENT) browser = self.getViewBrowser(livefs, user=self.person) browser.getLink("Edit live filesystem").click() browser.getControl("Owner").value = ["new-team"] browser.getControl("Name").value = "new-name" browser.getControl(name="field.distro_series").value = [ str(new_series.id) ] browser.getControl("Live filesystem build metadata").value = ( '{"product": "new-name"}') browser.getControl("Update live filesystem").click() content = find_main_content(browser.contents) self.assertEqual("new-name\nEdit", extract_text(content.h1)) self.assertThat("New Team", MatchesPickerText(content, "edit-owner")) self.assertThat( "Distribution series:\n%s\nEdit live filesystem" % new_series.fullseriesname, MatchesTagText(content, "distro_series")) self.assertThat("Metadata:\nproduct\nnew-name", MatchesTagText(content, "metadata"))
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_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_builder_history(self): Store.of(self.build).flush() self.build.updateStatus(BuildStatus.FULLYBUILT, builder=self.factory.makeBuilder()) title = self.build.title browser = self.getViewBrowser(self.build.builder, "+history") self.assertTextMatchesExpressionIgnoreWhitespace( "Build history.*%s" % title, extract_text(find_main_content(browser.contents))) self.assertEqual(self.build_url, browser.getLink(title).url)
def _test_search_batch_request(self, context, user=None): # A search request with a 'batch_request' query parameter causes the # view to just render the next batch of results. view = create_initialized_view( context, name="+branches", rootsite='code', principal=user, query_string='batch_request=True') content = view() self.assertIsNone(find_main_content(content)) self.assertIsNotNone( find_tag_by_id(content, 'branches-table-listing'))
def test_negative_openid_assertion(self): # The OpenID provider responded with a negative assertion, so the # login error page is shown. person = self.factory.makePerson() view, html = self._createViewWithResponse( person.account, response_status=FAILURE, response_msg='Server denied check_authentication') self.assertFalse(view.login_called) main_content = extract_text(find_main_content(html)) self.assertIn('Your login was unsuccessful', main_content)
def test_suspended_account(self): # There's a chance that our OpenID Provider lets a suspended account # login, but we must not allow that. person = self.factory.makePerson( account_status=AccountStatus.SUSPENDED) with SRegResponse_fromSuccessResponse_stubbed(): view, html = self._createViewWithResponse(person.account) self.assertFalse(view.login_called) main_content = extract_text(find_main_content(html)) self.assertIn('This account has been suspended', main_content)
def test_search_batch_request(self): # A search request with a 'batch_request' query parameter causes the # view to just render the next batch of results. product = self.factory.makeProduct() form = {'search': 'Search'} view = create_initialized_view( product, '+bugs', form=form, query_string='batch_request=True') content = view() self.assertIsNone(find_main_content(content)) self.assertIsNotNone( find_tag_by_id(content, 'bugs-batch-links-upper'))
def _test_search_batch_request(self, context, user=None): # A search request with a 'batch_request' query parameter causes the # view to just render the next batch of results. view = create_initialized_view(context, name="+branches", rootsite='code', principal=user, query_string='batch_request=True') content = view() self.assertIsNone(find_main_content(content)) self.assertIsNotNone(find_tag_by_id(content, 'branches-table-listing'))
def test_missing_fields(self): # If the OpenID provider response does not include required fields # (full name or email missing), the login error page is shown. person = self.factory.makePerson() with SRegResponse_fromSuccessResponse_stubbed(): view, html = self._createViewWithResponse(person.account, email=None) self.assertFalse(view.login_called) main_content = extract_text(find_main_content(html)) self.assertIn('No email address or full name found in sreg response', main_content)
def test_search_batch_request(self): # A search request with a 'batch_request' query parameter causes the # view to just render the next batch of results. product = self.factory.makeProduct() form = {'search': 'Search'} view = create_initialized_view(product, '+bugs', form=form, query_string='batch_request=True') content = view() self.assertIsNone(find_main_content(content)) self.assertIsNotNone(find_tag_by_id(content, 'bugs-batch-links-upper'))
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_missing_fields(self): # If the OpenID provider response does not include required fields # (full name or email missing), the login error page is shown. person = self.factory.makePerson() with SRegResponse_fromSuccessResponse_stubbed(): view, html = self._createViewWithResponse( person.account, email=None) self.assertFalse(view.login_called) main_content = extract_text(find_main_content(html)) self.assertIn( 'No email address or full name found in sreg response', main_content)
def test_builder_history(self): build = self.makeRecipeBuild() Store.of(build).flush() build_url = canonical_url(build) build.updateStatus( BuildStatus.FULLYBUILT, builder=self.factory.makeBuilder()) browser = self.getViewBrowser(build.builder, '+history') self.assertTextMatchesExpressionIgnoreWhitespace( 'Build history.*~chef/chocolate/cake recipe build', extract_text(find_main_content(browser.contents))) self.assertEqual(build_url, browser.getLink('~chef/chocolate/cake recipe build').url)
def test_builder_history(self): build = self.makeRecipeBuild() Store.of(build).flush() build_url = canonical_url(build) build.updateStatus(BuildStatus.FULLYBUILT, builder=self.factory.makeBuilder()) browser = self.getViewBrowser(build.builder, '+history') self.assertTextMatchesExpressionIgnoreWhitespace( 'Build history.*~chef/chocolate/cake recipe build', extract_text(find_main_content(browser.contents))) self.assertEqual( build_url, browser.getLink('~chef/chocolate/cake recipe build').url)
def test_account_with_team_email_address(self): # If the email address from the OpenID provider is owned by a # team, there's not much we can do. See bug #556680 for # discussions about a proper solution. self.factory.makeTeam(email="*****@*****.**") with SRegResponse_fromSuccessResponse_stubbed(): view, html = self._createViewWithResponse( None, email="*****@*****.**", identifier=self.factory.getUniqueString()) self.assertFalse(view.login_called) main_content = extract_text(find_main_content(html)) self.assertIn('Team email address conflict', main_content)
def print_bug_affects_table(content, highlighted_only=False): """Print information about all the bug tasks in the 'affects' table. :param highlighted_only: Only print the highlighted row """ main_content = find_main_content(content) affects_table = main_content.first('table', {'class': 'listing'}) if highlighted_only: tr_attrs = {'class': 'highlight'} else: tr_attrs = {} tr_tags = affects_table.tbody.findAll( 'tr', attrs=tr_attrs, recursive=False) for tr in tr_tags: if tr.td.table: # Don't print the bugtask edit form. continue # Strip zero-width white-spaces. print extract_text(tr).replace('​', '')
def test_create_new_livefs(self): archive = self.factory.makeArchive() distroseries = self.factory.makeDistroSeries( distribution=archive.distribution, status=SeriesStatus.DEVELOPMENT) browser = self.getViewBrowser(self.person, view_name="+new-livefs", user=self.person) browser.getControl("Name").value = "ubuntu-core" browser.getControl("Live filesystem build metadata").value = ( '{"product": "ubuntu-core", "image_format": "plain"}') browser.getControl("Create live filesystem").click() content = find_main_content(browser.contents) self.assertEqual("ubuntu-core\nEdit", extract_text(content.h1)) self.assertThat("Test Person", MatchesPickerText(content, "edit-owner")) self.assertThat( "Distribution series:\n%s\nEdit live filesystem" % distroseries.fullseriesname, MatchesTagText(content, "distro_series")) self.assertThat("Metadata:\nimage_format\nplain\nproduct\nubuntu-core", MatchesTagText(content, "metadata"))