def test_basic_for_person(self): """Check that the page shows the bugs/work items assigned to a person. """ person = self.factory.makePerson() workitem = self.factory.makeSpecificationWorkItem( assignee=person, milestone=self.today_milestone) bugtask = self.factory.makeBug( milestone=self.tomorrow_milestone).bugtasks[0] removeSecurityProxy(bugtask).assignee = person browser = self.getViewBrowser( person, view_name='+upcomingwork', no_login=True) # Check that the two work items created above are shown and grouped # under the appropriate milestone date. groups = find_tags_by_class(browser.contents, 'workitems-group') self.assertEqual(2, len(groups)) todays_group = extract_text(groups[0]) tomorrows_group = extract_text(groups[1]) self.assertStartsWith( todays_group, 'Work items due in %s' % self.today) self.assertIn(workitem.title, todays_group) self.assertStartsWith( tomorrows_group, 'Work items due in %s' % self.tomorrow) with anonymous_logged_in(): self.assertIn(bugtask.bug.title, tomorrows_group)
def test_basic_for_person(self): """Check that the page shows the bugs/work items assigned to a person. """ person = self.factory.makePerson() workitem = self.factory.makeSpecificationWorkItem( assignee=person, milestone=self.today_milestone) bugtask = self.factory.makeBug( milestone=self.tomorrow_milestone).bugtasks[0] removeSecurityProxy(bugtask).assignee = person browser = self.getViewBrowser(person, view_name='+upcomingwork', no_login=True) # Check that the two work items created above are shown and grouped # under the appropriate milestone date. groups = find_tags_by_class(browser.contents, 'workitems-group') self.assertEqual(2, len(groups)) todays_group = extract_text(groups[0]) tomorrows_group = extract_text(groups[1]) self.assertStartsWith(todays_group, 'Work items due in %s' % self.today) self.assertIn(workitem.title, todays_group) self.assertStartsWith(tomorrows_group, 'Work items due in %s' % self.tomorrow) with anonymous_logged_in(): self.assertIn(bugtask.bug.title, tomorrows_group)
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 print_upstream_linking_form(browser): """Print the upstream linking form found via +choose-affected-product. The resulting output will look something like: (*) A checked option [A related text field] ( ) An unchecked option """ soup = BeautifulSoup(browser.contents) link_upstream_how_radio_control = browser.getControl( name='field.link_upstream_how') link_upstream_how_buttons = soup.findAll( 'input', {'name': 'field.link_upstream_how'}) wrapper = textwrap.TextWrapper(width=65, subsequent_indent=' ') for button in link_upstream_how_buttons: # Print the radio button. label = button.findParent('label') if label is None: label = soup.find('label', {'for': button['id']}) if button.get('value') in link_upstream_how_radio_control.value: print wrapper.fill('(*) %s' % extract_text(label)) else: print wrapper.fill('( ) %s' % extract_text(label)) # Print related text field, if found. Assumes that the text # field is in the same table row as the radio button. text_field = button.findParent('tr').find('input', {'type': 'text'}) if text_field is not None: text_control = browser.getControl(name=text_field.get('name')) print ' [%s]' % text_control.value.ljust(10)
def test_basic_for_team(self): """Check that the page shows the bugs/work items assigned to members of a team. """ workitem1 = self.factory.makeSpecificationWorkItem( assignee=self.team.teamowner, milestone=self.today_milestone) workitem2 = self.factory.makeSpecificationWorkItem( assignee=self.team.teamowner, milestone=self.tomorrow_milestone) bugtask1 = self.factory.makeBug( milestone=self.today_milestone).bugtasks[0] bugtask2 = self.factory.makeBug( milestone=self.tomorrow_milestone).bugtasks[0] for bugtask in [bugtask1, bugtask2]: removeSecurityProxy(bugtask).assignee = self.team.teamowner browser = self.getViewBrowser( self.team, view_name='+upcomingwork', no_login=True) # Check that the two work items and bugtasks created above are shown # and grouped under the appropriate milestone date. groups = find_tags_by_class(browser.contents, 'workitems-group') self.assertEqual(2, len(groups)) todays_group = extract_text(groups[0]) tomorrows_group = extract_text(groups[1]) self.assertStartsWith( todays_group, 'Work items due in %s' % self.today) self.assertIn(workitem1.title, todays_group) with anonymous_logged_in(): self.assertIn(bugtask1.bug.title, todays_group) self.assertStartsWith( tomorrows_group, 'Work items due in %s' % self.tomorrow) self.assertIn(workitem2.title, tomorrows_group) with anonymous_logged_in(): self.assertIn(bugtask2.bug.title, tomorrows_group)
def test_merge_queue_list_contents(self): self.enable_queue_flag() login_person(self.branch_owner) browser = self.getUserBrowser( canonical_url(self.branch_owner, rootsite='code', view_name='+merge-queues'), self.branch_owner) table = find_tag_by_id(browser.contents, 'mergequeuetable') merge_queue_info = {} for row in table.tbody.fetch('tr'): cells = row('td') row_info = {} queue_name = extract_text(cells[0]) if not queue_name.startswith('queue'): continue qlink = extract_link_from_tag(cells[0].find('a')) row_info['queue_link'] = qlink queue_size = extract_text(cells[1]) row_info['queue_size'] = queue_size queue_branches = cells[2]('a') branch_links = set() for branch_tag in queue_branches: branch_links.add(extract_link_from_tag(branch_tag)) row_info['branch_links'] = branch_links merge_queue_info[queue_name] = row_info expected_queue_names = [queue.name for queue in self.merge_queues] self.assertEqual(set(expected_queue_names), set(merge_queue_info.keys())) #TODO: when IBranchMergeQueue API is available remove '4' expected_queue_sizes = dict([(queue.name, '4') for queue in self.merge_queues]) observed_queue_sizes = dict([ (queue.name, merge_queue_info[queue.name]['queue_size']) for queue in self.merge_queues ]) self.assertEqual(expected_queue_sizes, observed_queue_sizes) def branch_links(branches): return [ canonical_url(removeSecurityProxy(branch), force_local_path=True) for branch in branches ] expected_queue_branches = dict([(queue.name, set(branch_links(queue.branches))) for queue in self.merge_queues]) observed_queue_branches = dict([ (queue.name, merge_queue_info[queue.name]['branch_links']) for queue in self.merge_queues ]) self.assertEqual(expected_queue_branches, observed_queue_branches)
def print_remote_bugtasks(content): """Print the remote bugtasks of this bug. For each remote bugtask, print the target and the bugwatch. """ affects_table = find_tags_by_class(content, 'listing')[0] for span in affects_table.findAll('span'): for key, value in span.attrs: if 'bug-remote' in value: target = extract_text(span.findAllPrevious('td')[-2]) print target, extract_text(span.findNext('a'))
def test_merge_queue_list_contents(self): self.enable_queue_flag() login_person(self.branch_owner) browser = self.getUserBrowser( canonical_url(self.branch_owner, rootsite='code', view_name='+merge-queues'), self.branch_owner) table = find_tag_by_id(browser.contents, 'mergequeuetable') merge_queue_info = {} for row in table.tbody.fetch('tr'): cells = row('td') row_info = {} queue_name = extract_text(cells[0]) if not queue_name.startswith('queue'): continue qlink = extract_link_from_tag(cells[0].find('a')) row_info['queue_link'] = qlink queue_size = extract_text(cells[1]) row_info['queue_size'] = queue_size queue_branches = cells[2]('a') branch_links = set() for branch_tag in queue_branches: branch_links.add(extract_link_from_tag(branch_tag)) row_info['branch_links'] = branch_links merge_queue_info[queue_name] = row_info expected_queue_names = [queue.name for queue in self.merge_queues] self.assertEqual( set(expected_queue_names), set(merge_queue_info.keys())) #TODO: when IBranchMergeQueue API is available remove '4' expected_queue_sizes = dict( [(queue.name, '4') for queue in self.merge_queues]) observed_queue_sizes = dict( [(queue.name, merge_queue_info[queue.name]['queue_size']) for queue in self.merge_queues]) self.assertEqual( expected_queue_sizes, observed_queue_sizes) def branch_links(branches): return [canonical_url(removeSecurityProxy(branch), force_local_path=True) for branch in branches] expected_queue_branches = dict( [(queue.name, set(branch_links(queue.branches))) for queue in self.merge_queues]) observed_queue_branches = dict( [(queue.name, merge_queue_info[queue.name]['branch_links']) for queue in self.merge_queues]) self.assertEqual( expected_queue_branches, observed_queue_branches)
def print_bugs_list(content, list_id): """Print the bugs list with the given ID. Right now this is quite simplistic, in that it just extracts the text from the element specified by list_id. If the bug listing becomes more elaborate then this function will be the place to cope with it. """ bugs_list = find_tag_by_id(content, list_id).findAll( None, {'class': 'similar-bug'}) for node in bugs_list: # Also strip zero-width spaces out. print extract_text(node).replace('​', '')
def print_ul(ul): """Print the data from a list.""" li_content = [] for li in ul.findAll('li'): li_content.append(extract_text(li)) if len(li_content) > 0: print '\n'.join(li_content)
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_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_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_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_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_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_redeem_twice_causes_error(self): # If a voucher is redeemed twice, the second attempt is rejected. commercial_admin = login_celebrity('commercial_admin') voucher_id_1, voucher_id_2 = self.makeVouchers(commercial_admin, 2) project_1 = self.factory.makeProduct(name='p1') project_2 = self.factory.makeProduct(name='p2') url = canonical_url(commercial_admin, view_name='+vouchers') browser = self.getUserBrowser(url, commercial_admin) # A second browser opens the +vouchers page before the first browser # attempts to redeem the voucher. browser2 = self.getUserBrowser(url, commercial_admin) browser.getControl( 'Select the project you wish to subscribe').value = 'p1' browser.getControl('Select a voucher').getControl( voucher_id_1).selected = True browser.getControl('Redeem').click() with person_logged_in(commercial_admin): self.assertIsNotNone(project_1.commercial_subscription) browser2.getControl( 'Select the project you wish to subscribe').value = 'p2' browser2.getControl('Select a voucher').getControl( voucher_id_1).selected = True browser2.getControl('Redeem').click() with person_logged_in(commercial_admin): self.assertIsNone(project_2.commercial_subscription) error_messages = find_tags_by_class(browser2.contents, 'message') self.assertEqual(extract_text(error_messages[1]), 'Invalid value')
def test_redeem_twice_causes_error(self): # If a voucher is redeemed twice, the second attempt is rejected. commercial_admin = login_celebrity('commercial_admin') voucher_id_1, voucher_id_2 = self.makeVouchers(commercial_admin, 2) project_1 = self.factory.makeProduct(name='p1') project_2 = self.factory.makeProduct(name='p2') url = canonical_url(commercial_admin, view_name='+vouchers') browser = self.getUserBrowser(url, commercial_admin) # A second browser opens the +vouchers page before the first browser # attempts to redeem the voucher. browser2 = self.getUserBrowser(url, commercial_admin) browser.getControl( 'Select the project you wish to subscribe').value = 'p1' browser.getControl( 'Select a voucher').getControl(voucher_id_1).selected = True browser.getControl('Redeem').click() with person_logged_in(commercial_admin): self.assertIsNotNone(project_1.commercial_subscription) browser2.getControl( 'Select the project you wish to subscribe').value = 'p2' browser2.getControl( 'Select a voucher').getControl(voucher_id_1).selected = True browser2.getControl('Redeem').click() with person_logged_in(commercial_admin): self.assertIsNone(project_2.commercial_subscription) error_messages = find_tags_by_class(browser2.contents, 'message') self.assertEqual(extract_text(error_messages[1]), 'Invalid value')
def test_registration_date_displayed(self): """The time frame does not prepend on incorrectly.""" spec = self.factory.makeSpecification(owner=self.factory.makePerson( displayname="Some Person")) html = create_initialized_view(spec, '+index')() self.assertThat( extract_text(html), DocTestMatches("... Registered by Some Person ... ago ..."))
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_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_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_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_registration_date_displayed(self): """The time frame does not prepend on incorrectly.""" spec = self.factory.makeSpecification( owner=self.factory.makePerson(displayname="Some Person")) html = create_initialized_view( spec, '+index')() self.assertThat( extract_text(html), DocTestMatches( "... Registered by Some Person ... ago ..."))
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_private_message_message_without_list(self): # Private teams have private archives. owner = self.factory.makePerson() team = self.factory.makeTeam( owner=owner, visibility=PersonVisibility.PRIVATE) login_person(owner) view = create_initialized_view( team, name='+mailinglist', principal=owner) element = find_tag_by_id(view(), 'mailing-list-archive') self.assertEqual('private', extract_text(element))
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 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_private_team_membership_for_team_member(self): # If the logged in user can see the private teams, they are shown in # the related 'Branches owned by' section at the bottom of the page. private_team, member, branch = self._make_branch_for_private_team() browser = self.getUserBrowser(canonical_url(member, rootsite='code'), member) branches = find_tag_by_id(browser.contents, 'portlet-team-branches') text = extract_text(branches) self.assertTextMatchesExpressionIgnoreWhitespace( 'Branches owned by Shh', text)
def test_merge_with_multiple_emails_request(self): # Requesting a merge of an account with multiple email addresses # informs the user confirmation emails are sent out. browser = self._assert_perform_merge_request() confirmation = find_tag_by_id(browser.contents, 'confirmation') self.assertThat( extract_text(confirmation), DocTestMatches( "Confirmation email messages were sent to:...")) self.assertIn('*****@*****.**', browser.contents) self.assertIn('*****@*****.**', browser.contents)
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_merge_with_multiple_emails_request(self): # Requesting a merge of an account with multiple email addresses # informs the user confirmation emails are sent out. browser = self._assert_perform_merge_request() confirmation = find_tag_by_id(browser.contents, 'confirmation') self.assertThat( extract_text(confirmation), DocTestMatches("Confirmation email messages were sent to:...")) self.assertIn('*****@*****.**', browser.contents) self.assertIn('*****@*****.**', browser.contents)
def test_display_processors(self): ppa = self.factory.makeArchive() owner = login_person(ppa.owner) browser = self.getUserBrowser(canonical_url(ppa) + "/+edit", user=owner) processors = browser.getControl(name="field.processors") self.assertContentEqual( ["Intel 386 (386)", "AMD 64bit (amd64)", "HPPA Processor (hppa)"], [extract_text(option) for option in processors.displayOptions]) self.assertContentEqual(["386", "amd64", "hppa"], processors.options)
def test_private_team_membership_for_team_member(self): # If the logged in user can see the private teams, they are shown in # the related 'Branches owned by' section at the bottom of the page. private_team, member, branch = self._make_branch_for_private_team() browser = self.getUserBrowser( canonical_url(member, rootsite='code'), member) branches = find_tag_by_id(browser.contents, 'portlet-team-branches') text = extract_text(branches) self.assertTextMatchesExpressionIgnoreWhitespace( 'Branches owned by Shh', text)
def test_merge_with_hidden_emails_submit(self): # The merge request sends out emails but does not show the hidden email # addresses. browser = self._assert_perform_merge_request() confirmation = find_tag_by_id(browser.contents, 'confirmation') self.assertThat( extract_text(confirmation), DocTestMatches( "Confirmation email messages were sent to the 2 registered " "e-mail addresses...")) self.assertNotIn('*****@*****.**', browser.contents) self.assertNotIn('*****@*****.**', browser.contents)
def match(self, matchee): # Here to avoid circular dependancies. from lp.testing.pages import extract_text widgets = self.soup_content.findAll(id=self.tag_id) if len(widgets) == 0: return MissingElement(self.tag_id, self.soup_content) elif len(widgets) > 1: return MultipleElements(self.tag_id, self.soup_content) widget = widgets[0] text_matcher = DocTestMatches(extract_text(widget)) return text_matcher.match(matchee)
def test_is_public(self): product = self.factory.makeProduct() product_displayname = product.displayname branch = self.factory.makeProductBranch(product=product) login_person(product.owner) product.development_focus.branch = branch browser = self.getUserBrowser(canonical_url(product, rootsite='code')) text = extract_text(find_tag_by_id(browser.contents, 'privacy')) expected = ("New branches for %(name)s are Public.*" % dict(name=product_displayname)) self.assertTextMatchesExpressionIgnoreWhitespace(expected, text)
def test_event_types(self): # Only event types that are valid for the target are offered. browser = self.getUserBrowser(canonical_url(self.webhook, view_name="+index"), user=self.owner) event_types = browser.getControl(name="field.event_types") display_options = [ extract_text(option) for option in event_types.displayOptions ] self.assertContentEqual(self.expected_event_types, zip(event_types.options, display_options))
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_is_public(self): product = self.factory.makeProduct() product_displayname = product.displayname branch = self.factory.makeProductBranch(product=product) login_person(product.owner) product.development_focus.branch = branch browser = self.getUserBrowser(canonical_url(product, rootsite='code')) text = extract_text(find_tag_by_id(browser.contents, 'privacy')) expected = ( "New branches for %(name)s are Public.*" % dict(name=product_displayname)) self.assertTextMatchesExpressionIgnoreWhitespace(expected, text)
def assertSvnDetailsDisplayed(self, svn_details, rcs_type): """Assert the `svn_details` tag describes a Subversion import. :param svn_details: The BeautifulSoup object for the 'svn-import-details' area. :param rcs_type: SVN or BZR_SVN from RevisionControlSystems. """ self.assertEquals(rcs_type.title, svn_details.span['title']) text = re.sub('\s+', ' ', extract_text(svn_details)) self.assertTrue( text.startswith( 'This branch is an import of the Subversion branch'))
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 match(self, matchee): # Here to avoid circular dependancies. from lp.testing.pages import extract_text widgets = self.soup_content.findAll(id=self.widget_id) if len(widgets) == 0: return MissingElement(self.widget_id, self.soup_content) elif len(widgets) > 1: return MultipleElements(self.widget_id, self.soup_content) widget = widgets[0] text = widget.findAll(attrs={'class': 'yui3-activator-data-box'})[0] text_matcher = DocTestMatches(extract_text(text)) return text_matcher.match(matchee)