def testUpdateConversations(self):
    """Tests that the updateConversations task correctly adds a user to all
    conversations they should be in but aren't, and removes them from
    conversations they shouldn't be in.
    """

    def run_update_task(user_key, program_key):
      """Runs the task and test that it runs correctly.

      Args:
        user_key: Key (ndb) of User.
        program_key: Key (ndb) of GCIProgram.
      """
      update_conversations.spawnUpdateConversationsTask(user_key, program_key)
      self.assertTasksInQueue(n=1, url=TASK_URL)

      for task in self.get_tasks():
        if task['url'] == TASK_URL:
          params = task['params']
          self.assertIn('user_key', params)
          self.assertEqual(params['user_key'], user_key.urlsafe())
          self.assertIn('program_key', params)
          self.assertEqual(params['program_key'], program_key.urlsafe())

      # Test task
      post_data = {
          'user_key': user_key.urlsafe(),
          'program_key': program_key.urlsafe(),
          }
      response = self.post(TASK_URL, post_data)
      self.assertEqual(response.status_code, httplib.OK)

      self.clear_task_queue()

    # Create a couple dummy organizations
    org_keys = map(
        lambda org: ndb.Key.from_old_key(org.key()),
        list(self.conv_utils.program_helper.createNewOrg() for x in range(2)))

    # Create various dummy users
    user_admin_key = self.conv_utils.createUser(
        return_key=True, roles=[conversation_utils.ADMIN],
        admin_organizations=[org_keys[0]])
    user_mentor_key = self.conv_utils.createUser(
        return_key=True, roles=[conversation_utils.MENTOR],
        mentor_organizations=[org_keys[0], org_keys[1]])
    user_mentor_student_key = self.conv_utils.createUser(
        return_key=True,
        roles=[conversation_utils.MENTOR, conversation_utils.STUDENT])
    user_winner_key = self.conv_utils.createUser(
        return_key=True, winning_organization=org_keys[1],
        roles=[conversation_utils.WINNER, conversation_utils.STUDENT])
    
    # Conversation for program admins and mentors
    conv_a = self.conv_utils.createConversation(subject='')
    conv_a.recipients_type = conversation_model.PROGRAM
    conv_a.include_admins = True
    conv_a.include_mentors = True
    conv_a.put()

    # Conversation for first org's admins
    conv_b = self.conv_utils.createConversation(subject='')
    conv_b.recipients_type = conversation_model.ORGANIZATION
    conv_b.organization = org_keys[0]
    conv_b.include_admins = True
    conv_b.put()

    # Conversation for second org's mentors
    conv_c = self.conv_utils.createConversation(subject='')
    conv_c.recipients_type = conversation_model.ORGANIZATION
    conv_c.organization = org_keys[1]
    conv_c.include_mentors = True
    conv_c.put()

    # Conversation for program mentors and students
    conv_d = self.conv_utils.createConversation(subject='')
    conv_d.recipients_type = conversation_model.PROGRAM
    conv_d.include_mentors = True
    conv_d.include_students = True
    conv_d.put()

    # Conversation for program students, created by a non-student
    conv_e = self.conv_utils.createConversation(subject='')
    conv_e.creator = user_admin_key
    conv_e.recipients_type = conversation_model.PROGRAM
    conv_e.include_students = True
    conv_e.put()
    self.conv_utils.addUser(conversation=conv_e.key, user=conv_e.creator)

    # Conversation for basically nobody, in which the participants should not
    # be changed after the conversation's creation, and all users are added.
    # This is to ensure that users won't be removed if the conversation's
    # auto_update_users property is False.
    conv_f = self.conv_utils.createConversation(subject='')
    conv_f.recipients_type = conversation_model.PROGRAM
    conv_f.auto_update_users = False
    conv_f.put()
    self.conv_utils.addUser(conversation=conv_f.key, user=user_admin_key)
    self.conv_utils.addUser(conversation=conv_f.key, user=user_mentor_key)
    self.conv_utils.addUser(
        conversation=conv_f.key, user=user_mentor_student_key)
    self.conv_utils.addUser(conversation=conv_f.key, user=user_winner_key)

    # Conversation for that all users fit the criteria to participate in, but
    # should not be added after the converation's creation.
    conv_g = self.conv_utils.createConversation(subject='')
    conv_g.recipients_type = conversation_model.PROGRAM
    conv_g.include_students = True
    conv_g.include_mentors = True
    conv_g.include_admins = True
    conv_g.auto_update_users = False
    conv_g.put()

    # Conversation for program winners, created by a non-winner
    conv_h = self.conv_utils.createConversation(subject='')
    conv_h.recipients_type = conversation_model.PROGRAM
    conv_h.include_winners = True
    conv_h.put()

    # Conversation for winners of first organization
    conv_i = self.conv_utils.createConversation(subject='')
    conv_i.recipients_type = conversation_model.ORGANIZATION
    conv_i.organization = org_keys[0]
    conv_i.include_winners = True
    conv_i.put()

    # Conversation for winners of second organization
    conv_j = self.conv_utils.createConversation(subject='')
    conv_j.recipients_type = conversation_model.ORGANIZATION
    conv_j.organization = org_keys[1]
    conv_j.include_winners = True
    conv_j.put()

    # Refresh each user's conversations
    run_update_task(user_admin_key, self.program_key)
    run_update_task(user_mentor_key, self.program_key)
    run_update_task(user_mentor_student_key, self.program_key)
    run_update_task(user_winner_key, self.program_key)

    # Test that admin user is in the correct conversations
    expected_keys = set([conv_a.key, conv_b.key, conv_e.key, conv_f.key])
    actual_keys = set(map(
        lambda conv_user: conv_user.conversation,
        gciconversation_logic.queryForProgramAndUser(
            program=self.program_key, user=user_admin_key)))
    self.assertEqual(expected_keys, actual_keys)

    # Test that mentor user is in the correct conversations
    expected_keys = set([conv_a.key, conv_c.key, conv_d.key, conv_f.key])
    actual_keys = set(map(
        lambda conv_user: conv_user.conversation,
        gciconversation_logic.queryForProgramAndUser(
            program=self.program_key, user=user_mentor_key)))
    self.assertEqual(expected_keys, actual_keys)

    # Test that mentor/student user is in the correct conversations
    expected_keys = set([conv_a.key, conv_d.key, conv_e.key, conv_f.key])
    actual_keys = set(map(
        lambda conv_user: conv_user.conversation,
        gciconversation_logic.queryForProgramAndUser(
            program=self.program_key, user=user_mentor_student_key)))
    self.assertEqual(expected_keys, actual_keys)

    # Test that winner user is in the correct conversations
    expected_keys = set(
        [conv_d.key, conv_e.key, conv_f.key, conv_h.key, conv_j.key])
    actual_keys = set(map(
        lambda conv_user: conv_user.conversation,
        gciconversation_logic.queryForProgramAndUser(
            program=self.program_key, user=user_winner_key)))
    self.assertEqual(expected_keys, actual_keys)

    # Add all three users to all conversations
    self.conv_utils.addUser(conversation=conv_b.key, user=user_mentor_key)
    self.conv_utils.addUser(
        conversation=conv_b.key, user=user_mentor_student_key)
    self.conv_utils.addUser(conversation=conv_c.key, user=user_admin_key)
    self.conv_utils.addUser(
        conversation=conv_c.key, user=user_mentor_student_key)
    self.conv_utils.addUser(conversation=conv_d.key, user=user_admin_key)
    self.conv_utils.addUser(conversation=conv_e.key, user=user_mentor_key)
    self.conv_utils.addUser(
        conversation=conv_h.key, user=user_mentor_student_key)
    self.conv_utils.addUser(conversation=conv_h.key, user=user_mentor_key)
    self.conv_utils.addUser(conversation=conv_h.key, user=user_admin_key)
    self.conv_utils.addUser(
        conversation=conv_i.key, user=user_mentor_student_key)
    self.conv_utils.addUser(conversation=conv_i.key, user=user_mentor_key)
    self.conv_utils.addUser(conversation=conv_i.key, user=user_admin_key)
    self.conv_utils.addUser(
        conversation=conv_j.key, user=user_mentor_student_key)
    self.conv_utils.addUser(conversation=conv_j.key, user=user_mentor_key)
    self.conv_utils.addUser(conversation=conv_j.key, user=user_admin_key)
    self.conv_utils.addUser(conversation=conv_a.key, user=user_winner_key)
    self.conv_utils.addUser(conversation=conv_b.key, user=user_winner_key)
    self.conv_utils.addUser(conversation=conv_c.key, user=user_winner_key)
    self.conv_utils.addUser(conversation=conv_i.key, user=user_winner_key)

    # Test that admin user is in all conversations except for G
    expected_keys = set([
        conv_a.key, conv_b.key, conv_c.key, conv_d.key, conv_e.key, conv_f.key,
        conv_h.key, conv_i.key, conv_j.key])
    actual_keys = set(map(
        lambda conv_user: conv_user.conversation,
        gciconversation_logic.queryForProgramAndUser(
            program=self.program_key, user=user_admin_key)))

    self.assertEqual(expected_keys, actual_keys)

    # Test that mentor user is in all conversations except for G
    expected_keys = set([
        conv_a.key, conv_b.key, conv_c.key, conv_d.key, conv_e.key, conv_f.key,
        conv_h.key, conv_i.key, conv_j.key])
    actual_keys = set(map(
        lambda conv_user: conv_user.conversation,
        gciconversation_logic.queryForProgramAndUser(
            program=self.program_key, user=user_mentor_key)))
    self.assertEqual(expected_keys, actual_keys)

    # Test that mentor/student user is in all conversations except for G
    expected_keys = set([
        conv_a.key, conv_b.key, conv_c.key, conv_d.key, conv_e.key, conv_f.key,
        conv_h.key, conv_i.key, conv_j.key])
    actual_keys = set(map(
        lambda conv_user: conv_user.conversation,
        gciconversation_logic.queryForProgramAndUser(
            program=self.program_key, user=user_mentor_student_key)))
    self.assertEqual(expected_keys, actual_keys)

    # Test that winner user is in all conversations except for G
    expected_keys = set([
        conv_a.key, conv_b.key, conv_c.key, conv_d.key, conv_e.key, conv_f.key,
        conv_h.key, conv_i.key, conv_j.key])
    actual_keys = set(map(
        lambda conv_user: conv_user.conversation,
        gciconversation_logic.queryForProgramAndUser(
            program=self.program_key, user=user_winner_key)))
    self.assertEqual(expected_keys, actual_keys)

    # Refresh each user's conversations. Because we just added all users to
    # all conversations, refreshing each user should actually remove them from
    # conversations they don't belong to.
    run_update_task(user_admin_key, self.program_key)
    run_update_task(user_mentor_key, self.program_key)
    run_update_task(user_mentor_student_key, self.program_key)
    run_update_task(user_winner_key, self.program_key)

    # Test that admin user is in the correct conversations
    expected_keys = set([conv_a.key, conv_b.key, conv_e.key, conv_f.key])
    actual_keys = set(map(
        lambda conv_user: conv_user.conversation,
        gciconversation_logic.queryForProgramAndUser(
            program=self.program_key, user=user_admin_key)))

    self.assertEqual(expected_keys, actual_keys)

    # Test that mentor user is in the correct conversations
    expected_keys = set([conv_a.key, conv_c.key, conv_d.key, conv_f.key])
    actual_keys = set(map(
        lambda conv_user: conv_user.conversation,
        gciconversation_logic.queryForProgramAndUser(
            program=self.program_key, user=user_mentor_key)))
    self.assertEqual(expected_keys, actual_keys)

    # Test that mentor/student user is in the correct conversations
    expected_keys = set([conv_a.key, conv_d.key, conv_e.key, conv_f.key])
    actual_keys = set(map(
        lambda conv_user: conv_user.conversation,
        gciconversation_logic.queryForProgramAndUser(
            program=self.program_key, user=user_mentor_student_key)))
    self.assertEqual(expected_keys, actual_keys)

    # Test that winner user is in the correct conversations
    expected_keys = set(
        [conv_d.key, conv_e.key, conv_f.key, conv_h.key, conv_j.key])
    actual_keys = set(map(
        lambda conv_user: conv_user.conversation,
        gciconversation_logic.queryForProgramAndUser(
            program=self.program_key, user=user_winner_key)))
    self.assertEqual(expected_keys, actual_keys)
Esempio n. 2
0
    def testUpdateConversations(self):
        """Tests that the updateConversations task correctly adds a user to all
    conversations they should be in but aren't, and removes them from
    conversations they shouldn't be in.
    """
        def run_update_task(user_key, program_key):
            """Runs the task and test that it runs correctly.

      Args:
        user_key: Key (ndb) of User.
        program_key: Key (ndb) of GCIProgram.
      """
            update_conversations.spawnUpdateConversationsTask(
                user_key, program_key)
            self.assertTasksInQueue(n=1, url=TASK_URL)

            for task in self.get_tasks():
                if task['url'] == TASK_URL:
                    params = task['params']
                    self.assertIn('user_key', params)
                    self.assertEqual(params['user_key'], user_key.urlsafe())
                    self.assertIn('program_key', params)
                    self.assertEqual(params['program_key'],
                                     program_key.urlsafe())

            # Test task
            post_data = {
                'user_key': user_key.urlsafe(),
                'program_key': program_key.urlsafe(),
            }
            response = self.post(TASK_URL, post_data)
            self.assertEqual(response.status_code, httplib.OK)

            self.clear_task_queue()

        # Create a couple dummy organizations
        org_keys = map(
            lambda org: ndb.Key.from_old_key(org.key()),
            list(self.conv_utils.program_helper.createNewOrg()
                 for x in range(2)))

        # Create various dummy users
        user_admin_key = self.conv_utils.createUser(
            return_key=True,
            roles=[conversation_utils.ADMIN],
            admin_organizations=[org_keys[0]])
        user_mentor_key = self.conv_utils.createUser(
            return_key=True,
            roles=[conversation_utils.MENTOR],
            mentor_organizations=[org_keys[0], org_keys[1]])
        user_mentor_student_key = self.conv_utils.createUser(
            return_key=True,
            roles=[conversation_utils.MENTOR, conversation_utils.STUDENT])
        user_winner_key = self.conv_utils.createUser(
            return_key=True,
            winning_organization=org_keys[1],
            roles=[conversation_utils.WINNER, conversation_utils.STUDENT])

        # Conversation for program admins and mentors
        conv_a = self.conv_utils.createConversation(subject='')
        conv_a.recipients_type = conversation_model.PROGRAM
        conv_a.include_admins = True
        conv_a.include_mentors = True
        conv_a.put()

        # Conversation for first org's admins
        conv_b = self.conv_utils.createConversation(subject='')
        conv_b.recipients_type = conversation_model.ORGANIZATION
        conv_b.organization = org_keys[0]
        conv_b.include_admins = True
        conv_b.put()

        # Conversation for second org's mentors
        conv_c = self.conv_utils.createConversation(subject='')
        conv_c.recipients_type = conversation_model.ORGANIZATION
        conv_c.organization = org_keys[1]
        conv_c.include_mentors = True
        conv_c.put()

        # Conversation for program mentors and students
        conv_d = self.conv_utils.createConversation(subject='')
        conv_d.recipients_type = conversation_model.PROGRAM
        conv_d.include_mentors = True
        conv_d.include_students = True
        conv_d.put()

        # Conversation for program students, created by a non-student
        conv_e = self.conv_utils.createConversation(subject='')
        conv_e.creator = user_admin_key
        conv_e.recipients_type = conversation_model.PROGRAM
        conv_e.include_students = True
        conv_e.put()
        self.conv_utils.addUser(conversation=conv_e.key, user=conv_e.creator)

        # Conversation for basically nobody, in which the participants should not
        # be changed after the conversation's creation, and all users are added.
        # This is to ensure that users won't be removed if the conversation's
        # auto_update_users property is False.
        conv_f = self.conv_utils.createConversation(subject='')
        conv_f.recipients_type = conversation_model.PROGRAM
        conv_f.auto_update_users = False
        conv_f.put()
        self.conv_utils.addUser(conversation=conv_f.key, user=user_admin_key)
        self.conv_utils.addUser(conversation=conv_f.key, user=user_mentor_key)
        self.conv_utils.addUser(conversation=conv_f.key,
                                user=user_mentor_student_key)
        self.conv_utils.addUser(conversation=conv_f.key, user=user_winner_key)

        # Conversation for that all users fit the criteria to participate in, but
        # should not be added after the converation's creation.
        conv_g = self.conv_utils.createConversation(subject='')
        conv_g.recipients_type = conversation_model.PROGRAM
        conv_g.include_students = True
        conv_g.include_mentors = True
        conv_g.include_admins = True
        conv_g.auto_update_users = False
        conv_g.put()

        # Conversation for program winners, created by a non-winner
        conv_h = self.conv_utils.createConversation(subject='')
        conv_h.recipients_type = conversation_model.PROGRAM
        conv_h.include_winners = True
        conv_h.put()

        # Conversation for winners of first organization
        conv_i = self.conv_utils.createConversation(subject='')
        conv_i.recipients_type = conversation_model.ORGANIZATION
        conv_i.organization = org_keys[0]
        conv_i.include_winners = True
        conv_i.put()

        # Conversation for winners of second organization
        conv_j = self.conv_utils.createConversation(subject='')
        conv_j.recipients_type = conversation_model.ORGANIZATION
        conv_j.organization = org_keys[1]
        conv_j.include_winners = True
        conv_j.put()

        # Refresh each user's conversations
        run_update_task(user_admin_key, self.program_key)
        run_update_task(user_mentor_key, self.program_key)
        run_update_task(user_mentor_student_key, self.program_key)
        run_update_task(user_winner_key, self.program_key)

        # Test that admin user is in the correct conversations
        expected_keys = set([conv_a.key, conv_b.key, conv_e.key, conv_f.key])
        actual_keys = set(
            map(
                lambda conv_user: conv_user.conversation,
                gciconversation_logic.queryForProgramAndUser(
                    program=self.program_key, user=user_admin_key)))
        self.assertEqual(expected_keys, actual_keys)

        # Test that mentor user is in the correct conversations
        expected_keys = set([conv_a.key, conv_c.key, conv_d.key, conv_f.key])
        actual_keys = set(
            map(
                lambda conv_user: conv_user.conversation,
                gciconversation_logic.queryForProgramAndUser(
                    program=self.program_key, user=user_mentor_key)))
        self.assertEqual(expected_keys, actual_keys)

        # Test that mentor/student user is in the correct conversations
        expected_keys = set([conv_a.key, conv_d.key, conv_e.key, conv_f.key])
        actual_keys = set(
            map(
                lambda conv_user: conv_user.conversation,
                gciconversation_logic.queryForProgramAndUser(
                    program=self.program_key, user=user_mentor_student_key)))
        self.assertEqual(expected_keys, actual_keys)

        # Test that winner user is in the correct conversations
        expected_keys = set(
            [conv_d.key, conv_e.key, conv_f.key, conv_h.key, conv_j.key])
        actual_keys = set(
            map(
                lambda conv_user: conv_user.conversation,
                gciconversation_logic.queryForProgramAndUser(
                    program=self.program_key, user=user_winner_key)))
        self.assertEqual(expected_keys, actual_keys)

        # Add all three users to all conversations
        self.conv_utils.addUser(conversation=conv_b.key, user=user_mentor_key)
        self.conv_utils.addUser(conversation=conv_b.key,
                                user=user_mentor_student_key)
        self.conv_utils.addUser(conversation=conv_c.key, user=user_admin_key)
        self.conv_utils.addUser(conversation=conv_c.key,
                                user=user_mentor_student_key)
        self.conv_utils.addUser(conversation=conv_d.key, user=user_admin_key)
        self.conv_utils.addUser(conversation=conv_e.key, user=user_mentor_key)
        self.conv_utils.addUser(conversation=conv_h.key,
                                user=user_mentor_student_key)
        self.conv_utils.addUser(conversation=conv_h.key, user=user_mentor_key)
        self.conv_utils.addUser(conversation=conv_h.key, user=user_admin_key)
        self.conv_utils.addUser(conversation=conv_i.key,
                                user=user_mentor_student_key)
        self.conv_utils.addUser(conversation=conv_i.key, user=user_mentor_key)
        self.conv_utils.addUser(conversation=conv_i.key, user=user_admin_key)
        self.conv_utils.addUser(conversation=conv_j.key,
                                user=user_mentor_student_key)
        self.conv_utils.addUser(conversation=conv_j.key, user=user_mentor_key)
        self.conv_utils.addUser(conversation=conv_j.key, user=user_admin_key)
        self.conv_utils.addUser(conversation=conv_a.key, user=user_winner_key)
        self.conv_utils.addUser(conversation=conv_b.key, user=user_winner_key)
        self.conv_utils.addUser(conversation=conv_c.key, user=user_winner_key)
        self.conv_utils.addUser(conversation=conv_i.key, user=user_winner_key)

        # Test that admin user is in all conversations except for G
        expected_keys = set([
            conv_a.key, conv_b.key, conv_c.key, conv_d.key, conv_e.key,
            conv_f.key, conv_h.key, conv_i.key, conv_j.key
        ])
        actual_keys = set(
            map(
                lambda conv_user: conv_user.conversation,
                gciconversation_logic.queryForProgramAndUser(
                    program=self.program_key, user=user_admin_key)))

        self.assertEqual(expected_keys, actual_keys)

        # Test that mentor user is in all conversations except for G
        expected_keys = set([
            conv_a.key, conv_b.key, conv_c.key, conv_d.key, conv_e.key,
            conv_f.key, conv_h.key, conv_i.key, conv_j.key
        ])
        actual_keys = set(
            map(
                lambda conv_user: conv_user.conversation,
                gciconversation_logic.queryForProgramAndUser(
                    program=self.program_key, user=user_mentor_key)))
        self.assertEqual(expected_keys, actual_keys)

        # Test that mentor/student user is in all conversations except for G
        expected_keys = set([
            conv_a.key, conv_b.key, conv_c.key, conv_d.key, conv_e.key,
            conv_f.key, conv_h.key, conv_i.key, conv_j.key
        ])
        actual_keys = set(
            map(
                lambda conv_user: conv_user.conversation,
                gciconversation_logic.queryForProgramAndUser(
                    program=self.program_key, user=user_mentor_student_key)))
        self.assertEqual(expected_keys, actual_keys)

        # Test that winner user is in all conversations except for G
        expected_keys = set([
            conv_a.key, conv_b.key, conv_c.key, conv_d.key, conv_e.key,
            conv_f.key, conv_h.key, conv_i.key, conv_j.key
        ])
        actual_keys = set(
            map(
                lambda conv_user: conv_user.conversation,
                gciconversation_logic.queryForProgramAndUser(
                    program=self.program_key, user=user_winner_key)))
        self.assertEqual(expected_keys, actual_keys)

        # Refresh each user's conversations. Because we just added all users to
        # all conversations, refreshing each user should actually remove them from
        # conversations they don't belong to.
        run_update_task(user_admin_key, self.program_key)
        run_update_task(user_mentor_key, self.program_key)
        run_update_task(user_mentor_student_key, self.program_key)
        run_update_task(user_winner_key, self.program_key)

        # Test that admin user is in the correct conversations
        expected_keys = set([conv_a.key, conv_b.key, conv_e.key, conv_f.key])
        actual_keys = set(
            map(
                lambda conv_user: conv_user.conversation,
                gciconversation_logic.queryForProgramAndUser(
                    program=self.program_key, user=user_admin_key)))

        self.assertEqual(expected_keys, actual_keys)

        # Test that mentor user is in the correct conversations
        expected_keys = set([conv_a.key, conv_c.key, conv_d.key, conv_f.key])
        actual_keys = set(
            map(
                lambda conv_user: conv_user.conversation,
                gciconversation_logic.queryForProgramAndUser(
                    program=self.program_key, user=user_mentor_key)))
        self.assertEqual(expected_keys, actual_keys)

        # Test that mentor/student user is in the correct conversations
        expected_keys = set([conv_a.key, conv_d.key, conv_e.key, conv_f.key])
        actual_keys = set(
            map(
                lambda conv_user: conv_user.conversation,
                gciconversation_logic.queryForProgramAndUser(
                    program=self.program_key, user=user_mentor_student_key)))
        self.assertEqual(expected_keys, actual_keys)

        # Test that winner user is in the correct conversations
        expected_keys = set(
            [conv_d.key, conv_e.key, conv_f.key, conv_h.key, conv_j.key])
        actual_keys = set(
            map(
                lambda conv_user: conv_user.conversation,
                gciconversation_logic.queryForProgramAndUser(
                    program=self.program_key, user=user_winner_key)))
        self.assertEqual(expected_keys, actual_keys)
Esempio n. 3
0
def confirm_delete(profile):
  """Deletes the given profile entity and also the user entity if possible.

  1. Deletes the profile.
  2. Deletes the user entity if no other profiles exist for the user.
  3. Removes the user from task notification subscription lists.
  4. Replaces GCITask created_by, modified_by, student and GCIComment
     created_by properties with dummy "melange_deleted_user" profile or user
     entity.
  5. Replaces GCIMessage author with dummy "melange_deleted_user".
  6. Replaces GCIConversation creator with dummy "melange_deleted_user".
  7. Removes GCIConversationUser entities representing the user's involvement
     in a GCIConversation.

  This method implements a giant XG transaction, but should not take a long
  time because experience has shown that there won't be too much data to
  modify or delete.

  Args:
    profile: GCIProfile entity of the user.
  """
  profile_key = profile.key()

  program_ndb_key = ndb.Key.from_old_key(profile.program.key())
  user_ndb_key = ndb.Key.from_old_key(profile.parent_key())

  # Cannot delete the user entity if the user has other profiles, so set it
  # to False in that case.
  user_delete = not (profile_logic.hasOtherGCIProfiles(profile) or
                     profile_logic.hasOtherGCIProfiles(profile))

  task_sub_q = task_model.GCITask.all().filter('subscribers', profile)
  task_sub_remove_list = []
  for task in task_sub_q.run():
    task_sub_remove_list.append(task)

  tasks_created_by_q = task_model.GCITask.all().filter('created_by', profile)
  task_created_list = []
  for task in tasks_created_by_q.run():
    task_created_list.append(task)

  tasks_modified_by_q = task_model.GCITask.all().filter('modified_by', profile)
  task_modified_list = []
  for task in tasks_modified_by_q.run():
    task_modified_list.append(task)

  tasks_student_q = task_model.GCITask.all().filter('student', profile)
  task_student_list = []
  for task in tasks_student_q.run():
    task_student_list.append(task)

  comments_created_by_q = comment_model.GCIComment.all().filter(
      'created_by', profile.user)
  comments_created_by_list = []
  for comment in comments_created_by_q.run():
    comments_created_by_list.append(comment)

  conversations = conversation_logic.queryForProgramAndCreator(
      program_ndb_key, user_ndb_key)

  messages = message_logic.queryForUser(user_ndb_key)

  conversation_users = conversation_logic.queryForProgramAndUser(
      program_ndb_key, user_ndb_key)

  dummy_user = user_logic.getOrCreateDummyMelangeDeletedUser()
  dummy_profile = profile_logic.getOrCreateDummyMelangeDeletedProfile(
      profile.program)

  dummy_user_ndb_key = ndb.Key.from_old_key(dummy_user.key())

  options = db.create_transaction_options(xg=True)

  def delete_account_txn():
    entities_to_save = set([])
    entities_to_del = set([])

    # The batch size for query.run() is 20, in most of the cases we have
    # seen so far the user had a few tasks with subscriptions, created_by,
    # modified_by etc., so this should still be single datastore hits per
    # loop. Also, by running the query outside the transaction we may run
    # into situations of user subscribing to the task or creating or modifying
    # tasks or performing another activity after this batch fetch. However,
    # the chances of that happening is very low and can be traded-off for
    # the bigger problem of half run transactions.

    for conversation in conversations:
      conversation.creator = dummy_user_ndb_key
      conversation.put()

    for message in messages:
      message.author = dummy_user_ndb_key
      message.put()

    for conversation_user in conversation_users:
      conversation_user.key.delete()

    for task in task_sub_remove_list:
      task.subscribers.remove(profile_key)
      entities_to_save.add(task)

    for task in task_created_list:
      task.created_by = dummy_profile
      entities_to_save.add(task)

    for task in task_modified_list:
      task.modified_by = dummy_profile
      entities_to_save.add(task)

    for task in task_student_list:
      task.student = dummy_profile
      entities_to_save.add(task)

    for comment in comments_created_by_list:
      comment.created_by = dummy_user
      entities_to_save.add(comment)

    if profile.student_info:
      entities_to_del.add(profile.student_info)
      entities_to_del.add(profile)

    if user_delete:
      entities_to_del.add(profile.parent())

    db.put(entities_to_save)
    db.delete(entities_to_del)

  db.run_in_transaction_options(options, delete_account_txn)
Esempio n. 4
0
 def _getQuery(self):
     """See ConversationList._getQuery for full specification."""
     return gciconversation_logic.queryForProgramAndUser(
         ndb.Key.from_old_key(self.data.program.key()),
         ndb.Key.from_old_key(self.data.user.key()))
Esempio n. 5
0
def confirm_delete(profile):
    """Deletes the given profile entity and also the user entity if possible.

  1. Deletes the profile.
  2. Deletes the user entity if no other profiles exist for the user.
  3. Removes the user from task notification subscription lists.
  4. Replaces GCITask created_by, modified_by, student and GCIComment
     created_by properties with dummy "melange_deleted_user" profile or user
     entity.
  5. Replaces GCIMessage author with dummy "melange_deleted_user".
  6. Replaces GCIConversation creator with dummy "melange_deleted_user".
  7. Removes GCIConversationUser entities representing the user's involvement
     in a GCIConversation.

  This method implements a giant XG transaction, but should not take a long
  time because experience has shown that there won't be too much data to
  modify or delete.

  Args:
    profile: GCIProfile entity of the user.
  """
    profile_key = profile.key()

    program_ndb_key = ndb.Key.from_old_key(profile.program.key())
    user_ndb_key = ndb.Key.from_old_key(profile.parent_key())

    # Cannot delete the user entity if the user has other profiles, so set it
    # to False in that case.
    user_delete = not (profile_logic.hasOtherGCIProfiles(profile)
                       or profile_logic.hasOtherGCIProfiles(profile))

    task_sub_q = task_model.GCITask.all().filter('subscribers', profile)
    task_sub_remove_list = []
    for task in task_sub_q.run():
        task_sub_remove_list.append(task)

    tasks_created_by_q = task_model.GCITask.all().filter('created_by', profile)
    task_created_list = []
    for task in tasks_created_by_q.run():
        task_created_list.append(task)

    tasks_modified_by_q = task_model.GCITask.all().filter(
        'modified_by', profile)
    task_modified_list = []
    for task in tasks_modified_by_q.run():
        task_modified_list.append(task)

    tasks_student_q = task_model.GCITask.all().filter('student', profile)
    task_student_list = []
    for task in tasks_student_q.run():
        task_student_list.append(task)

    comments_created_by_q = comment_model.GCIComment.all().filter(
        'created_by', profile.user)
    comments_created_by_list = []
    for comment in comments_created_by_q.run():
        comments_created_by_list.append(comment)

    conversations = conversation_logic.queryForProgramAndCreator(
        program_ndb_key, user_ndb_key)

    messages = message_logic.queryForUser(user_ndb_key)

    conversation_users = conversation_logic.queryForProgramAndUser(
        program_ndb_key, user_ndb_key)

    dummy_user = user_logic.getOrCreateDummyMelangeDeletedUser()
    dummy_profile = profile_logic.getOrCreateDummyMelangeDeletedProfile(
        profile.program)

    dummy_user_ndb_key = ndb.Key.from_old_key(dummy_user.key())

    options = db.create_transaction_options(xg=True)

    def delete_account_txn():
        entities_to_save = set([])
        entities_to_del = set([])

        # The batch size for query.run() is 20, in most of the cases we have
        # seen so far the user had a few tasks with subscriptions, created_by,
        # modified_by etc., so this should still be single datastore hits per
        # loop. Also, by running the query outside the transaction we may run
        # into situations of user subscribing to the task or creating or modifying
        # tasks or performing another activity after this batch fetch. However,
        # the chances of that happening is very low and can be traded-off for
        # the bigger problem of half run transactions.

        for conversation in conversations:
            conversation.creator = dummy_user_ndb_key
            conversation.put()

        for message in messages:
            message.author = dummy_user_ndb_key
            message.put()

        for conversation_user in conversation_users:
            conversation_user.key.delete()

        for task in task_sub_remove_list:
            task.subscribers.remove(profile_key)
            entities_to_save.add(task)

        for task in task_created_list:
            task.created_by = dummy_profile
            entities_to_save.add(task)

        for task in task_modified_list:
            task.modified_by = dummy_profile
            entities_to_save.add(task)

        for task in task_student_list:
            task.student = dummy_profile
            entities_to_save.add(task)

        for comment in comments_created_by_list:
            comment.created_by = dummy_user
            entities_to_save.add(comment)

        if profile.student_info:
            entities_to_del.add(profile.student_info)
            entities_to_del.add(profile)

        if user_delete:
            entities_to_del.add(profile.parent())

        db.put(entities_to_save)
        db.delete(entities_to_del)

    db.run_in_transaction_options(options, delete_account_txn)
Esempio n. 6
0
 def _getQuery(self):
   """See ConversationList._getQuery for full specification."""
   return gciconversation_logic.queryForProgramAndUser(
       ndb.Key.from_old_key(self.data.program.key()),
       ndb.Key.from_old_key(self.data.user.key()))