def testNotActiveOrgAdmin(self): # seed non-active org admin for organization one profile_utils.seedNDBProfile( self.program.key(), admin_for=[self.organization_one.key], status=ndb_profile_model.Status.BANNED) # not active org admin not returned org_admins = profile_logic.getOrgAdmins(self.organization_one.key) self.assertListEqual(org_admins, []) # keys_only set to True does not return any keys org_admin_keys = profile_logic.getOrgAdmins( self.organization_one.key, keys_only=True) self.assertListEqual(org_admin_keys, [])
def testManyOrgAdmins(self): """Tests that all org admins are returned if many exist.""" # seed a few org admins for organization one org_admin_keys = set() for _ in range(5): org_admin_keys.add(profile_utils.seedNDBProfile( self.program.key(), admin_for=[self.organization_one.key]).key) # all org admins should be returned results = profile_logic.getOrgAdmins(self.organization_one.key) self.assertSetEqual( set([result.key for result in results]), org_admin_keys), # all org admins keys should be returned if keys_only set results = profile_logic.getOrgAdmins( self.organization_one.key, keys_only=True) self.assertSetEqual(set(results), org_admin_keys),
def testOneOrgAdmin(self): """Tests that a list of size one is returned if one org admin exists.""" # seed a new org admin for organization one org_admin = profile_utils.seedNDBProfile( self.program.key(), admin_for=[self.organization_one.key]) # the org admin should be returned results = profile_logic.getOrgAdmins(self.organization_one.key) self.assertSetEqual( set(result.key for result in results), set([org_admin.key])) # keys_only set to True should return only the key org_admin_keys = profile_logic.getOrgAdmins( self.organization_one.key, keys_only=True) self.assertSetEqual(set(org_admin_keys), set([org_admin.key])) # there is still no org admin for organization two org_admins = profile_logic.getOrgAdmins(self.organization_two.key) self.assertListEqual(org_admins, [])
def process(org_key): """Processes a single organization. Organization status is updated to ACCEPTED or REJECTED if the current status has been set to PRE_ACCEPTED or PRE_REJECTED, respectively, by program administrators. Args: org_key: Organization key. """ context = mapreduce_context.get() program_key = db.Key(context.mapreduce_spec.mapper.params['program_key']) if program_key.kind() == 'GSoCProgram': url_names = soc_urls.UrlNames elif program_key.kind() == 'GCIProgram': url_names = ci_urls.UrlNames else: raise ValueError('Invalid program type %s' % program_key.kind()) program = db.get(program_key) site = site_logic.singleton() org_key = ndb.Key.from_old_key(org_key) org_admins = profile_logic.getOrgAdmins(org_key) # We are "prefetching" the ProgramMessages entity here instead of fetching # it where it is required i.e. when the message templates are required # to build the email message body. We do this because we perform the # operation of fetching the ProgramMessages entity if it exists or create # it if it doesn't in a Appengine regular "db" transation whereas rest # of the updating of organization entities happen within an ndb transaction # because Organization model is an ndb model and such cross API nested # transactions are incompatible in Appengine. program_messages = program.getProgramMessages() @ndb.transactional def updateOrganizationStatus(): """Transactionally updates organization status.""" # only organizations defined for the specified program should be processed organization = org_key.get() if organization.program.to_old_key() == program_key: if organization.status == org_model.Status.PRE_ACCEPTED: org_logic.setStatus( organization, program, site, program_messages, org_model.Status.ACCEPTED, links.ABSOLUTE_LINKER, url_names, org_admins=org_admins) elif organization.status == org_model.Status.PRE_REJECTED: org_logic.setStatus( organization, program, site, program_messages, org_model.Status.REJECTED, links.ABSOLUTE_LINKER, url_names, org_admins=org_admins) updateOrganizationStatus()
def testExtraAttrs(self): # seed male org admin for organization one org_admin = profile_utils.seedNDBProfile( self.program.key(), admin_for=[self.organization_one.key], gender=ndb_profile_model.Gender.MALE) # seed female org admin for organization one profile_utils.seedNDBProfile( self.program.key(), admin_for=[self.organization_one.key], gender=ndb_profile_model.Gender.FEMALE) # retrieve only org admins with extra attrs extra_attrs = { ndb_profile_model.Profile.gender: [ndb_profile_model.Gender.MALE] } results = profile_logic.getOrgAdmins(self.organization_one.key, extra_attrs=extra_attrs) # only the male org admin should be returned self.assertSetEqual( set([result.key for result in results]), set([org_admin.key]))
def getOrgAdmins(org_key, keys_only=False, extra_attrs=None): """Returns organization administrators for the specified organization. Additional constraints on administrators may be specified by passing a custom extra_attrs dictionary. Each element of the dictionary maps a property with a requested value. The value must be a sequence (list or tuple). Please note that this function executes a non-ancestor query, so it cannot be safely used within transactions. Args: org_key: organization key keys_only: If true, return only keys instead of complete entities extra_args: a dictionary containing additional constraints on organization administrators to retrieve Returns: list of profiles entities or keys of organization administrators """ return profile_logic.getOrgAdmins( org_key, keys_only=keys_only, extra_attrs=extra_attrs, models=types.SOC_MODELS)
def refreshConversationParticipants(conversation): """Creates/deletes GCIConversationUser entities depending on the converation's criteria. The conversation's owner is always included in the conversation. If the conversation's recipients_type is 'User', this function will not do anything because it is expected that the GCIConversationUser will be managed elsewhere. Args: conversation: Key (ndb) of GCIConversation. """ conv = conversation.get() def addProfile(profile): addUserToConversation( conversation=conversation, user=profile.key.parent()) def deleteConvUserIfDoesntBelong(conv_user): if not doesConversationUserBelong(conversation_user=conv_user.key): conv_user.key.delete() # Remove any users included who no longer fit the criteria if conv.recipients_type != conversation_model.USER: conv_user_query = queryConversationUserForConversation(conversation) map(deleteConvUserIfDoesntBelong, conv_user_query) # Make sure users who fit the criteria are included if conv.recipients_type == conversation_model.PROGRAM: if conv.include_admins: query = profile_model.Profile.query( profile_model.Profile.program == conv.program, profile_model.Profile.is_admin == True) map(addProfile, query) if conv.include_mentors: query = profile_logic.queryAllMentorsForProgram(conv.program.to_old_key()) map(addProfile, query) if conv.include_students: query = profile_model.Profile.query( profile_model.Profile.program == conv.program, profile_model.Profile.is_student == True) map(addProfile, query) if conv.include_winners: query = profile_model.Profile.query( profile_model.Profile.program == conv.program, profile_model.Profile.student_data.is_winner == True) map(addProfile, query) elif conv.recipients_type == conversation_model.ORGANIZATION: if conv.include_admins: org_admins = profile_logic.getOrgAdmins(conv.organization) map(addProfile, org_admins) if conv.include_mentors: query = profile_model.Profile.query( profile_model.Profile.mentor_for == conv.organization, profile_model.Profile.status == profile_model.Status.ACTIVE) map(addProfile, query) if conv.include_winners: query = profile_model.Profile.query( profile_model.Profile.student_data.winner_for == conv.organization, profile_model.Profile.status == profile_model.Status.ACTIVE) map(addProfile, query) # Make sure conversation's creator is included if conv.creator is not None: addUserToConversation(conversation=conversation, user=conv.creator)
def testNoOrgAdmin(self): """Tests that the empty list is returned if no org admin exists.""" org_admins = profile_logic.getOrgAdmins(self.organization_one.key) self.assertListEqual(org_admins, [])
def refreshConversationParticipants(conversation): """Creates/deletes GCIConversationUser entities depending on the converation's criteria. The conversation's owner is always included in the conversation. If the conversation's recipients_type is 'User', this function will not do anything because it is expected that the GCIConversationUser will be managed elsewhere. Args: conversation: Key (ndb) of GCIConversation. """ conv = conversation.get() def addProfile(profile): addUserToConversation(conversation=conversation, user=profile.key.parent()) def deleteConvUserIfDoesntBelong(conv_user): if not doesConversationUserBelong(conversation_user=conv_user.key): conv_user.key.delete() # Remove any users included who no longer fit the criteria if conv.recipients_type != conversation_model.USER: conv_user_query = queryConversationUserForConversation(conversation) map(deleteConvUserIfDoesntBelong, conv_user_query) # Make sure users who fit the criteria are included if conv.recipients_type == conversation_model.PROGRAM: if conv.include_admins: query = profile_model.Profile.query( profile_model.Profile.program == conv.program, profile_model.Profile.is_admin == True) map(addProfile, query) if conv.include_mentors: query = profile_logic.queryAllMentorsForProgram( conv.program.to_old_key()) map(addProfile, query) if conv.include_students: query = profile_model.Profile.query( profile_model.Profile.program == conv.program, profile_model.Profile.is_student == True) map(addProfile, query) if conv.include_winners: query = profile_model.Profile.query( profile_model.Profile.program == conv.program, profile_model.Profile.student_data.is_winner == True) map(addProfile, query) elif conv.recipients_type == conversation_model.ORGANIZATION: if conv.include_admins: org_admins = profile_logic.getOrgAdmins(conv.organization) map(addProfile, org_admins) if conv.include_mentors: query = profile_model.Profile.query( profile_model.Profile.mentor_for == conv.organization, profile_model.Profile.status == profile_model.Status.ACTIVE) map(addProfile, query) if conv.include_winners: query = profile_model.Profile.query( profile_model.Profile.student_data.winner_for == conv.organization, profile_model.Profile.status == profile_model.Status.ACTIVE) map(addProfile, query) # Make sure conversation's creator is included if conv.creator is not None: addUserToConversation(conversation=conversation, user=conv.creator)