def test_team_admin_subscription(self): # Make a team subscription where the user is an admin, and see what # we record. user = self.factory.makePerson() target = self.factory.makeProduct() request = LaunchpadTestRequest() team = self.factory.makeTeam() with person_logged_in(team.teamowner): team.addMember(user, team.teamowner, status=TeamMembershipStatus.ADMIN) sub = target.addBugSubscription(team, team.teamowner) expose_user_subscriptions_to_js(user, [sub], request) info = IJSONRequestCache(request).objects['subscription_info'] self.assertEqual(len(info), 1) # One target. target_info = info[0] self.assertEqual(target_info['target_title'], target.title) self.assertEqual(target_info['target_url'], canonical_url(target, rootsite='mainsite')) self.assertEqual(len(target_info['filters']), 1) # One filter. filter_info = target_info['filters'][0] self.assertEqual(filter_info['filter'], sub.bug_filters[0]) self.assertTrue(filter_info['subscriber_is_team']) self.assertTrue(filter_info['user_is_team_admin']) self.assertTrue(filter_info['can_mute']) self.assertFalse(filter_info['is_muted']) self.assertEqual(filter_info['subscriber_title'], team.title) self.assertEqual(filter_info['subscriber_link'], absoluteURL(team, IWebServiceClientRequest(request))) self.assertEqual(filter_info['subscriber_url'], canonical_url(team, rootsite='mainsite'))
def metadata_changes_text(self): """Textual representation of the changes to the question metadata.""" question = self.question old_question = self.old_question indent = 4 * ' ' info_fields = [] if question.status != old_question.status: info_fields.append(indent + 'Status: %s => %s' % ( old_question.status.title, question.status.title)) if question.target != old_question.target: info_fields.append( indent + 'Project: %s => %s' % ( old_question.target.displayname, question.target.displayname)) if question.assignee != old_question.assignee: if old_question.assignee is None: old_assignee = None else: old_assignee = old_question.assignee.displayname if question.assignee is None: assignee = None else: assignee = question.assignee.displayname info_fields.append(indent + 'Assignee: %s => %s' % ( old_assignee, assignee)) old_bugs = set(old_question.bugs) bugs = set(question.bugs) for linked_bug in bugs.difference(old_bugs): info_fields.append( indent + 'Linked to bug: #%s\n' % linked_bug.id + indent + '%s\n' % canonical_url(linked_bug) + indent + '"%s"' % linked_bug.title) for unlinked_bug in old_bugs.difference(bugs): info_fields.append( indent + 'Removed link to bug: #%s\n' % unlinked_bug.id + indent + '%s\n' % canonical_url(unlinked_bug) + indent + '"%s"' % unlinked_bug.title) if question.faq != old_question.faq: if question.faq is None: info_fields.append( indent + 'Related FAQ was removed:\n' + indent + old_question.faq.title + '\n' + indent + canonical_url(old_question.faq)) else: info_fields.append( indent + 'Related FAQ set to:\n' + indent + question.faq.title + '\n' + indent + canonical_url(question.faq)) if question.title != old_question.title: info_fields.append('Summary changed to:\n%s' % question.title) if question.description != old_question.description: info_fields.append( 'Description changed to:\n%s' % ( self.wrapper.format(question.description))) question_changes = '\n\n'.join(info_fields) return question_changes
def notify_message_held(message_approval, event): """Send a notification of a message hold to all team administrators.""" message_details = getAdapter(message_approval, IHeldMessageDetails) team = message_approval.mailing_list.team from_address = format_address( team.displayname, config.canonical.noreply_from_address) subject = ( 'New mailing list message requiring approval for %s' % team.displayname) template = get_email_template('new-held-message.txt', app='registry') # Most of the replacements are the same for everyone. replacements = { 'subject': message_details.subject, 'author_name': message_details.author.displayname, 'author_url': canonical_url(message_details.author), 'date': message_details.date, 'message_id': message_details.message_id, 'review_url': '%s/+mailinglist-moderate' % canonical_url(team), 'team': team.displayname, } # Don't wrap the paragraph with the url. def wrap_function(paragraph): return (paragraph.startswith('http:') or paragraph.startswith('https:')) # Send one message to every team administrator. person_set = getUtility(IPersonSet) for address in team.getTeamAdminsEmailAddresses(): user = person_set.getByEmail(address) replacements['user'] = user.displayname body = MailWrapper(72).format( template % replacements, force_wrap=True, wrap_func=wrap_function) simple_sendmail(from_address, address, subject, body)
def test_view_with_source_package_recipe(self): # When a SourcePackageRelease is linked to a # SourcePackageRecipeBuild, the view shows which recipe was # responsible for creating the SPR. sprb = self.factory.makeSourcePackageRecipeBuild( archive=self.archive) recipe = sprb.recipe requester = sprb.requester spph = self.publisher.getPubSource( archive=self.archive, status=PackagePublishingStatus.PUBLISHED) spph.sourcepackagerelease.source_package_recipe_build = sprb recipe_link_matches = soupmatchers.HTMLContains( soupmatchers.Tag( 'link to build', 'a', attrs={'href': canonical_url(sprb)}, text='Built'), soupmatchers.Tag( 'recipe name', 'a', attrs={'href': canonical_url(recipe)}, text=recipe.name), soupmatchers.Tag( 'requester', 'a', attrs={ 'href': canonical_url(requester)}, text=requester.displayname)) browser = self.getViewBrowser(spph, '+listing-archive-extra') self.assertThat(browser.contents, recipe_link_matches)
def assertWebhookDeliveries(self, snapbuild, expected_store_upload_statuses): hook = snapbuild.snap.webhooks.one() deliveries = list(hook.deliveries) deliveries.reverse() expected_payloads = [{ "snap_build": Equals(canonical_url(snapbuild, force_local_path=True)), "action": Equals("status-changed"), "snap": Equals(canonical_url(snapbuild.snap, force_local_path=True)), "build_request": Is(None), "status": Equals("Successfully built"), "store_upload_status": Equals(expected), } for expected in expected_store_upload_statuses] matchers = [ MatchesStructure(event_type=Equals("snap:build:0.1"), payload=MatchesDict(expected_payload)) for expected_payload in expected_payloads ] self.assertThat(deliveries, MatchesListwise(matchers)) with dbuser(config.IWebhookDeliveryJobSource.dbuser): for delivery in deliveries: self.assertEqual( "<WebhookDeliveryJob for webhook %d on %r>" % (hook.id, hook.target), repr(delivery))
def setUp(self): super(TestBugTrackerBreadcrumbs, self).setUp() self.bug_tracker_set = getUtility(IBugTrackerSet) self.bug_tracker_set_url = canonical_url(self.bug_tracker_set, rootsite='bugs') self.bug_tracker = self.factory.makeBugTracker() self.bug_tracker_url = canonical_url(self.bug_tracker, rootsite='bugs')
def test_scheduleStoreUpload_triggers_webhooks(self): # Scheduling a store upload triggers webhooks on the corresponding # snap. self.setUpStoreUpload() self.build.updateStatus(BuildStatus.FULLYBUILT) self.factory.makeSnapFile( snapbuild=self.build, libraryfile=self.factory.makeLibraryFileAlias(db_only=True)) hook = self.factory.makeWebhook(target=self.build.snap, event_types=["snap:build:0.1"]) self.build.scheduleStoreUpload() expected_payload = { "snap_build": Equals(canonical_url(self.build, force_local_path=True)), "action": Equals("status-changed"), "snap": Equals(canonical_url(self.build.snap, force_local_path=True)), "build_request": Is(None), "status": Equals("Successfully built"), "store_upload_status": Equals("Pending"), } delivery = hook.deliveries.one() self.assertThat( delivery, MatchesStructure(event_type=Equals("snap:build:0.1"), payload=MatchesDict(expected_payload))) with dbuser(config.IWebhookDeliveryJobSource.dbuser): self.assertEqual( "<WebhookDeliveryJob for webhook %d on %r>" % (hook.id, hook.target), repr(delivery))
def test_view_with_source_package_recipe(self): # When a SourcePackageRelease is linked to a # SourcePackageRecipeBuild, the view shows which recipe was # responsible for creating the SPR. sprb = self.factory.makeSourcePackageRecipeBuild(archive=self.archive) recipe = sprb.recipe requester = sprb.requester spph = self.publisher.getPubSource( archive=self.archive, status=PackagePublishingStatus.PUBLISHED) spph.sourcepackagerelease.source_package_recipe_build = sprb recipe_link_matches = soupmatchers.HTMLContains( soupmatchers.Tag('link to build', 'a', attrs={'href': canonical_url(sprb)}, text='Built'), soupmatchers.Tag('recipe name', 'a', attrs={'href': canonical_url(recipe)}, text=recipe.name), soupmatchers.Tag('requester', 'a', attrs={'href': canonical_url(requester)}, text=requester.displayname)) browser = self.getViewBrowser(spph, '+listing-archive-extra') self.assertThat(browser.contents, recipe_link_matches)
def test_view_data_model(self): # Test that the json request cache contains the view data model. pillarperson = self.getPillarPerson() view = create_initialized_view(pillarperson, '+index') bugtask = list(view.bugtasks)[0] bug = bugtask.bug cache = IJSONRequestCache(view.request) request = get_current_web_service_request() self.assertEqual({ 'self_link': absoluteURL(pillarperson.person, request), 'displayname': pillarperson.person.displayname }, cache.objects.get('grantee')) self.assertEqual({ 'self_link': absoluteURL(pillarperson.pillar, request), }, cache.objects.get('pillar')) self.assertEqual({ 'bug_id': bug.id, 'bug_summary': bug.title, 'bug_importance': bugtask.importance.title.lower(), 'information_type': bug.information_type.title, 'web_link': canonical_url( bugtask, path_only_if_possible=True), 'self_link': absoluteURL(bug, request), }, cache.objects.get('bugs')[0]) if self.pillar_type == 'product': branch = list(view.branches)[0] self.assertEqual({ 'branch_id': branch.id, 'branch_name': branch.unique_name, 'information_type': branch.information_type.title, 'web_link': canonical_url(branch, path_only_if_possible=True), 'self_link': absoluteURL(branch, request), }, cache.objects.get('branches')[0])
def test_updateStatus_triggers_webhooks(self): # Updating the status of a SnapBuild triggers webhooks on the # corresponding Snap. hook = self.factory.makeWebhook(target=self.build.snap, event_types=["snap:build:0.1"]) self.build.updateStatus(BuildStatus.FULLYBUILT) expected_payload = { "snap_build": Equals(canonical_url(self.build, force_local_path=True)), "action": Equals("status-changed"), "snap": Equals(canonical_url(self.build.snap, force_local_path=True)), "build_request": Is(None), "status": Equals("Successfully built"), "store_upload_status": Equals("Unscheduled"), } delivery = hook.deliveries.one() self.assertThat( delivery, MatchesStructure(event_type=Equals("snap:build:0.1"), payload=MatchesDict(expected_payload))) with dbuser(config.IWebhookDeliveryJobSource.dbuser): self.assertEqual( "<WebhookDeliveryJob for webhook %d on %r>" % (hook.id, hook.target), repr(delivery))
def _getTemplateParams(self, email, recipient): """See `BaseMailer`.""" params = super(TeamMembershipMailer, self)._getTemplateParams(email, recipient) params["recipient"] = recipient.displayname reason, _ = self._recipients.getReason(email) if reason.recipient_class is not None: params["recipient_class"] = reason.recipient_class params["member"] = self.member.unique_displayname params["membership_invitations_url"] = "%s/+invitation/%s" % ( canonical_url(self.member), self.team.name) params["team"] = self.team.unique_displayname params["team_url"] = canonical_url(self.team) if self.membership is not None: params["membership_url"] = canonical_url(self.membership) if reason.recipient_class == "bulk" and self.reviewer == self.member: params["reviewer"] = "the user" elif self.reviewer is not None: params["reviewer"] = self.reviewer.unique_displayname if self.team.mailing_list is not None: template = get_email_template("team-list-subscribe-block.txt", app="registry") editemails_url = urlappend( canonical_url(getUtility(ILaunchpadRoot)), "~/+editmailinglists") list_instructions = template % {"editemails_url": editemails_url} else: list_instructions = "" params["list_instructions"] = list_instructions params.update(self.extra_params) return params
def test_view_with_deleted_source_package_recipe(self): # If a SourcePackageRelease is linked to a deleted recipe, the text # 'deleted recipe' is displayed, rather than a link. sprb = self.factory.makeSourcePackageRecipeBuild( archive=self.archive) recipe = sprb.recipe requester = sprb.requester spph = self.publisher.getPubSource( archive=self.archive, status=PackagePublishingStatus.PUBLISHED) spph.sourcepackagerelease.source_package_recipe_build = sprb with person_logged_in(recipe.owner): recipe.destroySelf() recipe_link_matches = soupmatchers.HTMLContains( soupmatchers.Tag( 'link to build', 'a', attrs={'href': canonical_url(sprb)}, text='Built'), soupmatchers.Tag( 'requester', 'a', attrs={ 'href': canonical_url(requester)}, text=requester.displayname)) browser = self.getViewBrowser(spph, '+listing-archive-extra') self.assertThat(browser.contents, recipe_link_matches) self.assertIn('deleted recipe', browser.contents)
def notify_message_held(message_approval, event): """Send a notification of a message hold to all team administrators.""" message_details = getAdapter(message_approval, IHeldMessageDetails) team = message_approval.mailing_list.team from_address = format_address(team.displayname, config.canonical.noreply_from_address) subject = ('New mailing list message requiring approval for %s' % team.displayname) template = get_email_template('new-held-message.txt', app='registry') # Most of the replacements are the same for everyone. replacements = { 'subject': message_details.subject, 'author_name': message_details.author.displayname, 'author_url': canonical_url(message_details.author), 'date': message_details.date, 'message_id': message_details.message_id, 'review_url': '%s/+mailinglist-moderate' % canonical_url(team), 'team': team.displayname, } # Don't wrap the paragraph with the url. def wrap_function(paragraph): return (paragraph.startswith('http:') or paragraph.startswith('https:')) # Send one message to every team administrator. person_set = getUtility(IPersonSet) for address in team.getTeamAdminsEmailAddresses(): user = person_set.getByEmail(address) replacements['user'] = user.displayname body = MailWrapper(72).format(template % replacements, force_wrap=True, wrap_func=wrap_function) simple_sendmail(from_address, address, subject, body)
def test_team_admin_subscription(self): # Make a team subscription where the user is an admin, and see what # we record. user = self.factory.makePerson() target = self.factory.makeProduct() request = LaunchpadTestRequest() team = self.factory.makeTeam() with person_logged_in(team.teamowner): team.addMember(user, team.teamowner, status=TeamMembershipStatus.ADMIN) sub = target.addBugSubscription(team, team.teamowner) expose_user_subscriptions_to_js(user, [sub], request) info = IJSONRequestCache(request).objects['subscription_info'] self.assertEqual(len(info), 1) # One target. target_info = info[0] self.assertEqual(target_info['target_title'], target.title) self.assertEqual( target_info['target_url'], canonical_url( target, rootsite='mainsite')) self.assertEqual(len(target_info['filters']), 1) # One filter. filter_info = target_info['filters'][0] self.assertEqual(filter_info['filter'], sub.bug_filters[0]) self.assertTrue(filter_info['subscriber_is_team']) self.assertTrue(filter_info['user_is_team_admin']) self.assertTrue(filter_info['can_mute']) self.assertFalse(filter_info['is_muted']) self.assertEqual(filter_info['subscriber_title'], team.title) self.assertEqual( filter_info['subscriber_link'], absoluteURL(team, IWebServiceClientRequest(request))) self.assertEqual( filter_info['subscriber_url'], canonical_url(team, rootsite='mainsite'))
def test_sharing_menu(self): url = canonical_url(self.pillar) sharing_url = canonical_url(self.pillar, view_name='+sharing') browser = setupBrowserForUser(user=self.driver) browser.open(url) soup = BeautifulSoup(browser.contents) sharing_menu = soup.find('a', {'href': sharing_url}) self.assertIsNotNone(sharing_menu)
def setUp(self): super(TestBugTrackerBreadcrumbs, self).setUp() self.bug_tracker_set = getUtility(IBugTrackerSet) self.bug_tracker_set_url = canonical_url( self.bug_tracker_set, rootsite='bugs') self.bug_tracker = self.factory.makeBugTracker() self.bug_tracker_url = canonical_url( self.bug_tracker, rootsite='bugs')
def setUp(self): super(TestHasSpecificationsBreadcrumbOnBlueprintsFacet, self).setUp() self.person = self.factory.makePerson() self.person_specs_url = canonical_url(self.person, rootsite='blueprints') self.product = self.factory.makeProduct(name='crumb-tester', displayname="Crumb Tester") self.product_specs_url = canonical_url(self.product, rootsite='blueprints')
def test_excessive_comments_redirect_to_download(self): """View for excessive comments redirects to download page.""" comment = make_bug_comment(self.factory, body='x ' * 5001) view_url = canonical_url(comment) download_url = canonical_url(comment, view_name='+download') browser = self.getUserBrowser(view_url) self.assertNotEqual(view_url, browser.url) self.assertEqual(download_url, browser.url) self.assertEqual('x ' * 5001, browser.contents)
def notify_new_ppa_subscription(subscription, event): """Notification that a new PPA subscription can be activated.""" non_active_subscribers = subscription.getNonActiveSubscribers() archive = subscription.archive # We don't send notification emails for some PPAs, particularly those that # are purchased via the Software Centre, so that its users do not have to # learn about Launchpad. if archive.suppress_subscription_notifications: return registrant_name = subscription.registrant.displayname ppa_displayname = archive.displayname ppa_reference = "ppa:%s/%s" % ( archive.owner.name, archive.name) ppa_description = archive.description subject = 'PPA access granted for ' + ppa_displayname template = get_email_template('ppa-subscription-new.txt', app='soyuz') for person, preferred_email in non_active_subscribers: to_address = [preferred_email.email] root = getUtility(ILaunchpadRoot) recipient_subscriptions_url = "%s~/+archivesubscriptions" % ( canonical_url(root)) description_blurb = '.' if ppa_description is not None and ppa_description != '': description_blurb = ( ' and has the following description:\n\n%s' % ppa_description) replacements = { 'recipient_name': person.displayname, 'registrant_name': registrant_name, 'registrant_profile_url': canonical_url(subscription.registrant), 'ppa_displayname': ppa_displayname, 'ppa_reference': ppa_reference, 'ppa_description_blurb': description_blurb, 'recipient_subscriptions_url': recipient_subscriptions_url, } body = MailWrapper(72).format(template % replacements, force_wrap=True) from_address = format_address( registrant_name, config.canonical.noreply_from_address) headers = { 'Sender': config.canonical.bounce_address, } # If the registrant has a preferred email, then use it for the # Reply-To. if subscription.registrant.preferredemail: headers['Reply-To'] = format_address( registrant_name, subscription.registrant.preferredemail.email) simple_sendmail(from_address, to_address, subject, body, headers)
def setUp(self): super(TestHasSpecificationsBreadcrumbOnBlueprintsVHost, self).setUp() self.person = self.factory.makePerson() self.person_specs_url = canonical_url( self.person, rootsite='blueprints') self.product = self.factory.makeProduct( name='crumb-tester', displayname="Crumb Tester") self.product_specs_url = canonical_url( self.product, rootsite='blueprints')
def test_view_navigation_links(self): # Check the navigation links get get to the change owner page. owner = self.factory.makePerson() team = self.factory.makeTeam(owner=owner) edit_url = canonical_url(team, view_name='+edit') reassign_url = canonical_url(team, view_name='+reassign') browser = setupBrowserForUser(owner) browser.open(edit_url) browser.getLink('Change owner').click() self.assertEqual(reassign_url, browser.url)
def test_package_bugtask(self): target = self.package_bugtask.target distro_url = canonical_url(target.distribution) distroseries_url = canonical_url(target.distroseries) package_url = canonical_url(target) package_bugs_url = canonical_url(target, rootsite='bugs') self.assertBreadcrumbUrls( [distro_url, distroseries_url, package_url, package_bugs_url, self.package_bugtask_url], self.package_bugtask)
def setup(request, data): owner = factory.makePerson() with person_logged_in(owner): product = factory.makeProduct(name="my-test-project", owner=owner) product_series = factory.makeProductSeries(name="new-series", product=product) data['product'] = product data['series_uri'] = canonical_url(product_series, path_only_if_possible=True) data['milestone_form_uri'] = (canonical_url(product_series) + '/+addmilestone/++form++') login_as_person(owner)
def setup(request, data): owner = factory.makePerson() with person_logged_in(owner): product = factory.makeProduct(name="my-test-project", owner=owner) product_series = factory.makeProductSeries( name="new-series", product=product) data['product'] = product data['series_uri'] = canonical_url( product_series, path_only_if_possible=True) data['milestone_form_uri'] = ( canonical_url(product_series) + '/+addmilestone/++form++') login_as_person(owner)
def setUp(self): super(TestQuestionTargetProjectAndPersonBreadcrumbOnAnswersVHost, self).setUp() self.person = self.factory.makePerson() self.person_questions_url = canonical_url( self.person, rootsite='answers') self.product = self.factory.makeProduct() self.product_questions_url = canonical_url( self.product, rootsite='answers') self.project = self.factory.makeProject() self.project_questions_url = canonical_url( self.project, rootsite='answers')
def test_delete_sprint_owner(self): # A sprint can be deleted by its owner, even if it has attendees and # specifications. self.useFixture(FakeLogger()) sprint = self.makePopulatedSprint() sprint_url = canonical_url(sprint) owner_url = canonical_url(sprint.owner) browser = self.getViewBrowser(sprint, user=sprint.owner) browser.getLink("Delete sprint").click() browser.getControl("Delete sprint").click() self.assertEqual(owner_url, browser.url) self.assertRaises(NotFound, browser.open, sprint_url)
def setUp(self): super(TestQuestionTargetProjectAndPersonBreadcrumbOnAnswersFacet, self).setUp() self.person = self.factory.makePerson() self.person_questions_url = canonical_url( self.person, rootsite='answers') self.product = self.factory.makeProduct() self.product_questions_url = canonical_url( self.product, rootsite='answers') self.project = self.factory.makeProject() self.project_questions_url = canonical_url( self.project, rootsite='answers')
def setUp(self): super(TestExtraFacetBreadcrumbsOnHierarchyView, self).setUp() login('*****@*****.**') self.product = self.factory.makeProduct(name='crumb-tester') self.product_url = canonical_url(self.product) self.product_bugs_url = canonical_url(self.product, rootsite='bugs') product_bug = self.factory.makeBug(target=self.product) self.product_bugtask = product_bug.default_bugtask self.product_bugtask_url = canonical_url(self.product_bugtask) self.source_package = self.factory.makeSourcePackage() self.package_bugtask = self.factory.makeBugTask( target=self.source_package) self.package_bugtask_url = canonical_url(self.package_bugtask)
def setUp(self): super(TestExtraVHostBreadcrumbsOnHierarchyView, self).setUp() login('*****@*****.**') self.product = self.factory.makeProduct(name='crumb-tester') self.product_url = canonical_url(self.product) self.product_bugs_url = canonical_url(self.product, rootsite='bugs') product_bug = self.factory.makeBug(target=self.product) self.product_bugtask = product_bug.default_bugtask self.product_bugtask_url = canonical_url(self.product_bugtask) self.source_package = self.factory.makeSourcePackage() self.package_bugtask = self.factory.makeBugTask( target=self.source_package) self.package_bugtask_url = canonical_url(self.package_bugtask)
def getBody(self): """See QuestionNotification.""" return get_email_template( 'question-linked-bug-status-updated.txt') % { 'bugtask_target_name': self.bugtask.target.displayname, 'question_id': self.question.id, 'question_title': self.question.title, 'question_url': canonical_url(self.question), 'bugtask_url': canonical_url(self.bugtask), 'bug_id': self.bugtask.bug.id, 'bugtask_title': self.bugtask.bug.title, 'old_status': self.old_bugtask.status.title, 'new_status': self.bugtask.status.title}
def test_notification_shown_if_marking_private_and_not_subscribed(self): # If a user who is not subscribed to a bug marks that bug as # private, the user will be subscribed to the bug. This allows # them to un-mark the bug if they choose to, rather than being # blocked from doing so. view = self.createInitializedSecrecyView() bug = view.context.bug task = removeSecurityProxy(bug).default_bugtask self.assertEqual(1, len(view.request.response.notifications)) notification = view.request.response.notifications[0].message mute_url = canonical_url(task, view_name='+mute') subscribe_url = canonical_url(task, view_name='+subscribe') self.assertIn(mute_url, notification) self.assertIn(subscribe_url, notification)
def test_traversal_to_nonexistent_bugtask(self): # Test that a traversing to a non-existent bugtask redirects to the # bug's default bugtask. bug = self.factory.makeBug() bugtask = self.factory.makeBugTask(bug=bug) bugtask_url = canonical_url(bugtask, rootsite='bugs') login_person(bugtask.owner) bugtask.delete() obj, view, request = test_traverse(bugtask_url) view() naked_view = removeSecurityProxy(view) self.assertEqual(301, request.response.getStatus()) self.assertEqual(naked_view.target, canonical_url(bug.default_bugtask, rootsite='bugs'))
def expose_user_subscriptions_to_js(user, subscriptions, request): """Make the user's subscriptions available to JavaScript.""" api_request = IWebServiceClientRequest(request) info = {} if user is None: administered_teams = [] else: administered_teams = user.administrated_teams for subscription in subscriptions: target = subscription.target record = info.get(target) if record is None: record = dict(target_title=target.title, target_url=canonical_url( target, rootsite='mainsite'), filters=[]) info[target] = record subscriber = subscription.subscriber for filter in subscription.bug_filters: is_team = subscriber.is_team user_is_team_admin = ( is_team and subscriber in administered_teams) team_has_contact_address = ( is_team and subscriber.preferredemail is not None) mailing_list = subscriber.mailing_list user_is_on_team_mailing_list = ( team_has_contact_address and mailing_list is not None and mailing_list.is_usable and mailing_list.getSubscription(subscriber) is not None) record['filters'].append(dict( filter=filter, subscriber_link=absoluteURL(subscriber, api_request), subscriber_url=canonical_url( subscriber, rootsite='mainsite'), target_bugs_url=canonical_url( target, rootsite='bugs'), subscriber_title=subscriber.title, subscriber_is_team=is_team, user_is_team_admin=user_is_team_admin, team_has_contact_address=team_has_contact_address, user_is_on_team_mailing_list=user_is_on_team_mailing_list, can_mute=filter.isMuteAllowed(user), is_muted=filter.muted(user) is not None, target_title=target.title)) info = info.values() info.sort(key=itemgetter('target_url')) IJSONRequestCache(request).objects['subscription_info'] = info
def test_constructs_correct_urls(self): # The view classes can override constructTemplateURL with # optimized versions. These can produce either an absolute URL # that exactly matches the template's canonical_url, or a # relative one starting from the series' canonical_url. template = self._makeTemplate() view = self._makeView(template) series_url = canonical_url( self._getSeries(template), rootsite='translations') constructed_url = view.constructTemplateURL(template) self.assertIn( canonical_url(template), (constructed_url, '/'.join([series_url, constructed_url])))
def test_constructs_correct_urls(self): # The view classes can override constructTemplateURL with # optimized versions. These can produce either an absolute URL # that exactly matches the template's canonical_url, or a # relative one starting from the series' canonical_url. template = self._makeTemplate() view = self._makeView(template) series_url = canonical_url(self._getSeries(template), rootsite='translations') constructed_url = view.constructTemplateURL(template) self.assertIn( canonical_url(template), (constructed_url, '/'.join([series_url, constructed_url])))
def test_traversal_to_nonexistent_bugtask(self): # Test that a traversing to a non-existent bugtask redirects to the # bug's default bugtask. bug = self.factory.makeBug() bugtask = self.factory.makeBugTask(bug=bug) bugtask_url = canonical_url(bugtask, rootsite='bugs') login_person(bugtask.owner) bugtask.delete() obj, view, request = test_traverse(bugtask_url) view() naked_view = removeSecurityProxy(view) self.assertEqual(301, request.response.getStatus()) self.assertEqual( naked_view.target, canonical_url(bug.default_bugtask, rootsite='bugs'))
def notify_bugtask_edited(modified_bugtask, event): """Notify CC'd subscribers of this bug that something has changed on this task. modified_bugtask must be an IBugTask. event must be an IObjectModifiedEvent. """ bugtask_delta = event.object.getDelta(event.object_before_modification) bug_delta = BugDelta( bug=event.object.bug, bugurl=canonical_url(event.object.bug), bugtask_deltas=bugtask_delta, user=IPerson(event.user)) event_creator = IPerson(event.user) previous_subscribers = event.object_before_modification.bug_subscribers current_subscribers = event.object.bug_subscribers prev_subs_set = set(previous_subscribers) cur_subs_set = set(current_subscribers) new_subs = cur_subs_set.difference(prev_subs_set) add_bug_change_notifications( bug_delta, old_bugtask=event.object_before_modification, new_subscribers=new_subs) send_bug_details_to_new_bug_subscribers( event.object.bug, previous_subscribers, current_subscribers, event_creator=event_creator)
def test_items_for_field_vocabulary(self): widget = self._getWidget(attribute_type="reference") vocab = getVocabularyRegistry().get(None, 'BuildableDistroSeries') value_fn = lambda item: canonical_url( item.value, force_local_path=True) expected_items = self._makeExpectedItems(vocab, value_fn=value_fn) self.assertEqual(simplejson.dumps(expected_items), widget.json_items)
def send(self): """Send a message to the user about the product's licence.""" if not self.needs_notification(self.product): # The project has a common licence. return False maintainer = self.product.owner if maintainer.is_team: user_address = maintainer.getTeamAdminsEmailAddresses() else: user_address = format_address_for_person(maintainer) from_address = format_address( "Launchpad", config.canonical.noreply_from_address) commercial_address = format_address( 'Commercial', '*****@*****.**') substitutions = dict( user_displayname=maintainer.displayname, user_name=maintainer.name, product_name=self.product.name, product_url=canonical_url(self.product), commercial_use_expiration=self.getCommercialUseMessage(), ) # Email the user about licence policy. subject = ( "Licence information for %(product_name)s " "in Launchpad" % substitutions) template = get_email_template( self.getTemplateName(), app='registry') message = template % substitutions simple_sendmail( from_address, user_address, subject, message, headers={'Reply-To': commercial_address}) # Inform that Launchpad recognized the licence change. self._addLicenseChangeToReviewWhiteboard() return True
def test_bug_page_user_with_aag_proprietary_product(self): # A user with an artifact grant for a bug targeted to a private # product can view the bug page. with person_logged_in(self.user): url = canonical_url(self.bug) # No exception is raised when the page is rendered. self.getUserBrowser(url, user=self.user)
def test_bugtarget(self): project = self.factory.makeProduct(name='fnord') project_bugs_url = canonical_url(project, rootsite='bugs') crumbs = self.getBreadcrumbsForObject(project, rootsite='bugs') last_crumb = crumbs[-1] self.assertEquals(project_bugs_url, last_crumb.url) self.assertEquals("Bugs", last_crumb.text)
def setUp(self): super(TestMilestoneBreadcrumb, self).setUp() self.project = self.factory.makeProduct() self.series = self.factory.makeProductSeries(product=self.project) self.milestone = self.factory.makeMilestone( productseries=self.series, name="1.1") self.milestone_url = canonical_url(self.milestone)
def test_personal_archive_subscription(self): subscription_url = canonical_url(self.personal_archive_subscription) crumbs = self.getBreadcrumbsForObject( self.personal_archive_subscription) self.assertEquals(subscription_url, crumbs[-1].url) self.assertEquals("Access to %s" % self.ppa.displayname, crumbs[-1].text)
def setUp(self): super(TestDistroseriesBreadcrumb, self).setUp() self.distribution = self.factory.makeDistribution( name='youbuntu', displayname='Youbuntu') self.distroseries = self.factory.makeDistroSeries( name='groovy', version="1.06", distribution=self.distribution) self.distroseries_url = canonical_url(self.distroseries)
def _assert_getBugData(self, related_bug=None): # The getBugData method works as expected. owner = self.factory.makePerson() product = self.factory.makeProduct() bug = self.factory.makeBug( target=product, owner=owner, status=BugTaskStatus.INPROGRESS, title='title', description='description', information_type=InformationType.PRIVATESECURITY) with person_logged_in(owner): bug_data = getUtility(IMaloneApplication).getBugData( owner, bug.id, related_bug) expected_bug_data = { 'id': bug.id, 'information_type': 'Private Security', 'is_private': True, 'importance': 'Undecided', 'importance_class': 'importanceUNDECIDED', 'status': 'In Progress', 'status_class': 'statusINPROGRESS', 'bug_summary': 'title', 'description': 'description', 'bug_url': canonical_url(bug.default_bugtask), 'different_pillars': related_bug is not None } self.assertEqual([expected_bug_data], bug_data)
def test_non_owner_unauthorised(self): # Only team owners can reassign team ownership. team = self.factory.makeTeam() any_person = self.factory.makePerson() reassign_url = canonical_url(team, view_name='+reassign') browser = setupBrowserForUser(any_person) self.assertRaises(Unauthorized, browser.open, reassign_url)
def composeWebhookPayload(branch, old_revid, new_revid): return { "bzr_branch": canonical_url(branch, force_local_path=True), "bzr_branch_path": branch.shortened_path, "old": {"revision_id": old_revid}, "new": {"revision_id": new_revid}, }
def createDelta(self, user=None, **kwargs): if user is None: user = self.user return BugDelta(bug=self.bug, bugurl=canonical_url(self.bug), user=user, **kwargs)
def test_distroarchseriesbinarypackagerelease(self): pmount_hoary_i386 = self.hoary_i386.getBinaryPackage("pmount") pmount_release = pmount_hoary_i386['0.1-1'] pmount_release_url = canonical_url(pmount_release) crumbs = self.getBreadcrumbsForObject(pmount_release) self.assertEquals(crumbs[-1].url, pmount_release_url) self.assertEquals(crumbs[-1].text, "0.1-1")
def submitForcedEmptySuggestion(self): """Submit an empty suggestion for `self.current_translation`.""" empty_translation = u'' msgset_id = 'msgset_' + str(self.current_translation.potmsgset.id) msgset_id_lang = msgset_id + '_' + self.pofile.language.code widget_id_base = msgset_id_lang + '_translation_0_' form = { 'lock_timestamp': datetime.now(pytz.utc).isoformat(), 'alt': None, msgset_id: None, widget_id_base + 'radiobutton': widget_id_base + 'new', widget_id_base + 'new': empty_translation, 'submit_translations': 'Save & Continue', msgset_id_lang + '_needsreview': 'force_suggestion', } url = canonical_url(self.current_translation) + '/+translate' view = create_view(self.current_translation, '+translate', form=form, server_url=url) view.request.method = 'POST' view.initialize()