Beispiel #1
0
    def testForBooleanType(self):
        """Tests that object is initialized correctly for values of bool type."""
        richBool = rich_bool.RichBool(True)
        self.assertEqual(richBool.value, True)

        richBool = rich_bool.RichBool(False)
        self.assertEqual(richBool.value, False)
Beispiel #2
0
def canResignAsMentorForOrg(profile, org_key):
  """Tells whether the specified profile can resign from their mentor role
  for the specified organization.

  A mentor may be removed from the list of mentors of an organization, if
  he or she does not have any tasks, which have not been closed, assigned.

  Please note that this function executes a non-ancestor query, so it cannot
  be safely used within transactions.

  Args:
    profile: profile entity.
    org_key: organization key.

  Returns:
    RichBool whose value is set to True, if the mentor is allowed to resign.
    Otherwise, RichBool whose value is set to False and extra part is a string
    that represents the reason why the user is not allowed to resign.
  """
  if org_key not in profile.mentor_for:
    return rich_bool.RichBool(False, extra=NOT_MENTOR_FOR_ORG)

  # TODO(daniel): if all work is already completed/reviewed,
  # the mentor can always resign?

  # the mentor cannot have any non-closed tasks assigned
  query = task_model.GCITask.all()
  query.filter('mentors', profile.key())
  query.filter('status !=', 'Closed')
  if query.get():
    return rich_bool.RichBool(False, extra=MENTOR_HAS_TASK_ASSIGNED)
  else:
    return rich_bool.TRUE
Beispiel #3
0
def createProfile(
    user_key, program_key, profile_properties, models=types.MELANGE_MODELS):
  """Creates a new profile entity based on the supplied properties.

  Args:
    user_key: User key for the profile to register.
    program: Program key.
    profile_properties: A dict mapping profile properties to their values.
    models: instance of types.Models that represent appropriate models.

  Returns:
    RichBool whose value is set to True if profile has been successfully
    created. In that case, extra part points to the newly created profile
    entity. Otherwise, RichBool whose value is set to False and extra part is
    a string that represents the reason why the action could not be completed.
  """
  # check if a profile entity for the user and the program already exists.
  profile_key = getProfileKey(
      program_model.getSponsorId(program_key),
      program_model.getProgramId(program_key),
      user_key.id(), models=models)

  if profile_key.get():
    return rich_bool.RichBool(False, PROFILE_EXISTS)
  else:
    try:
      program_key = ndb.Key.from_old_key(program_key)
      profile = models.ndb_profile_model(
          key=profile_key, program=program_key, **profile_properties)
      profile.put()
      return rich_bool.RichBool(True, profile)
    except datastore_errors.BadValueError as e:
      return rich_bool.RichBool(False, str(e))
Beispiel #4
0
    def testCompareWithOtherTypes(self):
        """Tests that comparison works correctly with a few other types."""
        richBool = rich_bool.RichBool(True)

        # because 1 == True
        self.assertEqual(1, richBool)

        # because True != object()
        self.assertNotEqual(richBool, object())

        # because True < []
        self.assertGreater([], richBool)

        # because 0 < True
        self.assertLess(0, True)

        richBool = rich_bool.RichBool(False)

        # because 1 > False
        self.assertGreater(1, richBool)

        # because False != object()
        self.assertNotEqual(richBool, object())

        # because False < []
        self.assertGreater([], richBool)

        # because 0 == False
        self.assertEqual(0, richBool)
Beispiel #5
0
def createPostSecondaryEducation(school_id, school_country,
                                 expected_graduation, major, degree):
    """Creates a new post secondary education entity based on
  the supplied properties.

  Args:
    school_id: Identifier of the school.
    school_country: Country of the school.
    expected_graduation: Int determining the expected graduation year.
    major: Major for the education.
    degree: Degree type for the education.

  Returns:
    RichBool whose value is set to True if education has been successfully
    created. In that case, extra part points to the newly created education
    entity. Otherwise, RichBool whose value is set to False and extra part is
    a string that represents the reason why the action could not be completed.
  """
    try:
        return rich_bool.RichBool(
            True,
            education_model.Education(school_id=school_id,
                                      school_country=school_country,
                                      expected_graduation=expected_graduation,
                                      major=major,
                                      degree=degree))
    except datastore_errors.BadValueError as e:
        return rich_bool.RichBool(False, str(e))
Beispiel #6
0
    def testExtra(self):
        """Tests that extra property returns a correct value."""
        richBool = rich_bool.RichBool(True)
        self.assertIsNone(richBool.extra)

        extra = object()
        richBool = rich_bool.RichBool(True, extra=extra)
        self.assertEqual(richBool.extra, extra)
Beispiel #7
0
    def testExtraPartOmitted(self):
        """Tests that comparison result does not depend on extra value."""
        richBool1 = rich_bool.RichBool(True, extra='extra one')
        richBool2 = rich_bool.RichBool(True, extra='extra two')
        self.assertEqual(richBool1, richBool2)

        richBool1 = rich_bool.RichBool(True, extra='extra one')
        richBool2 = rich_bool.RichBool(False, extra='extra one')
        self.assertNotEqual(richBool1, richBool2)
Beispiel #8
0
    def testEqualsContract(self):
        """Tests (simply) that equals is equivalence relation."""
        # check reflexivity
        richBool1 = rich_bool.RichBool(True)
        self.assertEqual(richBool1, richBool1)

        # check symmetry
        richBool2 = rich_bool.RichBool(True)
        self.assertEqual(richBool1, richBool2)
        self.assertEqual(richBool2, richBool1)

        # check transitivity
        richBool3 = rich_bool.RichBool(True)
        self.assertEqual(richBool1, richBool2)
        self.assertEqual(richBool2, richBool3)
        self.assertEqual(richBool1, richBool3)
Beispiel #9
0
def canResignAsOrgAdminForOrg(profile, org_key, models=types.MELANGE_MODELS):
  """Tells whether the specified profile can resign from their organization
  administrator role for the specified organization.

  An organization administrator may be removed from the list of administrators
  of an organization, if there is at least one other user with this role.

  Args:
    profile: Profile entity.
    org_key: Organization key.
    models: Instance of types.Models that represent appropriate models.

  Returns:
    RichBool whose value is set to True, if the organization administrator
    is allowed to resign. Otherwise, RichBool whose value is set to False
    and extra part is a string that represents the reason why the user
    is not allowed to resign.
  """
  if org_key not in profile.admin_for:
    raise ValueError(
        'The specified profile is not an organization administrator for %s' %
        org_key.id())

  # retrieve keys of other org admins
  org_admin_keys = getOrgAdmins(org_key, keys_only=True, models=models)
  org_admin_keys.remove(profile.key)

  # try to retrieve the first org admin from the list
  # therefore, it can be safely used within a XG transaction
  if org_admin_keys and org_admin_keys[0].get():
    return rich_bool.TRUE
  else:
    return rich_bool.RichBool(False, extra=ONLY_ORG_ADMIN)
Beispiel #10
0
    def testForNonBooleanType(self):
        """Tests that exception is raised for values of non bool type."""
        # test for object type
        with self.assertRaises(TypeError):
            richBool = rich_bool.RichBool(object())

        # test for list type
        with self.assertRaises(TypeError):
            richBool = rich_bool.RichBool([])

        # test for int type
        with self.assertRaises(TypeError):
            richBool = rich_bool.RichBool(1)

        # test for extra part of bool type
        with self.assertRaises(TypeError):
            richBool = rich_bool.RichBool(object(), extra=True)
Beispiel #11
0
    def testCompareWithBool(self):
        """Tests that comparison with bool type works correctly."""
        richBool = rich_bool.RichBool(True)
        self.assertEqual(True, richBool)
        self.assertEqual(richBool, True)
        self.assertNotEqual(False, richBool)
        self.assertNotEqual(richBool, False)
        self.assertLess(False, richBool)
        self.assertGreater(richBool, False)

        richBool = rich_bool.RichBool(False)
        self.assertEqual(False, richBool)
        self.assertEqual(richBool, False)
        self.assertNotEqual(True, richBool)
        self.assertNotEqual(richBool, True)
        self.assertLess(richBool, True)
        self.assertGreater(True, richBool)
Beispiel #12
0
def createContact(email=None,
                  web_page=None,
                  mailing_list=None,
                  irc_channel=None,
                  feed_url=None,
                  google_plus=None,
                  facebook=None,
                  blog=None,
                  twitter=None,
                  phone=None):
    """Creates a new contact based on the specified channels.

  Args:
    email: Email address.
    web_page: URL to a web page.
    mailing_list: Email address or URL to a mailing list.
    irc_channel: IRC channel.
    feed_url: Feed URL.
    google_plus: URL to Google Plus page.
    facebook: URL to Facebook page.
    blog: URL to a blog page.
    twitter: URL to Twitter profile.
    phone: Phone number.

  Returns:
    RichBool whose value is set to True if contact entity has been successfully
    created. In that case, extra part points to  the newly created object.
    Otherwise, RichBool whose value is set to False and extra part is a string
    that represents the reason why the action could not be completed.
  """
    try:
        return rich_bool.RichBool(
            True,
            contact_model.Contact(email=email,
                                  web_page=web_page,
                                  mailing_list=mailing_list,
                                  irc_channel=irc_channel,
                                  feed_url=feed_url,
                                  google_plus=google_plus,
                                  facebook=facebook,
                                  blog=blog,
                                  twitter=twitter,
                                  phone=phone))
    except ValueError as e:
        return rich_bool.RichBool(False, str(e))
Beispiel #13
0
def createOrganization(org_id,
                       program_key,
                       org_properties,
                       models=types.MELANGE_MODELS):
    """Creates a new organization profile based on the specified properties.

  Args:
    org_id: Identifier of the new organization. Must be unique on
      'per program' basis.
    program_key: Program key.
    org_properties: A dict mapping organization properties to their values.
    models: instance of types.Models that represent appropriate models.

  Returns:
    RichBool whose value is set to True if organization has been successfully
    created. In that case, extra part points to the newly created organization
    entity. Otherwise, RichBool whose value is set to False and extra part is
    a string that represents the reason why the action could not be completed.
  """
    # TODO(daniel): move it to a utility function
    entity_id = '%s/%s' % (program_key.name(), org_id)

    # check if no organization exists for the given key ID
    if models.ndb_org_model.get_by_id(entity_id) is not None:
        return rich_bool.RichBool(False, extra=ORG_ID_IN_USE % org_id)

    program_key = ndb.Key.from_old_key(program_key)

    try:
        organization = models.ndb_org_model(id=entity_id,
                                            org_id=org_id,
                                            program=program_key,
                                            **org_properties)
        organization.put()
    except ValueError as e:
        return rich_bool.RichBool(False, extra=str(e))
    except datastore_errors.BadValueError as e:
        return rich_bool.RichBool(False, extra=str(e))

    return rich_bool.RichBool(True, extra=organization)
Beispiel #14
0
def createUser(username, host_for=None):
    """Creates a new User entity for the specified username for the currently
  logged in account.

  Please note that there should be one-one relationship between Google Accounts
  and User entities. This function, however, does not check if User entity does
  not exist for the account. Therefore, the callers should try to make sure that
  this function will not create a duplicate User entity.

  This function will raise an error, if it is not called from within
  a transaction.

  Args:
    username: A string containing username.
    host_for: A list of program keys for which the user has a program
      administrator role.

  Returns:
    RichBool whose value is set to True if user has been successfully created.
    In that case, extra part points to the newly created user entity. Otherwise,
    RichBool whose value is set to False and extra part is a string that
    represents the reason why the action could not be completed.
    """
    if not ndb.in_transaction():
        raise RuntimeError(
            'This function must be called from within a transaction')

    account = users_api.get_current_user()
    if not account:
        return rich_bool.RichBool(False, _ACCOUNT_NOT_LOGGED_IN)
    elif user_model.User.get_by_id(username):
        # there is already a user with the specified username
        return rich_bool.RichBool(False, _USER_EXISTS_FOR_USERNAME % username)
    else:
        host_for = host_for or []
        user = user_model.User(id=username,
                               account_id=account.user_id(),
                               host_for=host_for)
        user.put()
        return rich_bool.RichBool(True, user)
Beispiel #15
0
def canResignAsMentorForOrg(profile, org_key):
    """Tells whether the specified profile can resign from their mentor role
  for the specified organization.

  A mentor may be removed from the list of mentors of an organization, if
  he or she does not have a proposal or a project assigned to mentor. Also,
  organization administrators have cannot resign from mentorship. They have
  to give up that role first.

  Please note that this function executes a non-ancestor query, so it cannot
  be safely used within transactions.

  Args:
    profile: the specified GSoCProfile entity
    org_key: organization key

  Returns:
    RichBool whose value is set to True, if the mentor is allowed to resign.
    Otherwise, RichBool whose value is set to False and extra part is a string
    that represents the reason why the user is not allowed to resign.
  """
    # TODO(daniel): figure out what to do with "possible_mentors"
    # user may be asked either to remove herself from those proposals or
    # its profile has to be removed in a safe way.

    if org_key not in profile.mentor_for:
        raise ValueError('The specified profile is not a mentor for %s' %
                         org_key.id())

    if org_key in profile.admin_for:
        return rich_bool.RichBool(False, IS_ORG_ADMIN)

    if proposal_logic.hasMentorProposalAssigned(profile, org_key=org_key):
        return rich_bool.RichBool(False, HAS_PROPOSAL_ASSIGNED)

    if project_logic.hasMentorProjectAssigned(profile, org_key=org_key):
        return rich_bool.RichBool(False, HAS_PROJECT_ASSIGNED)

    return rich_bool.TRUE
Beispiel #16
0
def editProfile(profile_key, profile_properties):
  """Edits profile with the specified key based on the supplied properties.

  Args:
    profile_key: Profile key of an existing profile to edit.
    profile_properties: A dict mapping profile properties to their values.

  Returns:
    RichBool whose value is set to True if profile has been successfully
    updated. In that case, extra part points to the updated profile entity.
    Otherwise, RichBool whose value is set to False and extra part is a string
    that represents the reason why the action could not be completed.
  """
  profile = profile_key.get()
  if not profile:
    return rich_bool.RichBool(False, PROFILE_DOES_NOT_EXIST % profile_key.id())
  else:
    try:
      profile.populate(**profile_properties)
      profile.put()
      return rich_bool.RichBool(True, profile)
    except datastore_errors.BadValueError as e:
      return rich_bool.RichBool(False, str(e))
Beispiel #17
0
def canCreateConnection(profile, org_key):
    """Tells whether a connection between the specified profile and organization
  can be created.

  Args:
    profile: Profile entity.
    org_key: Organization key.

  Returns:
    RichBool whose value is set to True, if a connection can be created.
    Otherwise, RichBool whose value is set to False and extra part is
    a string that represents the reason why it is not possible to create
    a new connection.
  """
    if profile.is_student:
        return rich_bool.RichBool(False,
                                  extra=_PROFILE_IS_STUDENT %
                                  profile.profile_id)
    elif connectionExists(profile.key, org_key):
        return rich_bool.RichBool(False,
                                  extra=_CONNECTION_EXISTS %
                                  (profile.profile_id, org_key.id()))
    else:
        return rich_bool.TRUE
Beispiel #18
0
    def testCompareTwoRichBool(self):
        """Tests that two objects are compared based on their boolean value."""
        richBool1 = rich_bool.RichBool(True)
        richBool2 = rich_bool.RichBool(True)
        self.assertEqual(richBool1, richBool2)

        richBool1 = rich_bool.RichBool(True)
        richBool2 = rich_bool.RichBool(False)
        self.assertGreater(richBool1, richBool2)
        self.assertNotEqual(richBool1, richBool2)
        self.assertLess(richBool2, richBool1)

        richBool1 = rich_bool.RichBool(False)
        richBool2 = rich_bool.RichBool(True)
        self.assertGreater(richBool2, richBool1)
        self.assertNotEqual(richBool1, richBool2)
        self.assertLess(richBool1, richBool2)
Beispiel #19
0
    def testValue(self):
        """Tests that value property returns a correct value."""
        richBool = rich_bool.RichBool(True)
        self.assertEqual(richBool.value, True)

        richBool = rich_bool.RichBool(True, extra=object())
        self.assertEqual(richBool.value, True)

        richBool = rich_bool.RichBool(True, extra=False)
        self.assertEqual(richBool.value, True)

        richBool = rich_bool.RichBool(False)
        self.assertEqual(richBool.value, False)

        richBool = rich_bool.RichBool(False, extra=object())
        self.assertEqual(richBool.value, False)

        richBool = rich_bool.RichBool(False, extra=True)
        self.assertEqual(richBool.value, False)
Beispiel #20
0
 def testWithExtra(self):
     """Test that extra part does not change the behavior."""
     self.assertEqual(True .__nonzero__(),
                      rich_bool.RichBool(True, extra=False).__nonzero__())
     self.assertEqual(False .__nonzero__(),
                      rich_bool.RichBool(False, extra=True).__nonzero__())
Beispiel #21
0
 def testNonZero(self):
     """Test that nonzero is computed like for bool type."""
     self.assertEqual(True .__nonzero__(),
                      rich_bool.RichBool(True).__nonzero__())
     self.assertEqual(False .__nonzero__(),
                      rich_bool.RichBool(False).__nonzero__())
Beispiel #22
0
 def testHash(self):
     """Tests that hash is computed like for bool type."""
     self.assertEqual(hash(True), hash(rich_bool.RichBool(True)))
     self.assertEqual(hash(False), hash(rich_bool.RichBool(False)))