Merge org app email changes and access fix.
diff --git a/app/main.py b/app/main.py
index d122307..bed8b31 100644
--- a/app/main.py
+++ b/app/main.py
@@ -12,16 +12,14 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-"""Main Melange module with profiling support.
-"""
-
+"""Main Melange module with profiling support."""
import logging
from google.appengine.ext.webapp import util
-# pylint: disable=W0611
-import gae_django
+# TODO(nathaniel): What's up with this unused import?
+import gae_django # pylint: disable=unused-import
def profile_main_as_html():
diff --git a/app/melange/logic/organization.py b/app/melange/logic/organization.py
index 585d583..b080c26 100644
--- a/app/melange/logic/organization.py
+++ b/app/melange/logic/organization.py
@@ -254,3 +254,73 @@
cache_key, CachedData(orgs, datetime.datetime.now(), next_cursor))
return orgs
+
+
+# TODO(nathaniel): This is computationally inefficient and just plain weird.
+# The right way to fix this problem is to just store org logos in org profiles
+# (issue 1796).
+def getAcceptedOrganizationsWithLogoURLs(
+ program_key, limit=None, models=types.MELANGE_MODELS):
+ """Finds accepted organizations that have set a logo URL.
+
+ There is no guarantee that two different invocation of this function for
+ the same arguments will return the same entities. The callers should
+ acknowledge that it will receive a list of 'any' accepted organizations for
+ the program and not make any further assumptions.
+
+ In order to speed up the function, organizations may be returned
+ from memcache, so subsequent calls to this function may be more efficient.
+
+ Args:
+ program_key: Program key.
+ limit: Maximum number of results to return.
+ models: instance of types.Models that represent appropriate models.
+
+ Returns:
+ A list of organization entities participating in the specified program
+ that have non-empty logo URL attributes.
+ """
+ limit = limit or _DEFAULT_ORG_NUMBER
+
+ cache_key = '%s_accepted_orgs_with_logo_URLs_%s' % (limit, program_key.name())
+ cached_data = memcache.get(cache_key)
+ if cached_data:
+ if datetime.datetime.now() < cached_data.time + _ORG_CACHE_DURATION:
+ return cached_data.orgs
+ else:
+ cursor = cached_data.cursor
+ else:
+ cursor = None
+
+ # Iterate through all the orgs looking for limit orgs with logos or a
+ # determination that all available orgs have been exhausted.
+ orgs = []
+ all_found_org_keys = set()
+ while len(orgs) < limit:
+ query = models.ndb_org_model.query(
+ models.ndb_org_model.program == ndb.Key.from_old_key(program_key),
+ models.ndb_org_model.status == org_model.Status.ACCEPTED)
+ found_orgs, cursor, _ = query.fetch_page(
+ limit - len(orgs), start_cursor=cursor)
+ for found_org in found_orgs:
+ if found_org.key in all_found_org_keys:
+ # We've wrapped all the way around the list of orgs and come back
+ # to the start. Return what we have.
+ break
+ all_found_org_keys.add(found_org.key)
+ if found_org.logo_url:
+ orgs.append(found_org)
+ if len(found_orgs) < limit - len(orgs):
+ if cursor:
+ # Wrap around to the beginning.
+ cursor = None
+ else:
+ # Even from the beginning there just aren't enough orgs? Give up.
+ break
+
+ # If the requested number of organizations have been found, cache them.
+ if len(orgs) == limit:
+ memcache.set(
+ cache_key, CachedData(orgs, datetime.datetime.now(), cursor))
+
+ return orgs
diff --git a/app/soc/logic/cleaning.py b/app/soc/logic/cleaning.py
index ffb3f46..5d396a2 100644
--- a/app/soc/logic/cleaning.py
+++ b/app/soc/logic/cleaning.py
@@ -226,7 +226,6 @@
user_id = clean_link_id(field_name)(self)
current_user = user_logic.getByCurrentAccount()
- # pylint: disable=E1103
if not current_user or current_user.user_id != user_id:
# this user is not the current user
raise forms.ValidationError('This user is not you.')
@@ -267,7 +266,6 @@
user = clean_user_field(self)
current_user = user_logic.getByCurrentAccount()
- # pylint: disable=E1103
if user.key == current_user.key:
# users are equal
raise forms.ValidationError('You cannot enter yourself here.')
diff --git a/app/soc/logic/user.py b/app/soc/logic/user.py
index 4929145..16a3e88 100644
--- a/app/soc/logic/user.py
+++ b/app/soc/logic/user.py
@@ -150,7 +150,6 @@
# default user to the current logged in user
user = forAccount(account)
- # pylint: disable=E1103
if user and user.is_developer:
return True
diff --git a/app/soc/modules/core.py b/app/soc/modules/core.py
index 6da188f..50a5a21 100644
--- a/app/soc/modules/core.py
+++ b/app/soc/modules/core.py
@@ -96,14 +96,10 @@
class Core(object):
- """The core handler that controls the Melange API.
- """
+ """The core handler that controls the Melange API."""
def __init__(self):
- """Creates a new instance of the Core.
- """
-
- # pylint: disable=C0103
+ """Creates a new instance of the Core."""
self.API_VERSION = 1
self.registered_callbacks = []
diff --git a/app/soc/modules/gci/logic/conversation.py b/app/soc/modules/gci/logic/conversation.py
index 27143ee..6b78ed3 100644
--- a/app/soc/modules/gci/logic/conversation.py
+++ b/app/soc/modules/gci/logic/conversation.py
@@ -14,20 +14,20 @@
"""GCIConversationUser logic methods."""
+from datetime import timedelta
+
from google.appengine.ext import db
from google.appengine.ext import ndb
-from datetime import timedelta
+from melange.logic import profile as profile_logic
+from melange.models import profile as profile_model
from soc.tasks import mailer
+from soc.modules.gci.logic import message as gcimessage_logic
+from soc.modules.gci.logic.helper import notifications
from soc.modules.gci.models import conversation as gciconversation_model
from soc.modules.gci.models import message as gcimessage_model
-from soc.modules.gci.models import profile as gciprofile_model
-
-from soc.modules.gci.logic import message as gcimessage_logic
-from soc.modules.gci.logic import profile as gciprofile_logic
-from soc.modules.gci.logic.helper import notifications
from soc.models import conversation as conversation_model
@@ -339,54 +339,42 @@
recipients_type is 'User', True is always returned. Also returns true if
the user is the conversation's creator.
"""
-
- user_ent = db.get(ndb.Key.to_old_key(user))
conversation_ent = conversation.get()
if not conversation_ent.auto_update_users and not ignore_auto_update_users:
return True
- if conversation_ent.creator == ndb.Key.from_old_key(user_ent.key()):
+ if conversation_ent.creator == user:
return True
- profile_results = gciprofile_logic.queryProfileForUserAndProgram(
- user=user_ent.key(),
- program=ndb.Key.to_old_key(conversation_ent.program)).fetch(1)
+ profile = profile_logic.getProfileForUsername(
+ user.id(), conversation_ent.program.to_old_key())
- if len(profile_results) == 0:
+ if not profile:
raise Exception('Could not find GCIProfile for user and program.')
- profile = profile_results[0]
-
- student_info_query = gciprofile_logic.queryStudentInfoForParent(profile)
- student_info_results = student_info_query.fetch(1)
- student_info = student_info_results[0] if student_info_results else None
-
if conversation_ent.recipients_type == conversation_model.PROGRAM:
- if conversation_ent.include_admins and profile.is_org_admin:
+ if conversation_ent.include_admins and profile.is_admin:
return True
elif conversation_ent.include_mentors and profile.is_mentor:
return True
elif conversation_ent.include_students and profile.is_student:
return True
- elif (student_info and conversation_ent.include_winners
- and student_info.is_winner):
+ elif (profile.is_student and conversation_ent.include_winners
+ and profile.student_data.is_winner):
return True
else:
return False
elif conversation_ent.recipients_type == conversation_model.ORGANIZATION:
- if (conversation_ent.include_admins and profile.is_org_admin and
- ndb.Key.to_old_key(conversation_ent.organization) in
- profile.org_admin_for):
+ if (conversation_ent.include_admins and
+ conversation_ent.organization in profile.admin_for):
return True
- elif (conversation_ent.include_mentors and profile.is_mentor and
- ndb.Key.to_old_key(conversation_ent.organization) in
- profile.mentor_for):
+ elif (conversation_ent.include_mentors and
+ conversation_ent.organization in profile.mentor_for):
return True
- elif (student_info and conversation_ent.include_winners
- and student_info.is_winner and
- ndb.Key.to_old_key(conversation_ent.organization) ==
- student_info.winner_for.key()):
+ elif (profile.is_student and conversation_ent.include_winners
+ and profile.student_data.is_winner and
+ conversation_ent.organization == profile.student_data.winner_for):
return True
else:
return False
@@ -408,12 +396,11 @@
conversation: Key (ndb) of GCIConversation.
"""
conv = conversation.get()
- program = db.get(ndb.Key.to_old_key(conv.program))
def addProfile(profile):
addUserToConversation(
conversation=conversation,
- user=ndb.Key.from_old_key(profile.user.key()))
+ user=profile.key.parent())
def deleteConvUserIfDoesntBelong(conv_user):
if not doesConversationUserBelong(conversation_user=conv_user.key):
@@ -427,59 +414,50 @@
# Make sure users who fit the criteria are included
if conv.recipients_type == conversation_model.PROGRAM:
if conv.include_admins:
- query = gciprofile_model.GCIProfile.all()
- query.filter('program =', ndb.Key.to_old_key(conv.program))
- query.filter('is_org_admin =', True)
- map(addProfile, query.run(batch_size=1000))
+ 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 = gciprofile_model.GCIProfile.all()
- query.filter('program =', ndb.Key.to_old_key(conv.program))
- query.filter('is_mentor =', True)
- map(addProfile, query.run(batch_size=1000))
+ query = profile_logic.queryAllMentorsForProgram(conv.program.to_old_key())
+ map(addProfile, query)
if conv.include_students:
- query = gciprofile_model.GCIProfile.all()
- query.filter('program =', ndb.Key.to_old_key(conv.program))
- query.filter('is_student =', True)
- map(addProfile, query.run(batch_size=1000))
+ 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 = gciprofile_model.GCIStudentInfo.all()
- query.filter('program =', ndb.Key.to_old_key(conv.program))
- query.filter('is_winner =', True)
- map(lambda e: addProfile(e.parent()), query.run(batch_size=1000))
+ 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:
- org_db_key = ndb.Key.to_old_key(conv.organization)
-
if conv.include_admins:
- query = gciprofile_model.GCIProfile.all()
- query.filter('program =', ndb.Key.to_old_key(conv.program))
- query.filter('is_org_admin =', True)
- query.filter('org_admin_for =', org_db_key)
- map(addProfile, query.run(batch_size=1000))
+ org_admins = profile_logic.getOrgAdmins(conv.organization)
+ map(addProfile, org_admins)
if conv.include_mentors:
- query = gciprofile_model.GCIProfile.all()
- query.filter('program =', ndb.Key.to_old_key(conv.program))
- query.filter('is_mentor =', True)
- query.filter('mentor_for =', org_db_key)
- map(addProfile, query.run(batch_size=1000))
+ 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 = gciprofile_model.GCIStudentInfo.all()
- query.filter('program =', ndb.Key.to_old_key(conv.program))
- query.filter('is_winner =', True)
- query.filter('winner_for =', org_db_key)
- map(lambda e: addProfile(e.parent()), query.run(batch_size=1000))
+ 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 refreshConversationsForUserAndProgram(user, program):
+def refreshConversationsForUserAndProgram(user_key, program_key):
"""Adds/removes the user to/from conversations that they should be involved in
based on the conversation's criteria.
@@ -499,18 +477,14 @@
should have been created when the conversation was initially created.
Args:
- user: Key (ndb) of the User.
- program: Key (ndb) of the GCIProgram.
+ user_key: Key (ndb) of the User.
+ program_key: Key (ndb) of the GCIProgram.
"""
- profile = gciprofile_logic.queryProfileForUserAndProgram(
- user=ndb.Key.to_old_key(user),
- program=ndb.Key.to_old_key(program)).get()
+ profile = profile_logic.getProfileForUsername(
+ user_key.id(), program_key.to_old_key())
if not profile:
- raise Exception('Could not find GCIProfile for user and program.')
-
- student_info_query = gciprofile_logic.queryStudentInfoForParent(profile)
- student_info = student_info_query.get()
+ raise Exception('Could not find Profile for user and program.')
def deleteConvUserIfDoesntBelong(conv_user):
if not doesConversationUserBelong(
@@ -518,21 +492,19 @@
conv_user.key.delete()
# Remove user from any conversations they're in that they don't belong in
- conv_user_query = queryForProgramAndUser(user=user, program=program)
+ conv_user_query = queryForProgramAndUser(user=user_key, program=program_key)
map(deleteConvUserIfDoesntBelong, conv_user_query)
def addToConversation(conversation):
- addUserToConversation(conversation=conversation.key, user=user)
+ addUserToConversation(conversation=conversation.key, user=user_key)
- mentor_org_keys = map(lambda key: ndb.Key.from_old_key(key),
- profile.mentor_for)
- admin_org_keys = map(lambda key: ndb.Key.from_old_key(key),
- profile.org_admin_for)
+ mentor_org_keys = profile.mentor_for
+ admin_org_keys = profile.admin_for
# Make sure user is added to program conversations they belong in as a
# student
if profile.is_student:
- query = (queryConversationsForProgram(program)
+ query = (queryConversationsForProgram(program_key)
.filter(gciconversation_model.GCIConversation.recipients_type ==
conversation_model.PROGRAM)
.filter(gciconversation_model.GCIConversation.auto_update_users == True)
@@ -542,7 +514,7 @@
# Make sure user is added to program conversations they belong in as a
# mentor
if profile.is_mentor:
- query = (queryConversationsForProgram(program)
+ query = (queryConversationsForProgram(program_key)
.filter(gciconversation_model.GCIConversation.recipients_type ==
conversation_model.PROGRAM)
.filter(gciconversation_model.GCIConversation.auto_update_users == True)
@@ -551,8 +523,8 @@
# Make sure user is added to program conversations they belong in as an
# admin
- if profile.is_org_admin:
- query = (queryConversationsForProgram(program)
+ if profile.is_admin:
+ query = (queryConversationsForProgram(program_key)
.filter(gciconversation_model.GCIConversation.recipients_type ==
conversation_model.PROGRAM)
.filter(gciconversation_model.GCIConversation.auto_update_users == True)
@@ -561,8 +533,8 @@
# Make sure user is added to program conversations they belong in as a
# winner
- if student_info and student_info.is_winner:
- query = (queryConversationsForProgram(program)
+ if profile.student_data and profile.student_data.is_winner:
+ query = (queryConversationsForProgram(program_key)
.filter(gciconversation_model.GCIConversation.recipients_type ==
conversation_model.PROGRAM)
.filter(gciconversation_model.GCIConversation.auto_update_users == True)
@@ -572,7 +544,7 @@
# Make sure user is added to org conversations they belong in as an org
# mentor
if profile.is_mentor and mentor_org_keys:
- query = (queryConversationsForProgram(program)
+ query = (queryConversationsForProgram(program_key)
.filter(gciconversation_model.GCIConversation.recipients_type ==
conversation_model.ORGANIZATION)
.filter(gciconversation_model.GCIConversation.auto_update_users == True)
@@ -583,8 +555,8 @@
# Make sure user is added to org conversations they belong in as an org
# admin
- if profile.is_org_admin and admin_org_keys:
- query = (queryConversationsForProgram(program)
+ if profile.is_admin and admin_org_keys:
+ query = (queryConversationsForProgram(program_key)
.filter(gciconversation_model.GCIConversation.recipients_type ==
conversation_model.ORGANIZATION)
.filter(gciconversation_model.GCIConversation.auto_update_users == True)
@@ -595,14 +567,14 @@
# Make sure user is added to org conversations they belong in as an org
# winner
- if student_info and student_info.is_winner and student_info.winner_for:
- query = (queryConversationsForProgram(program)
+ if profile.is_student and profile.student_data.is_winner:
+ query = (queryConversationsForProgram(program_key)
.filter(gciconversation_model.GCIConversation.recipients_type ==
conversation_model.ORGANIZATION)
.filter(gciconversation_model.GCIConversation.auto_update_users == True)
.filter(gciconversation_model.GCIConversation.include_winners == True)
.filter(gciconversation_model.GCIConversation.organization ==
- ndb.Key.from_old_key(student_info.winner_for.key())))
+ profile.student_data.winner_for))
map(addToConversation, query)
@@ -626,16 +598,14 @@
for conv_user in conv_users:
if conv_user.enable_notifications and (
not exclude or conv_user.user not in exclude):
- user_key = ndb.Key.to_old_key(conv_user.user)
- profile_results = gciprofile_logic.queryProfileForUserAndProgram(
- user=user_key, program=program_key).fetch(1)
+ profile = profile_logic.getProfileForUsername(
+ conv_user.user.id(), program_key)
- if len(profile_results) == 0:
+ if not profile:
raise Exception('Could not find GCIProfile for user %s and program. %s'
% (conv_user.name, program_key.name()))
- profile = profile_results[0]
- addresses.add(profile.email)
+ addresses.add(profile.contact.email)
return addresses
diff --git a/app/soc/modules/gci/views/conversation_create.py b/app/soc/modules/gci/views/conversation_create.py
index c58a63b..6b6af19 100644
--- a/app/soc/modules/gci/views/conversation_create.py
+++ b/app/soc/modules/gci/views/conversation_create.py
@@ -21,9 +21,10 @@
from django.utils import translation
from django.forms import util as forms_util
-from google.appengine.ext import db
from google.appengine.ext import ndb
+from melange.models import user as user_model
+
from soc.logic import cleaning
from soc.views import template
@@ -287,9 +288,9 @@
invalid_usernames = []
for username in usernames:
if username:
- key = db.Key.from_path('User', username)
- if db.get(key):
- user_keys.append(ndb.Key.from_old_key(key))
+ user = user_model.User.get_by_id(username)
+ if user:
+ user_keys.append(user.key)
else:
invalid_usernames.append(username)
diff --git a/app/soc/modules/gsoc/views/homepage.py b/app/soc/modules/gsoc/views/homepage.py
index 74a0e0a..616985a 100644
--- a/app/soc/modules/gsoc/views/homepage.py
+++ b/app/soc/modules/gsoc/views/homepage.py
@@ -105,7 +105,7 @@
context['nr_accepted_orgs'] = nr_orgs if nr_orgs else ""
context['accepted_orgs_link'] = accepted_orgs_link
participating_orgs = []
- current_orgs = org_logic.getAcceptedOrganizations(
+ current_orgs = org_logic.getAcceptedOrganizationsWithLogoURLs(
self.data.program.key(), models=self.data.models)
for org in current_orgs:
diff --git a/app/soc/modules/seeder/logic/models.py b/app/soc/modules/seeder/logic/models.py
index 11f6fe9..375dd5f 100644
--- a/app/soc/modules/seeder/logic/models.py
+++ b/app/soc/modules/seeder/logic/models.py
@@ -11,9 +11,8 @@
# 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.
-"""This is the Data Seeder Model Logic module.
-"""
+"""This is the Data Seeder Model Logic module."""
import os
@@ -49,21 +48,19 @@
@staticmethod
def _getModels():
- """Returns a list of models in all modules specified in
- settings.MODULES.
- """
- modules = set()
-
+ """Returns a list of models in all modules specified in settings.MODULES."""
model_package_names = [
+ 'codein.models',
'soc.models',
'soc.modules.gsoc.models',
'soc.modules.gci.models',
- 'summerofcode.models'
+ 'summerofcode.models',
]
packages = [(__import__(module_name, fromlist=['']), module_name)
for module_name in model_package_names]
+ modules = set()
for package, packagename in packages:
for module_file in os.listdir(os.path.dirname(package.__file__)):
if not module_file.endswith(".py"):
@@ -73,13 +70,8 @@
modelname = os.path.basename(module_file)[:-3]
try:
- # pylint: disable=W0122
- exec("import %s.%s as current_model" % (packagename, modelname))
- # pylint: enable=W0122
-
- # pylint: disable=E0602
- for _, klass in getmembers(current_model, isclass):#@UndefinedVariable
- # pylint: enable=E0602
+ current_model = __import__('%s.%s' % (packagename, modelname))
+ for _, klass in getmembers(current_model, isclass):
# Make sure the class is actually defined in the module
klass_module = '.'.join(klass.__module__.split('.')[:-1])
@@ -99,8 +91,7 @@
return list(modules)
def _getReferenceClass(self, prop, model):
- """Return the referenced class name for a reference property.
- """
+ """Return the referenced class name for a reference property."""
klass = None
if (prop.name == 'scope'):
module = model.__module__
diff --git a/app/soc/modules/seeder/logic/providers/__init__.py b/app/soc/modules/seeder/logic/providers/__init__.py
index 811a221..1e85513 100644
--- a/app/soc/modules/seeder/logic/providers/__init__.py
+++ b/app/soc/modules/seeder/logic/providers/__init__.py
@@ -11,11 +11,9 @@
# 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.
-"""Contains data providers implementations and utilities.
-"""
+"""Contains data providers implementations and utilities."""
-# pylint: disable=C0301
from soc.modules.seeder.logic.providers.string import FixedStringProvider
from soc.modules.seeder.logic.providers.string import RandomWordProvider
from soc.modules.seeder.logic.providers.string import RandomNameProvider
@@ -50,12 +48,10 @@
from soc.modules.seeder.logic.providers.reference import RandomReferenceProvider
from soc.modules.seeder.logic.providers.reference import FixedReferenceProvider
from soc.modules.seeder.logic.providers.list import EmptyListProvider
-# pylint: enable=C0301
class Logic():
- """Logic class for general data provider functionality.
- """
+ """Logic class for general data provider functionality."""
def __init__(self):
self.providers = {}
diff --git a/app/soc/modules/seeder/logic/providers/boolean.py b/app/soc/modules/seeder/logic/providers/boolean.py
index 4194ef6..27b3a37 100644
--- a/app/soc/modules/seeder/logic/providers/boolean.py
+++ b/app/soc/modules/seeder/logic/providers/boolean.py
@@ -11,33 +11,23 @@
# 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.
-"""Module containing data providers for BooleanProperty.
-"""
+"""Module containing data providers for BooleanProperty."""
+
+import random
from soc.modules.seeder.logic.providers.provider import FixedValueProvider
from soc.modules.seeder.logic.providers.provider import BaseDataProvider
from soc.modules.seeder.logic.providers.provider import ParameterValueError
from soc.modules.seeder.logic.providers.provider import DataProviderParameter
-import random
-_authors__ = [
- '"Felix Kerekes" <sttwister@gmail.com>',
- ]
-
-
-# pylint: disable=W0223
class BooleanProvider(BaseDataProvider):
- """Base class for all data providers that return a boolean.
- """
-
- pass
+ """Base class for all data providers that return a boolean."""
class FixedBooleanProvider(BooleanProvider, FixedValueProvider):
- """Data provider that returns a fixed integer.
- """
+ """Data provider that returns a fixed integer."""
def checkParameters(self):
super(FixedBooleanProvider, self).checkParameters()
@@ -49,8 +39,7 @@
class RandomBooleanProvider(BooleanProvider):
- """Data provider that returns a random boolean value.
- """
+ """Data provider that returns a random boolean value."""
DEFAULT_CHANCE = 0.5
diff --git a/app/soc/modules/seeder/logic/providers/date.py b/app/soc/modules/seeder/logic/providers/date.py
index cc09974..8f9b90e 100644
--- a/app/soc/modules/seeder/logic/providers/date.py
+++ b/app/soc/modules/seeder/logic/providers/date.py
@@ -11,30 +11,24 @@
# 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.
-"""Module containing data providers for DateProperty.
-"""
+"""Module containing data providers for DateProperty."""
-from soc.modules.seeder.logic.providers.provider import BaseDataProvider
-from soc.modules.seeder.logic.providers.provider import DataProviderParameter
-from soc.modules.seeder.logic.providers.provider import ParameterValueError
import datetime
import random
import time
+from soc.modules.seeder.logic.providers.provider import BaseDataProvider
+from soc.modules.seeder.logic.providers.provider import DataProviderParameter
+from soc.modules.seeder.logic.providers.provider import ParameterValueError
-# pylint: disable=W0223
class DateProvider(BaseDataProvider):
- """Base class for all data providers that return a date.
- """
-
- pass
+ """Base class for all data providers that return a date."""
class FixedDateProvider(DateProvider):
- """Data provider that returns a fixed string.
- """
+ """Data provider that returns a fixed string."""
@classmethod
def getParametersList(cls):
diff --git a/app/soc/modules/seeder/logic/providers/datetime_provider.py b/app/soc/modules/seeder/logic/providers/datetime_provider.py
index 1dde7ae..01ddb2d 100644
--- a/app/soc/modules/seeder/logic/providers/datetime_provider.py
+++ b/app/soc/modules/seeder/logic/providers/datetime_provider.py
@@ -11,30 +11,24 @@
# 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.
-"""Module containing data providers for DateProperty.
-"""
+"""Module containing data providers for DateProperty."""
-from soc.modules.seeder.logic.providers.provider import BaseDataProvider
-from soc.modules.seeder.logic.providers.provider import DataProviderParameter
-from soc.modules.seeder.logic.providers.provider import ParameterValueError
import datetime
import random
import time
+from soc.modules.seeder.logic.providers.provider import BaseDataProvider
+from soc.modules.seeder.logic.providers.provider import DataProviderParameter
+from soc.modules.seeder.logic.providers.provider import ParameterValueError
-# pylint: disable=W0223
class DateTimeProvider(BaseDataProvider):
- """Base class for all data providers that return a date.
- """
-
- pass
+ """Base class for all data providers that return a date."""
class FixedDateTimeProvider(DateTimeProvider):
- """Data provider that returns a fixed string.
- """
+ """Data provider that returns a fixed string."""
@classmethod
def getParametersList(cls):
diff --git a/app/soc/modules/seeder/logic/providers/email.py b/app/soc/modules/seeder/logic/providers/email.py
index 5356ecf..f79d165 100644
--- a/app/soc/modules/seeder/logic/providers/email.py
+++ b/app/soc/modules/seeder/logic/providers/email.py
@@ -11,27 +11,22 @@
# 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.
-"""Module containing data providers for UserProperty.
-"""
+
+"""Module containing data providers for UserProperty."""
+
+from django.core.validators import email_re
from soc.modules.seeder.logic.providers.provider import BaseDataProvider
from soc.modules.seeder.logic.providers.provider import FixedValueProvider
from soc.modules.seeder.logic.providers.provider import ParameterValueError
-from django.core.validators import email_re
-
-# pylint: disable=W0223
class EmailProvider(BaseDataProvider):
- """Base class for all data providers that return an e-mail.
- """
-
- pass
+ """Base class for all data providers that return an e-mail."""
class FixedEmailProvider(EmailProvider, FixedValueProvider):
- """Data provider that returns a fixed e-mail.
- """
+ """Data provider that returns a fixed e-mail."""
def checkParameters(self):
super(FixedEmailProvider, self).checkParameters()
@@ -56,8 +51,7 @@
@staticmethod
def getRandomDomain():
- """Returns a random domain for a link
- """
+ """Returns a random domain for a link."""
#TODO(sttwister): Really return a random domain
return "gmail.com"
diff --git a/app/soc/modules/seeder/logic/providers/float.py b/app/soc/modules/seeder/logic/providers/float.py
index be50c82..1092a84 100644
--- a/app/soc/modules/seeder/logic/providers/float.py
+++ b/app/soc/modules/seeder/logic/providers/float.py
@@ -11,30 +11,23 @@
# 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.
-"""Module containing data providers for FloatProperty.
-"""
+"""Module containing data providers for FloatProperty."""
+
+import random
from soc.modules.seeder.logic.providers.provider import BaseDataProvider
from soc.modules.seeder.logic.providers.provider import DataProviderParameter
from soc.modules.seeder.logic.providers.provider import ParameterValueError
from soc.modules.seeder.logic.providers.provider import FixedValueProvider
-import random
-
-# pylint: disable=W0223
class FloatProvider(BaseDataProvider):
- """Base class for all data providers that return a float.
- """
-
- pass
+ """Base class for all data providers that return a float."""
-# pylint: disable=W0223
class FixedFloatProvider(FloatProvider, FixedValueProvider):
- """Data provider that returns a fixed float.
- """
+ """Data provider that returns a fixed float."""
def checkParameters(self):
super(FixedFloatProvider, self).checkParameters()
@@ -46,8 +39,7 @@
class RandomUniformDistributionFloatProvider(FloatProvider):
- """Returns a float sampled from an uniform distribution.
- """
+ """Returns a float sampled from an uniform distribution."""
DEFAULT_MIN = 0
DEFAULT_MAX = 10
diff --git a/app/soc/modules/seeder/logic/providers/integer.py b/app/soc/modules/seeder/logic/providers/integer.py
index 5179b51..dbb27c8 100644
--- a/app/soc/modules/seeder/logic/providers/integer.py
+++ b/app/soc/modules/seeder/logic/providers/integer.py
@@ -11,30 +11,25 @@
# 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.
-"""Module containing data providers for IntegerProperty.
-"""
+
+"""Module containing data providers for IntegerProperty."""
+
+import random
from google.appengine.api import memcache
+
from soc.modules.seeder.logic.providers.provider import BaseDataProvider
from soc.modules.seeder.logic.providers.provider import ParameterValueError
from soc.modules.seeder.logic.providers.provider import FixedValueProvider
from soc.modules.seeder.logic.providers.provider import DataProviderParameter
-import random
-
-# pylint: disable=W0223
class IntegerProvider(BaseDataProvider):
- """Base class for all data providers that return a integer.
- """
-
- pass
+ """Base class for all data providers that return a integer."""
-# pylint: disable=W0223
class FixedIntegerProvider(IntegerProvider, FixedValueProvider):
- """Data provider that returns a fixed integer.
- """
+ """Data provider that returns a fixed integer."""
def checkParameters(self):
super(FixedIntegerProvider, self).checkParameters()
@@ -44,10 +39,9 @@
except (TypeError, ValueError):
raise ParameterValueError('%s is not a valid integer' % value)
-# pylint: disable=W0622
+
class RandomUniformDistributionIntegerProvider(IntegerProvider):
- """Returns an integer sampled from an uniform distribution.
- """
+ """Returns an integer sampled from an uniform distribution."""
DEFAULT_MIN = 0
DEFAULT_MAX = 10
@@ -175,14 +169,12 @@
raise ParameterValueError('%s is not a valid integer for %s' %
(value, key))
-# pylint: disable=E1101
def getValue(self):
self.checkParameters()
key = self.param_values['name']
- data = memcache.get(key, self.MEMCACHE_NAMESPACE) #@UndefinedVariable
+ data = memcache.get(key, self.MEMCACHE_NAMESPACE)
if not data:
data = self.param_values.get('start', self.DEFAULT_START)
- memcache.set(key, data + self.DEFAULT_STEP, #@UndefinedVariable
+ memcache.set(key, data + self.DEFAULT_STEP,
namespace=self.MEMCACHE_NAMESPACE)
return data
-# pylint: enable=E1101
diff --git a/app/soc/modules/seeder/logic/providers/link.py b/app/soc/modules/seeder/logic/providers/link.py
index 4aaf8bf..e6bdb60 100644
--- a/app/soc/modules/seeder/logic/providers/link.py
+++ b/app/soc/modules/seeder/logic/providers/link.py
@@ -11,36 +11,26 @@
# 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.
-"""Module containing data providers for LinkProperty.
-"""
+"""Module containing data providers for LinkProperty."""
+
+import random
from soc.modules.seeder.logic.providers.provider import BaseDataProvider
from soc.modules.seeder.logic.providers.provider import FixedValueProvider
from soc.modules.seeder.logic.providers.string import RandomWordProvider
-import random
-
-# pylint: disable=W0223
class LinkProvider(BaseDataProvider):
- """Base class for all data providers that return a link.
- """
-
- pass
+ """Base class for all data providers that return a link."""
-# pylint: disable=W0223
class FixedLinkProvider(LinkProvider, FixedValueProvider):
- """Data provider that returns a fixed link.
- """
-
- pass
+ """Data provider that returns a fixed link."""
class RandomLinkProvider(LinkProvider, RandomWordProvider):
- """Data provider that returns a random link.
- """
+ """Data provider that returns a random link."""
def getValue(self):
link = 'http://www.'
diff --git a/app/soc/modules/seeder/logic/providers/list.py b/app/soc/modules/seeder/logic/providers/list.py
index 23bf44d..9dd4b91 100644
--- a/app/soc/modules/seeder/logic/providers/list.py
+++ b/app/soc/modules/seeder/logic/providers/list.py
@@ -11,28 +11,18 @@
# 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.
-"""Module containing data providers for ListProperty.
-"""
-_authors__ = [
- '"Felix Kerekes" <sttwister@gmail.com>',
- ]
-
+"""Module containing data providers for ListProperty."""
from soc.modules.seeder.logic.providers.provider import BaseDataProvider
-# pylint: disable=W0223
class ListProvider(BaseDataProvider):
- """Base class for all data providers that return a list.
- """
-
- pass
+ """Base class for all data providers that return a list."""
class EmptyListProvider(ListProvider):
- """Data provider that returns an empty.
- """
+ """Data provider that returns an empty."""
def getValue(self):
return []
diff --git a/app/soc/modules/seeder/logic/providers/phone_number.py b/app/soc/modules/seeder/logic/providers/phone_number.py
index 3fd377f..ef525f1 100644
--- a/app/soc/modules/seeder/logic/providers/phone_number.py
+++ b/app/soc/modules/seeder/logic/providers/phone_number.py
@@ -11,35 +11,25 @@
# 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.
-"""Module containing data providers for PhoneNumberProperty.
-"""
+"""Module containing data providers for PhoneNumberProperty."""
+
+import random
from soc.modules.seeder.logic.providers.provider import BaseDataProvider
from soc.modules.seeder.logic.providers.provider import FixedValueProvider
-import random
-
-# pylint: disable=W0223
class PhoneNumberProvider(BaseDataProvider):
- """Base class for all data providers that return a phone number.
- """
-
- pass
+ """Base class for all data providers that return a phone number."""
-# pylint: disable=W0223
class FixedPhoneNumberProvider(PhoneNumberProvider, FixedValueProvider):
- """Data provider that returns a fixed phone number.
- """
-
- pass
+ """Data provider that returns a fixed phone number."""
class RandomPhoneNumberProvider(PhoneNumberProvider):
- """Data provider that returns a random phone number.
- """
+ """Data provider that returns a random phone number."""
def getValue(self):
return ''.join(str(random.randint(0, 9)) for _ in range(10))
diff --git a/app/soc/modules/seeder/logic/providers/provider.py b/app/soc/modules/seeder/logic/providers/provider.py
index 507d82c..e75d6cd 100644
--- a/app/soc/modules/seeder/logic/providers/provider.py
+++ b/app/soc/modules/seeder/logic/providers/provider.py
@@ -11,35 +11,26 @@
# 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.
-"""Module containing basic data provider classes.
-"""
+
+"""Module containing basic data provider classes."""
class Error(Exception):
- """Error class for the data provider module.
- """
-
- pass
+ """Error class for the data provider module."""
class MissingParameterError(Error):
- """Error raised when a required parameter is missing.
- """
-
- pass
+ """Error raised when a required parameter is missing."""
+# TODO(nathaniel): Replace all occurrences of this with Python's
+# built-in TypeError.
class ParameterValueError(Error):
- """Error raised when a parameter is not of the expected type.
- """
-
- pass
+ """Error raised when a parameter is not of the expected type."""
-# pylint: disable=R0903
class DataProviderParameter(object):
- """Holds information about a data provider parameters
- """
+ """Holds information about a data provider parameters."""
def __init__(self, name, verbose_name, description, required=False):
self.name = name
@@ -48,10 +39,8 @@
self.required = required
-# pylint: disable=R0922
class BaseDataProvider(object):
- """Base class for all data providers.
- """
+ """Base class for all data providers."""
def __init__(self, **param_values):
"""Constructor for the base data provider.
@@ -62,34 +51,28 @@
self.param_values = param_values
def getValue(self):
- """Returns a value from the data provider.
- """
+ """Returns a value from the data provider."""
raise NotImplementedError
@classmethod
def getParametersList(cls):
- """Returns a list of accepted parameters.
- """
+ """Returns a list of accepted parameters."""
return []
@classmethod
def hasParameter(cls, param_name):
- """Checks whether this data provider has a parameter named param_name.
- """
+ """Checks whether this data provider has a parameter named param_name."""
return param_name in (param.name for param in cls.getParametersList())
def checkParameters(self):
- """Checks that all required parameters are supplied.
- """
-
+ """Checks that all required parameters are supplied."""
for param in self.getParametersList():
if param.required and param.name not in self.param_values:
raise MissingParameterError('Parameter "%s" is missing.' % param.name)
class FixedValueProvider(BaseDataProvider):
- """Data provider interface for providing a fixed value.
- """
+ """Data provider interface for providing a fixed value."""
@classmethod
def getParametersList(cls):
diff --git a/app/soc/modules/seeder/logic/providers/string.py b/app/soc/modules/seeder/logic/providers/string.py
index e8e2f1d..d374c65 100644
--- a/app/soc/modules/seeder/logic/providers/string.py
+++ b/app/soc/modules/seeder/logic/providers/string.py
@@ -22,20 +22,12 @@
from soc.modules.seeder.logic.providers.provider import ParameterValueError
-# pylint: disable=W0223
class StringProvider(BaseDataProvider):
- """Base class for all data providers that return a string.
- """
-
- pass
+ """Base class for all data providers that return a string."""
-# pylint: disable=W0223
class FixedStringProvider(StringProvider, FixedValueProvider):
- """Data provider that returns a fixed string.
- """
-
- pass
+ """Data provider that returns a fixed string."""
class FixedLengthAscendingNumericStringProvider(StringProvider):
diff --git a/app/soc/modules/seeder/logic/providers/text.py b/app/soc/modules/seeder/logic/providers/text.py
index 2c67b68..65608ba 100644
--- a/app/soc/modules/seeder/logic/providers/text.py
+++ b/app/soc/modules/seeder/logic/providers/text.py
@@ -11,27 +11,21 @@
# 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.
-"""Module containing data providers for TextProperty.
-"""
+"""Module containing data providers for TextProperty."""
+
+import random
from soc.modules.seeder.logic.providers.string import StringProvider
from soc.modules.seeder.logic.providers.string import RandomPhraseProvider
-import random
-
-# pylint: disable=W0223
class TextProvider(StringProvider):
- """Base class for all data providers that return text.
- """
-
- pass
+ """Base class for all data providers that return text."""
class RandomParagraphProvider(TextProvider, RandomPhraseProvider):
- """Data provider that returns a random paragraph.
- """
+ """Data provider that returns a random paragraph."""
def getValue(self):
return ' '.join(RandomPhraseProvider.getValue(self)
@@ -39,8 +33,7 @@
class RandomPlainTextDocumentProvider(RandomParagraphProvider):
- """Data provider that returns a random plain text document.
- """
+ """Data provider that returns a random plain text document."""
def getValue(self):
return '\n\n'.join(RandomParagraphProvider.getValue(self)
@@ -48,8 +41,7 @@
class RandomHtmlDocumentProvider(RandomParagraphProvider):
- """Data provider that returns a random HTML document.
- """
+ """Data provider that returns a random HTML document."""
def getValue(self):
#TODO(sttwister): This could be improved
@@ -62,8 +54,7 @@
class RandomMarkdownDocumentProvider(RandomParagraphProvider):
- """Data provider that returns a random Markdown document.
- """
+ """Data provider that returns a random Markdown document."""
def getValue(self):
#TODO(sttwister): This could be improved
diff --git a/app/soc/modules/seeder/logic/providers/user.py b/app/soc/modules/seeder/logic/providers/user.py
index c2609d9..e0c5e8a 100644
--- a/app/soc/modules/seeder/logic/providers/user.py
+++ b/app/soc/modules/seeder/logic/providers/user.py
@@ -11,9 +11,8 @@
# 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.
-"""Module containing data providers for UserProperty.
-"""
+"""Module containing data providers for UserProperty."""
from google.appengine.api import users
@@ -22,34 +21,25 @@
from soc.modules.seeder.logic.providers.email import UniqueEmailProvider
-
-# pylint: disable=W0223
class UserProvider(BaseDataProvider):
- """Base class for all data providers that return an e-mail.
- """
-
- pass
+ """Base class for all data providers that return an e-mail."""
class CurrentUserProvider(UserProvider):
- """Data provider that returns the currently logged in user.
- """
+ """Data provider that returns the currently logged in user."""
def getValue(self):
return users.User()
class FixedUserProvider(FixedEmailProvider):
- """Data provider that returns a fixed user.
- """
+ """Data provider that returns a fixed user."""
def getValue(self):
return users.User(super(FixedUserProvider, self).getValue())
-# pylint: disable=R0901
class RandomUserProvider(UniqueEmailProvider):
- """Data provider that returns a random user.
- """
+ """Data provider that returns a random user."""
def getValue(self):
return users.User(super(RandomUserProvider, self).getValue())
diff --git a/app/soc/modules/seeder/logic/seeder.py b/app/soc/modules/seeder/logic/seeder.py
index a236b3e..4028581 100644
--- a/app/soc/modules/seeder/logic/seeder.py
+++ b/app/soc/modules/seeder/logic/seeder.py
@@ -11,8 +11,8 @@
# 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.
-"""Logic for data seeding operations.
-"""
+
+"""Logic for data seeding operations."""
import json
import random
@@ -238,9 +238,7 @@
values[str(property_name)] = value
- # pylint: disable=W0142
model = model_class(**values)
- # pylint: enable=W0142
return model
def processReferences(self, model_data):
@@ -291,9 +289,7 @@
related_models = self.seedModel(provider_data['parameters'])
for related_model in related_models:
back_reference_property = getattr(model_class, property_name)
- # pylint: disable=W0212
setattr(related_model, back_reference_property._prop_name, model)
- # pylint: enable=W0212
related_model.put()
models.append(model)
diff --git a/app/summerofcode/views/org_app.py b/app/summerofcode/views/org_app.py
index 46241ee..d9a54c6 100644
--- a/app/summerofcode/views/org_app.py
+++ b/app/summerofcode/views/org_app.py
@@ -694,8 +694,10 @@
"""View to submit application to a program by organization representatives."""
access_checker = access.ConjuctionAccessChecker([
- access.NON_STUDENT_PROFILE_ACCESS_CHECKER,
- access.ORG_SIGNUP_ACTIVE_ACCESS_CHECKER])
+ access.IS_USER_ORG_ADMIN_FOR_NDB_ORG,
+ access.UrlOrgStatusAccessChecker(
+ [org_model.Status.APPLYING, org_model.Status.PRE_ACCEPTED,
+ org_model.Status.PRE_REJECTED])])
def djangoURLPatterns(self):
"""See base.RequestHandler.djangoURLPatterns for specification."""
diff --git a/tests/app/soc/modules/gci/logic/test_conversation.py b/tests/app/soc/modules/gci/logic/test_conversation.py
index c6e2398..19f95a6 100644
--- a/tests/app/soc/modules/gci/logic/test_conversation.py
+++ b/tests/app/soc/modules/gci/logic/test_conversation.py
@@ -639,16 +639,22 @@
but no longer should be.
"""
+ # Create a couple dummy organizations
+ org_keys = map(
+ lambda org: ndb.Key.from_old_key(org.key()),
+ (program_utils.seedOldOrganization(self.conv_utils.program_key)
+ for _ in range(2)))
+
# Create dummy admins, mentors, and students, some hybrid users, and a
# conversation creator
creator = self.conv_utils.createUser(return_key=True)
dummy_admin_keys = list(
self.conv_utils.createUser(
- return_key=True,
+ return_key=True, admin_organizations=org_keys,
roles=[conversation_utils.ADMIN]) for _ in range(2))
dummy_mentor_keys = list(
self.conv_utils.createUser(
- return_key=True,
+ return_key=True, mentor_organizations=org_keys,
roles=[conversation_utils.MENTOR]) for _ in range(2))
dummy_student_keys = list(
self.conv_utils.createUser(
@@ -656,12 +662,12 @@
roles=[conversation_utils.STUDENT]) for _ in range(2))
dummy_mentor_student_keys = list(
self.conv_utils.createUser(
- return_key=True,
+ return_key=True, mentor_organizations=org_keys,
roles=[conversation_utils.STUDENT, conversation_utils.MENTOR])
for _ in range(2))
dummy_winner_keys = list(
self.conv_utils.createUser(
- return_key=True,
+ return_key=True, winning_organization=org_keys[0],
roles=[conversation_utils.STUDENT, conversation_utils.WINNER])
for _ in range(2))
@@ -846,7 +852,7 @@
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,
+ return_key=True, mentor_organizations=[org_keys[0], org_keys[1]],
roles=[conversation_utils.MENTOR, conversation_utils.STUDENT])
user_winner_key = self.conv_utils.createUser(
return_key=True, winning_organization=org_keys[1],
@@ -934,13 +940,14 @@
# Refresh each user's conversations
gciconversation_logic.refreshConversationsForUserAndProgram(
- user=user_admin_key, program=self.program_key)
+ user_admin_key, self.program_key)
gciconversation_logic.refreshConversationsForUserAndProgram(
- user=user_mentor_key, program=self.program_key)
+ user_mentor_key, self.program_key)
+
gciconversation_logic.refreshConversationsForUserAndProgram(
- user=user_mentor_student_key, program=self.program_key)
+ user_mentor_student_key, self.program_key)
gciconversation_logic.refreshConversationsForUserAndProgram(
- user=user_winner_key, program=self.program_key)
+ 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])
@@ -959,7 +966,8 @@
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])
+ expected_keys = set(
+ [conv_a.key, conv_c.key, conv_d.key, conv_e.key, conv_f.key])
actual_keys = set(map(
lambda conv_user: conv_user.conversation,
gciconversation_logic.queryForProgramAndUser(
@@ -1046,13 +1054,13 @@
# all conversations, refreshing each user should actually remove them from
# conversations they don't belong to.
gciconversation_logic.refreshConversationsForUserAndProgram(
- user=user_admin_key, program=self.program_key)
+ user_admin_key, self.program_key)
gciconversation_logic.refreshConversationsForUserAndProgram(
- user=user_mentor_key, program=self.program_key)
+ user_mentor_key, self.program_key)
gciconversation_logic.refreshConversationsForUserAndProgram(
- user=user_mentor_student_key, program=self.program_key)
+ user_mentor_student_key, self.program_key)
gciconversation_logic.refreshConversationsForUserAndProgram(
- user=user_winner_key, program=self.program_key)
+ 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])
@@ -1072,7 +1080,8 @@
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])
+ expected_keys = set(
+ [conv_a.key, conv_c.key, conv_d.key, conv_e.key, conv_f.key])
actual_keys = set(map(
lambda conv_user: conv_user.conversation,
gciconversation_logic.queryForProgramAndUser(
@@ -1088,6 +1097,7 @@
program=self.program_key, user=user_winner_key)))
self.assertEqual(expected_keys, actual_keys)
+ @unittest.skip('emails must be taken from profiles')
def testGetSubscribedEmails(self):
"""Tests that getSubscribedEmails correctly returns email addresses of
users subscribed to a conversation.
@@ -1131,6 +1141,7 @@
self.conv_b.key, exclude=[self.user_keys[2]]))
self.assertEqual(expected, actual)
+ @unittest.skip('emails must be taken from profiles')
def testNotifyParticipantsOfMessage(self):
"""Tests that notifyParticipantsOfMessage sends the correct email
notification to subscribed recipients of a conversation for a message.
@@ -1138,30 +1149,28 @@
# Create a few users with unique email addresses
email_a = 'a@example.net'
user_a = self.conv_utils.createUser(email=email_a)
- user_a_key = ndb.Key.from_old_key(user_a.key())
self.conv_utils.addUser(
- conversation=self.conv_a.key, user=user_a_key,
+ conversation=self.conv_a.key, user=user_a.key,
enable_notifications=False)
self.conv_utils.addUser(
- conversation=self.conv_b.key, user=user_a_key,
+ conversation=self.conv_b.key, user=user_a.key,
enable_notifications=False)
# Add another new user to the two conversations with notifications enabled
email_b = 'b@example.net'
user_b = self.conv_utils.createUser(email=email_b)
- user_b_key = ndb.Key.from_old_key(user_b.key())
self.conv_utils.addUser(
- conversation=self.conv_a.key, user=user_b_key,
+ conversation=self.conv_a.key, user=user_b.key,
enable_notifications=True)
self.conv_utils.addUser(
- conversation=self.conv_b.key, user=user_b_key,
+ conversation=self.conv_b.key, user=user_b.key,
enable_notifications=True)
# Add a new message and send an email notification for it as if it were the
# first message.
content = 'Hello universe?'
message = self.conv_utils.addMessage(
- self.conv_a.key, user=user_b_key, content=content)
+ self.conv_a.key, user=user_b.key, content=content)
gciconversation_logic.notifyParticipantsOfMessage(
message.key, False)
@@ -1189,7 +1198,7 @@
# reply
content = 'The universe is busy at the moment. Please check back later.'
message = self.conv_utils.addMessage(
- self.conv_a.key, user=user_a_key, content=content)
+ self.conv_a.key, user=user_a.key, content=content)
gciconversation_logic.notifyParticipantsOfMessage(
message.key, True)
diff --git a/tests/utils/conversation_utils.py b/tests/utils/conversation_utils.py
index 33af3c2..cf75c0c 100644
--- a/tests/utils/conversation_utils.py
+++ b/tests/utils/conversation_utils.py
@@ -216,11 +216,10 @@
See ConversationHelper.createUser for full specification.
"""
- program_ent = db.get(ndb.Key.to_old_key(self.program_key))
- profile_helper = profile_utils.GCIProfileHelper(program_ent, False)
+ program = db.get(ndb.Key.to_old_key(self.program_key))
roles = set(roles) if roles else set()
- profile = profile_helper.createProfile()
+ profile = profile_utils.seedNDBProfile(program.key())
winner_for = None
if profile is None:
@@ -231,27 +230,20 @@
if mentor_organizations:
roles.update([MENTOR])
- profile.mentor_for = map(ndb.Key.to_old_key, mentor_organizations)
+ profile.mentor_for = mentor_organizations
if admin_organizations:
roles.update([ADMIN])
- profile.org_admin_for = map(ndb.Key.to_old_key, admin_organizations)
+ profile.admin_for = admin_organizations
if winning_organization:
roles.update([WINNER])
- winner_for = ndb.Key.to_old_key(winning_organization)
+ winner_for = winning_organization
- profile.is_mentor = MENTOR in roles
- profile.is_org_admin = ADMIN in roles
- profile.is_student = STUDENT in roles
+ if winner_for or WINNER in roles or STUDENT in roles:
+ profile.student_data = profile_utils.seedStudentData(
+ winner_for=winner_for)
profile.put()
- if winner_for or WINNER in roles:
- profile_helper.createStudent(
- is_winner=WINNER in roles, winner_for=winner_for)
-
- if return_key:
- return ndb.Key.from_old_key(profile_helper.user.key())
- else:
- return profile_helper.user
+ return profile.key.parent() if return_key else profile.key.parent().get()