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)
예제 #3
0
    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))
예제 #4
0
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)
예제 #6
0
    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)
예제 #7
0
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)
예제 #9
0
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('​', '')
예제 #10
0
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)
예제 #11
0
 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.')
예제 #13
0
 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)
예제 #14
0
 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.')
예제 #15
0
 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))
예제 #17
0
    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"))
예제 #18
0
    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 ..."))
예제 #21
0
 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_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_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 ..."))
예제 #27
0
 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))
예제 #29
0
 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)
예제 #30
0
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)
예제 #32
0
 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)
예제 #33
0
 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)
예제 #34
0
 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)
예제 #35
0
 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)
예제 #37
0
 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)
예제 #38
0
 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)
예제 #39
0
 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)
예제 #40
0
 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))
예제 #41
0
 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_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)
예제 #43
0
 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)
예제 #44
0
    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'))
예제 #45
0
 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)
예제 #46
0
 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)