blob: 5b02af0197e81ef3b0a5b0605d43eac174b3c8b9 [file] [log] [blame]
# Copyright 2013 the Melange authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Tests for profile logic."""
import datetime
import unittest
from google.appengine.ext import ndb
from melange.logic import profile as profile_logic
from melange.models import address as address_model
from melange.models import education as education_model
from melange.models import profile as ndb_profile_model
from melange.models import user as user_model
from soc.models import program as program_model
from soc.modules.seeder.logic.seeder import logic as seeder_logic
from tests import org_utils
from tests import profile_utils
from tests import program_utils
class CanResignAsOrgAdminForOrgTest(unittest.TestCase):
"""Unit tests for canResignAsOrgAdminForOrg function."""
def setUp(self):
"""See unittest.TestCase.setUp for specification."""
# seed a new program
self.program = program_utils.seedProgram()
# seed a couple of organizations
self.organization_one = org_utils.seedOrganization(self.program.key())
self.organization_two = org_utils.seedOrganization(self.program.key())
# seed a new org admin for organization one
self.org_admin = profile_utils.seedNDBProfile(
self.program.key(), admin_for=[self.organization_one.key])
def testOnlyOrgAdmin(self):
"""Tests that the only org admin cannot resign."""
can_resign = profile_logic.canResignAsOrgAdminForOrg(
self.org_admin, self.organization_one.key)
self.assertFalse(can_resign)
self.assertEqual(can_resign.extra, profile_logic.ONLY_ORG_ADMIN)
def testMoreOrgAdmins(self):
"""Tests that org admin can resign if there is another one."""
# seed another org admin
profile_utils.seedNDBProfile(
self.program.key(), admin_for=[self.organization_one.key])
# now the org admin can resign, as there is another admin
can_resign = profile_logic.canResignAsOrgAdminForOrg(
self.org_admin, self.organization_one.key)
self.assertTrue(can_resign)
def testNotOrgAdminForOrg(self):
"""Tests that error is raised if the profile is not an org admin."""
with self.assertRaises(ValueError):
profile_logic.canResignAsOrgAdminForOrg(
self.org_admin, self.organization_two.key)
_NUMBER_OF_MENTORS = 3
class QueryAllMentorsForProgramTest(unittest.TestCase):
"""Unit test for queryAllMentorsForProgram function."""
def setUp(self):
"""See unittest.TestCase.setUp for specification."""
# seed two programs for the same sponsor
sponsor = program_utils.seedSponsor()
self.program_one = program_utils.seedProgram(sponsor_key=sponsor.key())
program_two = program_utils.seedProgram(sponsor_key=sponsor.key())
org_one = org_utils.seedOrganization(self.program_one.key())
org_two = org_utils.seedOrganization(program_two.key())
self.mentor_keys = set()
# seed a few mentors for both programs
for _ in range(_NUMBER_OF_MENTORS):
self.mentor_keys.add(profile_utils.seedNDBProfile(
self.program_one.key(), mentor_for=[org_one.key]).key)
profile_utils.seedNDBProfile(program_two.key(), mentor_for=[org_two.key])
def testAllMentorsForProgramFetched(self):
"""Tests that the returned query fetches all mentors for the program."""
query = profile_logic.queryAllMentorsForProgram(self.program_one.key())
result = query.fetch(1000)
self.assertEqual(self.mentor_keys, set(mentor.key for mentor in result))
class GetOrgAdminsTest(unittest.TestCase):
"""Unit tests for getOrgAdmins function."""
def setUp(self):
"""See unittest.TestCase.setUp for specification."""
# seed a new program
self.program = program_utils.seedProgram()
# seed a couple of organizations
self.organization_one = org_utils.seedOrganization(self.program.key())
self.organization_two = org_utils.seedOrganization(self.program.key())
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 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 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 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 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]))
class AssignNoRoleForOrgTest(unittest.TestCase):
"""Unit tests for assignNoRoleForOrg function."""
def setUp(self):
"""See unittest.TestCase.setUp for specification."""
# seed a program
self.program = program_utils.seedProgram()
# seed an organization
self.org = org_utils.seedOrganization(self.program.key())
# seed a profile
self.profile = profile_utils.seedNDBProfile(self.program.key())
def testForRoleForOneOrg(self):
"""Tests that the user does not have roles for organization anymore."""
self.profile.mentor_for = [self.org.key]
self.profile.admin_for = [self.org.key]
self.profile.put()
profile_logic.assignNoRoleForOrg(self.profile, self.org.key)
self.assertFalse(self.profile.is_mentor)
self.assertListEqual(self.profile.mentor_for, [])
self.assertFalse(self.profile.is_admin)
self.assertListEqual(self.profile.admin_for, [])
def testForRoleForManyOrgs(self):
"""Tests that the user still have roles for other organizations."""
# seed another organization
other_org = org_utils.seedOrganization(self.program.key())
self.profile.mentor_for = [self.org.key, other_org.key]
self.profile.org_admin_for = [self.org.key]
self.profile.put()
profile_logic.assignNoRoleForOrg(self.profile, self.org.key)
self.assertTrue(self.profile.is_mentor)
self.assertListEqual(self.profile.mentor_for, [other_org.key])
self.assertFalse(self.profile.is_admin)
self.assertListEqual(self.profile.admin_for, [])
class AssignMentorRoleForOrgTest(unittest.TestCase):
"""Unit tests for assignMentorRoleForOrg function."""
def setUp(self):
"""See unittest.TestCase.setUp for specification."""
# seed a program
self.program = program_utils.seedProgram()
# seed an organization
self.org = org_utils.seedOrganization(self.program.key())
# seed a profile
self.profile = profile_utils.seedNDBProfile(self.program.key())
def testForUserWithNoRole(self):
"""Tests that a user with no role is promoted to a mentor role."""
profile_logic.assignMentorRoleForOrg(self.profile, self.org.key)
self.assertTrue(self.profile.is_mentor)
self.assertListEqual(self.profile.mentor_for, [self.org.key])
self.assertFalse(self.profile.is_admin)
self.assertListEqual(self.profile.admin_for, [])
def testForUserWithOrgAdminRole(self):
"""Tests that a user with org admin role is lowered to a mentor role."""
self.profile.mentor_for = [self.org.key]
self.profile.admin_for = [self.org.key]
self.profile.put()
profile_logic.assignMentorRoleForOrg(self.profile, self.org.key)
self.assertTrue(self.profile.is_mentor)
self.assertListEqual(self.profile.mentor_for, [self.org.key])
self.assertFalse(self.profile.is_admin)
self.assertListEqual(self.profile.admin_for, [])
def testForOrgAdminForAnotherOrg(self):
"""Tests that a user is still org admin for another organization."""
# seed another organization
other_org = org_utils.seedOrganization(self.program.key())
self.profile.mentor_for = [other_org.key]
self.profile.admin_for = [other_org.key]
self.profile.put()
profile_logic.assignMentorRoleForOrg(self.profile, self.org.key)
self.assertTrue(self.profile.is_mentor)
self.assertIn(self.org.key, self.profile.mentor_for)
self.assertIn(other_org.key, self.profile.mentor_for)
self.assertTrue(self.profile.is_admin)
self.assertListEqual(self.profile.admin_for, [other_org.key])
class AssignOrgAdminRoleForOrgTest(unittest.TestCase):
"""Unit tests for assignOrgAdminRoleForOrg function."""
def setUp(self):
"""See unittest.TestCase.setUp for specification."""
# seed a program
self.program = program_utils.seedProgram()
# seed an organization
self.org = org_utils.seedOrganization(self.program.key())
# seed a profile
self.profile = profile_utils.seedNDBProfile(self.program.key())
def testForUserWithNoRole(self):
"""Tests that a user with no role is promoted to an org admin role."""
profile_logic.assignOrgAdminRoleForOrg(self.profile, self.org.key)
self.assertTrue(self.profile.is_mentor)
self.assertListEqual(self.profile.mentor_for, [self.org.key])
self.assertTrue(self.profile.is_admin)
self.assertListEqual(self.profile.admin_for, [self.org.key])
def testForUserWithMentorRole(self):
"""Tests that a user with mentor role is promoted to an org admin role."""
self.profile.mentor_for = [self.org.key]
self.profile.put()
profile_logic.assignOrgAdminRoleForOrg(self.profile, self.org.key)
self.assertTrue(self.profile.is_mentor)
self.assertListEqual(self.profile.mentor_for, [self.org.key])
self.assertTrue(self.profile.is_admin)
self.assertListEqual(self.profile.admin_for, [self.org.key])
def testForMentorForAnotherOrg(self):
"""Tests that a user is still only a mentor for another organization."""
# seed another organization
other_org = org_utils.seedOrganization(self.program.key())
self.profile.mentor_for = [other_org.key]
self.profile.put()
profile_logic.assignOrgAdminRoleForOrg(self.profile, self.org.key)
self.assertTrue(self.profile.is_mentor)
self.assertIn(self.org.key, self.profile.mentor_for)
self.assertIn(other_org.key, self.profile.mentor_for)
self.assertTrue(self.profile.is_admin)
self.assertListEqual(self.profile.admin_for, [self.org.key])
class GetProfileForUsernameTest(unittest.TestCase):
"""Unit tests for getProfileForUsername function."""
def setUp(self):
"""See unittest.TestCase.setUp for specification."""
# seed a program
self.program_key = seeder_logic.seed(program_model.Program).key()
# seed a user
self.user = profile_utils.seedNDBUser(user_id='test')
# seed a profile
self.profile = profile_utils.seedNDBProfile(
self.program_key, user=self.user)
def testForNoProfile(self):
"""Tests that no entity is returned when a user does not have a profile."""
profile = profile_logic.getProfileForUsername('other', self.program_key)
self.assertIsNone(profile)
def testForOtherProgram(self):
"""Tests that no entity is returned for a different program."""
other_program = seeder_logic.seed(program_model.Program)
profile = profile_logic.getProfileForUsername('other', other_program.key())
self.assertIsNone(profile)
def testForExistingProfile(self):
"""Tests that profile is returned if exists."""
profile = profile_logic.getProfileForUsername('test', self.program_key)
self.assertEqual(profile.key, self.profile.key)
TEST_SPONSOR_ID = 'sponsor_id'
TEST_PROGRAM_ID = 'program_id'
TEST_PROFILE_ID = 'profile_id'
class GetProfileKeyTest(unittest.TestCase):
"""Unit tests for getProfileKey function."""
def testProfileKey(self):
"""Tests that constructed profile key is correct."""
key = profile_logic.getProfileKey(
TEST_SPONSOR_ID, TEST_PROGRAM_ID, TEST_PROFILE_ID)
self.assertEqual(
key.id(),
'%s/%s/%s' % (TEST_SPONSOR_ID, TEST_PROGRAM_ID, TEST_PROFILE_ID))
self.assertEqual(key.kind(), ndb_profile_model.Profile._get_kind())
self.assertEqual(key.parent().id(), TEST_PROFILE_ID)
self.assertEqual(key.parent().kind(), user_model.User._get_kind())
TEST_FIRST_NAME = 'First'
TEST_LAST_NAME = 'Last'
TEST_PUBLIC_NAME = 'Public Name'
TEST_PHOTO_URL = 'http://www.test.photo.url.com'
TEST_BIRTH_DATE = datetime.date(1990, 1, 1)
TEST_STREET = 'Test street'
TEST_CITY = 'Test city'
TEST_COUNTRY = 'United States'
TEST_PROVINCE = 'California'
TEST_POSTAL_CODE = '90000'
TEST_RESIDENTIAL_ADDRESS = address_model.Address(
street=TEST_STREET, city=TEST_CITY, country=TEST_COUNTRY,
province=TEST_PROVINCE, postal_code=TEST_POSTAL_CODE)
TEST_PROFILE_PROPERTIES = {
'first_name': TEST_FIRST_NAME,
'last_name': TEST_LAST_NAME,
'public_name': TEST_PUBLIC_NAME,
'photo_url': TEST_PHOTO_URL,
'birth_date': TEST_BIRTH_DATE,
'residential_address': TEST_RESIDENTIAL_ADDRESS,
}
class CreateProfileTest(unittest.TestCase):
"""Unit tests for createProfile function."""
def setUp(self):
"""See unittest.TestCase.setUp for specification."""
self.user = profile_utils.seedNDBUser()
self.program = program_utils.seedProgram()
def testProfileCreated(self):
"""Tests that profile entity is created."""
result = profile_logic.createProfile(
self.user.key, self.program.key(), TEST_PROFILE_PROPERTIES)
# check that profile is returned
self.assertTrue(result)
# check that profile is persisted
profile = result.extra.key.get()
self.assertIsNotNone(profile)
# check properties
self.assertEqual(
profile.key.id(),
'%s/%s' % (self.program.key().name(), self.user.key.id()))
self.assertEqual(profile.program.to_old_key(), self.program.key())
self.assertEqual(profile.first_name, TEST_FIRST_NAME)
self.assertEqual(profile.last_name, TEST_LAST_NAME)
self.assertEqual(profile.photo_url, TEST_PHOTO_URL)
self.assertEqual(profile.birth_date, TEST_BIRTH_DATE)
self.assertEqual(profile.residential_address.street, TEST_STREET)
self.assertEqual(profile.residential_address.city, TEST_CITY)
self.assertEqual(profile.residential_address.country, TEST_COUNTRY)
self.assertEqual(profile.residential_address.province, TEST_PROVINCE)
self.assertEqual(profile.residential_address.postal_code, TEST_POSTAL_CODE)
def testProfileExists(self):
"""Tests that second profile is not created for same user and program."""
# seed a profile
profile_utils.seedNDBProfile(self.program.key(), user=self.user)
result = profile_logic.createProfile(
self.user.key, self.program.key(), TEST_PROFILE_PROPERTIES)
self.assertFalse(result)
self.assertEqual(result.extra, profile_logic.PROFILE_EXISTS)
OTHER_TEST_FIRST_NAME = 'Other First'
OTHER_TEST_LAST_NAME = 'Other Last'
OTHER_TEST_PUBLIC_NAME = 'Other Public Name'
OTHER_TEST_PHOTO_URL = 'http://www.other.test.photo.url.com'
OTHER_TEST_BIRTH_DATE = datetime.date(1991, 1, 1)
OTHER_TEST_STREET = 'Test other street'
OTHER_TEST_CITY = 'Test city'
OTHER_TEST_COUNTRY = 'United States'
OTHER_TEST_PROVINCE = 'Alaska'
OTHER_TEST_POSTAL_CODE = '99503'
OTHER_TEST_RESIDENTIAL_ADDRESS = address_model.Address(
street=OTHER_TEST_STREET, city=OTHER_TEST_CITY, country=OTHER_TEST_COUNTRY,
province=OTHER_TEST_PROVINCE, postal_code=OTHER_TEST_POSTAL_CODE)
OTHER_TEST_PROFILE_PROPERTIES = {
'first_name': OTHER_TEST_FIRST_NAME,
'last_name': OTHER_TEST_LAST_NAME,
'public_name': OTHER_TEST_PUBLIC_NAME,
'photo_url': OTHER_TEST_PHOTO_URL,
'birth_date': OTHER_TEST_BIRTH_DATE,
'residential_address': OTHER_TEST_RESIDENTIAL_ADDRESS,
}
class EditProfileTest(unittest.TestCase):
"""Unit tests for editProfile function."""
def setUp(self):
"""See unittest.TestCase.setUp for specification."""
self.user = profile_utils.seedNDBUser()
self.program = program_utils.seedProgram()
self.profile_key = ndb.Key(
user_model.User._get_kind(), self.user.key.id(),
ndb_profile_model.Profile._get_kind(),
'%s/%s' % (self.program.key().name(), self.user.key.id()))
def testProfileDoesNotExist(self):
"""Tests that error is raised when a profile does not exist."""
result = profile_logic.editProfile(
self.profile_key, TEST_PROFILE_PROPERTIES)
self.assertFalse(result)
self.assertEqual(
result.extra,
profile_logic.PROFILE_DOES_NOT_EXIST % self.profile_key.id())
def testProfileUpdated(self):
"""Tests that profile properties are updated properly."""
# seed a profile
profile = profile_utils.seedNDBProfile(self.program.key(), user=self.user)
result = profile_logic.editProfile(
profile.key, OTHER_TEST_PROFILE_PROPERTIES)
self.assertTrue(result)
# check that updated profile is persisted
profile = result.extra.key.get()
self.assertIsNotNone(profile)
# check properties
self.assertEqual(
profile.key.id(),
'%s/%s' % (self.program.key().name(), self.user.key.id()))
self.assertEqual(profile.program.to_old_key(), self.program.key())
self.assertEqual(profile.first_name, OTHER_TEST_FIRST_NAME)
self.assertEqual(profile.last_name, OTHER_TEST_LAST_NAME)
self.assertEqual(profile.photo_url, OTHER_TEST_PHOTO_URL)
self.assertEqual(profile.birth_date, OTHER_TEST_BIRTH_DATE)
self.assertEqual(profile.residential_address.street, OTHER_TEST_STREET)
self.assertEqual(profile.residential_address.city, OTHER_TEST_CITY)
self.assertEqual(profile.residential_address.country, OTHER_TEST_COUNTRY)
self.assertEqual(profile.residential_address.province, OTHER_TEST_PROVINCE)
self.assertEqual(
profile.residential_address.postal_code, OTHER_TEST_POSTAL_CODE)
TEST_SCHOOL_COUNTRY = 'United States'
TEST_SCHOOL_ID = 'Melange University'
TEST_EXPECTED_GRADUATION = datetime.date.today().year
TEST_EDUCATION_PROPERTIES = {
'school_country': TEST_SCHOOL_COUNTRY,
'school_id': TEST_SCHOOL_ID,
'expected_graduation': TEST_EXPECTED_GRADUATION
}
TEST_EDUCATION = education_model.Education(**TEST_EDUCATION_PROPERTIES)
TEST_STUDENT_DATA_PROPERTIES = {
'education': TEST_EDUCATION
}
class CreateStudentDataTest(unittest.TestCase):
"""Unit tests for createStudentData function."""
def testStudentDataCreated(self):
"""Tests that student data is created properly if all data is valid."""
student_data = profile_logic.createStudentData(TEST_STUDENT_DATA_PROPERTIES)
# check properties of education
for key in TEST_EDUCATION_PROPERTIES:
self.assertEqual(
student_data.education.to_dict()[key], TEST_EDUCATION_PROPERTIES[key])