def initialize(self): # Insert close team membership policy data into the json cache. # This data is used for the maintainer and driver pickers. super(PillarViewMixin, self).initialize() cache = IJSONRequestCache(self.request) policy_items = [(item.name, item) for item in EXCLUSIVE_TEAM_POLICY] team_membership_policy_data = vocabulary_to_choice_edit_items( SimpleVocabulary.fromItems(policy_items), value_fn=lambda item: item.name) cache.objects['team_membership_policy_data'] = ( team_membership_policy_data)
def initialize(self): super(BugSubscriptionListView, self).initialize() subscriptions = list( get_structural_subscriptions_for_bug(self.context.bug, self.user)) expose_structural_subscription_data_to_js(self.context, self.request, self.user, subscriptions) subscriptions_info = PersonSubscriptions(self.user, self.context.bug) subdata, references = subscriptions_info.getDataForClient() cache = IJSONRequestCache(self.request).objects cache.update(references) cache['bug_subscription_info'] = subdata cache['bug_is_private'] = self.context.bug.private
def subscribe(self, event): cache = IJSONRequestCache(self.request) if "longpoll" not in cache.objects: cache.objects["longpoll"] = { "uri": config.txlongpoll.uri, "key": generate_subscribe_key(), "subscriptions": [], } session = getUtility(IMessageSession) subscribe_queue = session.getConsumer(self.subscribe_key) producer = session.getProducer(event.event_key) producer.associateConsumer(subscribe_queue) cache.objects["longpoll"]["subscriptions"].append(event.event_key)
def initialize(self): super(BugSubscriptionListView, self).initialize() subscriptions = list(get_structural_subscriptions_for_bug( self.context.bug, self.user)) expose_structural_subscription_data_to_js( self.context, self.request, self.user, subscriptions) subscriptions_info = PersonSubscriptions( self.user, self.context.bug) subdata, references = subscriptions_info.getDataForClient() cache = IJSONRequestCache(self.request).objects cache.update(references) cache['bug_subscription_info'] = subdata cache['bug_is_private'] = self.context.bug.private
def initialize(self): self.pillar = self.context.pillar self.person = self.context.person self.label = "Information shared with %s" % self.person.displayname self.page_title = "%s" % self.person.displayname self.sharing_service = getUtility(IService, 'sharing') self._loadSharedArtifacts() cache = IJSONRequestCache(self.request) request = get_current_web_service_request() branch_data = self._build_branch_template_data(self.branches, request) gitrepository_data = self._build_gitrepository_template_data( self.gitrepositories, request) bug_data = self._build_bug_template_data(self.bugtasks, request) spec_data = self._build_specification_template_data( self.specifications, request) grantee_data = { 'displayname': self.person.displayname, 'self_link': absoluteURL(self.person, request) } pillar_data = {'self_link': absoluteURL(self.pillar, request)} cache.objects['grantee'] = grantee_data cache.objects['pillar'] = pillar_data cache.objects['bugs'] = bug_data cache.objects['branches'] = branch_data cache.objects['gitrepositories'] = gitrepository_data cache.objects['specifications'] = spec_data
def cache_me_link_when_principal_identified(event): """Insert the current user into the JSON request cache. This ensures that the Javascript variable LP.links['me'] will be set. """ # XML-RPC requests and other non-browser requests don't have a # IJSONRequestCache, and this code shouldn't run from them. try: cache = IJSONRequestCache(event.request) except TypeError: cache = None if cache is not None: person = IPerson(event.principal, None) if person is not None: cache.links['me'] = person
def test_longpoll_uri_config(self): # The JSON cache contains config.txlongpoll.uri. self.pushConfig("txlongpoll", uri="/+longpoll/") request = LaunchpadTestRequest() cache = IJSONRequestCache(request) ILongPollSubscriber(request).subscribe(FakeEvent()) self.assertEqual('/+longpoll/', cache.objects["longpoll"]["uri"])
def test_query_count(self): # The function issues a constant number of queries regardless of # team count. login_person(self.user) context = self.factory.makeProduct(owner=self.user) self._setup_teams(self.user) IStore(Person).invalidate() clear_cache() with StormStatementRecorder() as recorder: expose_user_administered_teams_to_js( self.request, self.user, context, absoluteURL=fake_absoluteURL) self.assertThat(recorder, HasQueryCount(Equals(4))) # Create some new public teams owned by the user, and a private # team administered by the user. for i in range(3): self.factory.makeTeam(owner=self.user) pt = self.factory.makeTeam( visibility=PersonVisibility.PRIVATE, members=[self.user]) with person_logged_in(pt.teamowner): pt.addMember( self.user, pt.teamowner, status=TeamMembershipStatus.ADMIN) IStore(Person).invalidate() clear_cache() del IJSONRequestCache(self.request).objects['administratedTeams'] with StormStatementRecorder() as recorder: expose_user_administered_teams_to_js( self.request, self.user, context, absoluteURL=fake_absoluteURL) self.assertThat(recorder, HasQueryCount(Equals(4)))
def test_getCacheJSON_non_resource_object(self): request = LaunchpadTestRequest() view = LaunchpadView(object(), request) IJSONRequestCache(request).objects['my_bool'] = True with person_logged_in(self.factory.makePerson()): self.assertEqual('{"related_features": {}, "my_bool": true}', view.getCacheJSON())
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_getCacheJSON_resource_object(self): request = LaunchpadTestRequest() view = LaunchpadView(object(), request) IJSONRequestCache(request).objects['country'] = self.getCanada() with person_logged_in(self.factory.makePerson()): json_dict = simplejson.loads(view.getCacheJSON())['country'] self.assertIsCanada(json_dict)
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_getCacheJSON_context_overrides_objects(self): request = LaunchpadTestRequest() view = LaunchpadView(self.getCanada(), request) IJSONRequestCache(request).objects['context'] = True with person_logged_in(self.factory.makePerson()): json_dict = simplejson.loads(view.getCacheJSON())['context'] self.assertIsCanada(json_dict)
def test_json_cache_not_populated_on_init(self): # LongPollApplicationRequestSubscriber does not put the name of the # new queue into the JSON cache. request = LaunchpadTestRequest() cache = IJSONRequestCache(request) self.assertThat(cache.objects, Not(Contains("longpoll"))) ILongPollSubscriber(request) self.assertThat(cache.objects, Not(Contains("longpoll")))
def test_getCache_anonymous(self): request = LaunchpadTestRequest() view = LaunchpadView(self.getCanada(), request) self.assertIs(None, view.user) IJSONRequestCache(request).objects['my_bool'] = True json_dict = simplejson.loads(view.getCacheJSON()) self.assertIsCanada(json_dict['context']) self.assertIn('my_bool', json_dict)
def initialize(self): cache = IJSONRequestCache(self.request).objects context_url_data = { 'web_link': canonical_url(self.context, rootsite='mainsite'), 'self_link': absoluteURL(self.context, self.api_request), } cache[self.context.name + '_answer_portlet_url_data'] = (context_url_data)
def initialize(self): """Initialize the view to handle the request.""" LaunchpadView.initialize(self) cache = IJSONRequestCache(self.request).objects self.extractBugSubscriptionDetails(self.user, self.context, cache) cache['bug_is_private'] = self.context.private if self.user: cache['notifications_text'] = self.notifications_text
def test_view_batch_data(self): # Test the expected batching data is in the json request cache. view = create_initialized_view(self.pillar, name='+sharing') cache = IJSONRequestCache(view.request) # Test one expected data value (there are many). next_batch = view.grantees().batch.nextBatch() self.assertContentEqual( next_batch.range_memo, cache.objects.get('next')['memo'])
def getCacheJSON(self): cache = dict(IJSONRequestCache(self.request).objects) if WebLayerAPI(self.context).is_entry: cache['context'] = self.context if self.user is None: cache = obfuscate_structure(cache) return simplejson.dumps( cache, cls=ResourceJSONEncoder, media_type=EntryResource.JSON_TYPE)
def test_information_type(self): # Information type controls are provided when creating a project via a # project group. form = make_product_form(action=1) project = self.factory.makeProject() with person_logged_in(project.owner): view = create_initialized_view(project, '+newproduct', form=form) self.assertIn('information_type_data', IJSONRequestCache(view.request).objects) self.assertIsNot(None, view.view.form_fields.get('information_type'))
def _get_json_cache(self): # Some tests create views without providing any request # object at all; other tests run without the component # infrastructure. try: cache = IJSONRequestCache(self.request).objects except TypeError as error: if error.args[0] == 'Could not adapt': cache = None return cache
def test_view_data_model(self): # The view's json request cache contains the expected data. view = create_initialized_view(self.project_group, '+index') cache = IJSONRequestCache(view.request) policy_items = [(item.name, item) for item in EXCLUSIVE_TEAM_POLICY] team_membership_policy_data = vocabulary_to_choice_edit_items( SimpleVocabulary.fromItems(policy_items), value_fn=lambda item: item.name) self.assertContentEqual(team_membership_policy_data, cache.objects['team_membership_policy_data'])
def expose_user_administered_teams_to_js(request, user, context, absoluteURL=absoluteURL): """Make the list of teams the user administers available to JavaScript.""" # XXX: Robert Collins workaround multiple calls making this cause # timeouts: see bug 788510. objects = IJSONRequestCache(request).objects if 'administratedTeams' in objects: return info = [] api_request = IWebServiceClientRequest(request) is_distro = IDistribution.providedBy(context) if is_distro: # If the context is a distro AND a bug supervisor is set then we only # allow subscriptions from members of the bug supervisor team. bug_supervisor = context.bug_supervisor else: bug_supervisor = None if user is not None: administrated_teams = set(user.administrated_teams) if administrated_teams: # Get this only if we need to. membership = set(user.teams_participated_in) # Only consider teams the user is both in and administers: # If the user is not a member of the team itself, then # skip it, because structural subscriptions and their # filters can only be edited by the subscriber. # This can happen if the user is an owner but not a member. administers_and_in = membership.intersection(administrated_teams) list( getUtility(IPersonSet).getPrecachedPersonsFromIDs( [team.id for team in administers_and_in], need_preferred_email=True)) # If the requester is the user, they're at least an admin in # all of these teams. Precache launchpad.(Limited)View so we # can see the necessary attributes. current_user = IPerson(get_current_principal(), None) if current_user is not None and user == current_user: for perm in ('launchpad.View', 'launchpad.LimitedView'): precache_permission_for_objects(None, perm, administers_and_in) for team in sorted(administers_and_in, key=attrgetter('name')): if (bug_supervisor is not None and not team.inTeam(bug_supervisor)): continue info.append({ 'has_preferredemail': team.preferredemail is not None, 'link': absoluteURL(team, api_request), 'title': team.unique_displayname, 'url': canonical_url(team), }) objects['administratedTeams'] = info
def test_view_invisible_information_types(self): # Test the expected invisible information type data is in the # json request cache. with person_logged_in(self.pillar.owner): getUtility(IService, 'sharing').deletePillarGrantee( self.pillar, self.pillar.owner, self.pillar.owner) view = create_initialized_view(self.pillar, name='+sharing') cache = IJSONRequestCache(view.request) self.assertContentEqual( ['Private Security', 'Private'], cache.objects.get('invisible_information_types'))
def initialize(self): self.pillar = self.context.pillar self.person = self.context.person self.label = "Information shared with %s" % self.person.displayname self.page_title = "%s" % self.person.displayname self.sharing_service = getUtility(IService, 'sharing') self._loadSharedArtifacts() cache = IJSONRequestCache(self.request) request = get_current_web_service_request() branch_data = self._build_branch_template_data(self.branches, request) bug_data = self._build_bug_template_data(self.bugtasks, request) spec_data = self._build_specification_template_data( self.specifications, request) grantee_data = { 'displayname': self.person.displayname, 'self_link': absoluteURL(self.person, request) } pillar_data = { 'self_link': absoluteURL(self.pillar, request) } cache.objects['grantee'] = grantee_data cache.objects['pillar'] = pillar_data cache.objects['bugs'] = bug_data cache.objects['branches'] = branch_data cache.objects['specifications'] = spec_data
def initialize(self): super(DistroSeriesInitializeView, self).initialize() cache = IJSONRequestCache(self.request).objects distribution = self.context.distribution is_first_derivation = not distribution.has_published_sources cache['is_first_derivation'] = is_first_derivation if (not is_first_derivation and self.context.previous_series is not None): cache['previous_series'] = seriesToVocab( self.context.previous_series) previous_parents = self.context.previous_series.getParentSeries() cache['previous_parents'] = [ seriesToVocab(series) for series in previous_parents]
def test_proprietary_excluded_for_normal_projects(self): # The Proprietary information type isn't in the JSON request cache for # normal projects without proprietary bugs configured. self.view.initialize() cache = IJSONRequestCache(self.view.request) expected = [ InformationType.PUBLIC.name, InformationType.PUBLICSECURITY.name, InformationType.PRIVATESECURITY.name, InformationType.USERDATA.name] self.assertContentEqual(expected, [ type['value'] for type in cache.objects['information_type_data'].values()])
def test_getCache_redirected_view(self): # A redirection view may be provided with a target view instance from # which json cache data is obtained. class TestView(LaunchpadView): pass request = LaunchpadTestRequest() test_view = TestView(self.getCanada(), request) view = RedirectionView(None, request, cache_view=test_view) IJSONRequestCache(request).objects['my_bool'] = True json_dict = simplejson.loads(view.getCacheJSON()) self.assertIsCanada(json_dict['context']) self.assertIn('my_bool', json_dict)
def test_muted_team_member_subscription(self): # Show that a muted team subscription is correctly represented. user = self.factory.makePerson() target = self.factory.makeProduct() request = LaunchpadTestRequest() team = self.factory.makeTeam(members=[user]) with person_logged_in(team.teamowner): sub = target.addBugSubscription(team, team.teamowner) sub.bug_filters.one().mute(user) expose_user_subscriptions_to_js(user, [sub], request) info = IJSONRequestCache(request).objects['subscription_info'] filter_info = info[0]['filters'][0] self.assertTrue(filter_info['can_mute']) self.assertTrue(filter_info['is_muted'])
def initialize(self): super(PillarSharingView, self).initialize() cache = IJSONRequestCache(self.request) cache.objects['information_types'] = self.information_types cache.objects['sharing_permissions'] = self.sharing_permissions cache.objects['bug_sharing_policies'] = self.bug_sharing_policies cache.objects['branch_sharing_policies'] = ( self.branch_sharing_policies) cache.objects['specification_sharing_policies'] = ( self.specification_sharing_policies) cache.objects['has_edit_permission'] = check_permission( "launchpad.Edit", self.context) batch_navigator = self.grantees() cache.objects['grantee_data'] = ( self._getSharingService().jsonGranteeData(batch_navigator.batch)) cache.objects.update( get_batch_properties_for_json_cache(self, batch_navigator)) grant_counts = (self._getSharingService().getAccessPolicyGrantCounts( self.context)) cache.objects['invisible_information_types'] = [ count_info[0].title for count_info in grant_counts if count_info[1] == 0 ]
def test_messages_are_in_json(self): team = self.factory.makeTeam() self.factory.makeMailingList(team, team.teamowner) messages = '''[{ "headers": { "To": "*****@*****.**", "From": "*****@*****.**", "Subject": "foobar"}, "message_id": "foo"}]''' with self._override_messages(TeamMailingListArchiveView, messages): view = create_view(team, name='+mailing-list-archive') messages = IJSONRequestCache(view.request).objects['mail'] self.assertEqual(1, len(messages)) self.assertEqual('foo', messages[0]['message_id'])
def test_jsoncache_contents(self): product = self.factory.makeProduct() question = self.factory.makeQuestion(target=product) login_person(product.owner) # It works even for anonymous users, so no log-in is needed. view = create_initialized_view( question.target, '+portlet-answercontacts', rootsite='answers') cache = IJSONRequestCache(view.request).objects context_url_data = { 'web_link': canonical_url(product, rootsite='mainsite'), 'self_link': absoluteURL(product, IWebServiceClientRequest(view.request)), } self.assertEqual(cache[product.name + '_answer_portlet_url_data'], context_url_data)
def initialize(self): super(PillarSharingView, self).initialize() cache = IJSONRequestCache(self.request) cache.objects['information_types'] = self.information_types cache.objects['sharing_permissions'] = self.sharing_permissions cache.objects['bug_sharing_policies'] = self.bug_sharing_policies cache.objects['branch_sharing_policies'] = ( self.branch_sharing_policies) cache.objects['specification_sharing_policies'] = ( self.specification_sharing_policies) cache.objects['has_edit_permission'] = check_permission( "launchpad.Edit", self.context) view_names = set(reg.name for reg in iter_view_registrations(self.__class__)) if len(view_names) != 1: raise AssertionError("Ambiguous view name.") cache.objects['view_name'] = view_names.pop() batch_navigator = self.grantees() cache.objects['grantee_data'] = ( self._getSharingService().jsonGranteeData(batch_navigator.batch)) grant_counts = ( self._getSharingService().getAccessPolicyGrantCounts(self.context)) cache.objects['invisible_information_types'] = [ count_info[0].title for count_info in grant_counts if count_info[1] == 0] def _getBatchInfo(batch): if batch is None: return None return {'memo': batch.range_memo, 'start': batch.startNumber() - 1} next_batch = batch_navigator.batch.nextBatch() cache.objects['next'] = _getBatchInfo(next_batch) prev_batch = batch_navigator.batch.prevBatch() cache.objects['prev'] = _getBatchInfo(prev_batch) cache.objects['total'] = batch_navigator.batch.total() cache.objects['forwards'] = batch_navigator.batch.range_forwards last_batch = batch_navigator.batch.lastBatch() cache.objects['last_start'] = last_batch.startNumber() - 1 cache.objects.update(_getBatchInfo(batch_navigator.batch))