def updateOrCreateRecordsFor(survey_group, projects): """Updates or creates GradingRecords in batch. Args: survey_group: GradingSurveyGroup entity projects: list of GSoCProjects which to process Returns: The list of updated and new records. """ records = [] for project in projects: q = GSoCGradingRecord.all() q.filter('grading_survey_group', survey_group) q.ancestor(project) # try to retrieve an existing record record = q.get() # retrieve the fields that should be set record_fields = getFieldsForGradingRecord(project, survey_group, record) if not record and project.status in ['failed', 'invalid'] \ and not record_fields['mentor_record'] \ and not record_fields['student_record']: # Don't create a new GradingRecord for an already failed project which # has no records attached. Because it does not matter. continue if record: # update existing GradingRecord for key, value in record_fields.iteritems(): setattr(record, key, value) else: # create a new GradingRecord record = GSoCGradingRecord(parent=project, **record_fields) # prepare the new/updated record for storage records.append(record) db.put(records) return records
def createSurveys(self): """Creates the surveys and records required for the tests. """ survey_values = { 'author': self.founder, 'title': 'Title', 'modified_by': self.founder, 'link_id': 'link_id', 'scope': self.gsoc, 'scope_path': self.gsoc.key().id_or_name()} self.project_survey = ProjectSurvey(key_name='key_name', **survey_values) self.project_survey.put() self.grading_survey = GradingProjectSurvey(key_name='key_name', **survey_values) self.grading_survey.put() record_values = { 'user': self.student.user, 'org': self.org, 'project': self.project, 'survey': self.project_survey} self.project_survey_record = GSoCProjectSurveyRecord(**record_values) self.project_survey_record.put() self.grading_survey = GradingProjectSurvey(**survey_values) self.grading_survey.put() record_values = { 'user': self.student.user, 'org': self.org, 'project': self.project, 'survey': self.grading_survey, 'grade': True} self.grading_survey_record = GSoCGradingProjectSurveyRecord( **record_values) self.grading_survey_record.put() group_values = { 'name': 'Survey Group Name', 'grading_survey': self.grading_survey, 'student_survey': self.project_survey, 'program': self.gsoc} self.survey_group = GSoCGradingSurveyGroup(**group_values) self.survey_group.put() record_values = { 'grading_survey_group': self.survey_group, 'mentor_record': self.grading_survey_record, 'student_record': self.project_survey_record, 'grade_decision': 'pass'} self.grading_record = GSoCGradingRecord(parent=self.project, **record_values) self.grading_record.put()
def listContent(self): """Returns the ListContentResponse object that is constructed from the data. """ q = GSoCGradingRecord.all() q.filter('grading_survey_group', self.data.survey_group) starter = lists.keyStarter prefetcher = GradingRecordsList.ListPrefetcher() response_builder = lists.RawQueryContentResponseBuilder( self.data.request, self._list_config, q, starter, prefetcher=prefetcher) return response_builder.build()
def listContent(self): """Returns the ListContentResponse object that is constructed from the data. """ q = GSoCGradingRecord.all() q.filter('grading_survey_group', self.data.survey_group) starter = lists.keyStarter prefetcher = lists.modelPrefetcher( GSoCGradingRecord, ['mentor_record', 'student_record'], parent=True) response_builder = lists.RawQueryContentResponseBuilder( self.request, self._list_config, q, starter, prefetcher=prefetcher) return response_builder.build()
def testCreateGradingRecord(self): """Test creating a GradingRecord. """ self.grading_record.delete() post_data = {'group_key': self.survey_group.key().id_or_name()} response = self.post(self.UPDATE_RECORDS_URL, post_data) self.assertEqual(response.status_code, httplib.OK) self.assertTasksInQueue(n=1, url=self.UPDATE_RECORDS_URL) record = GSoCGradingRecord.all().get() self.assertFalse(record is None) self.assertEqual(record.grade_decision, 'pass')
def gradingSurveyRecordFromKwargs(self): """Sets a GradingSurveyRecord entry in the RequestData object. """ if not ('group' in self.data.kwargs and 'id' in self.data.kwargs): raise exception.BadRequest(message=access_checker.DEF_NOT_VALID_REQUEST) # url regexp ensures that it is a digit record_id = long(self.data.kwargs['record']) group_id = long(self.data.kwargs['group']) record = GSoCGradingRecord.get_by_id( record_id, parent=self.data.url_project) if not record or record.grading_survey_group.key().id() != group_id: raise exception.NotFound(message=DEF_NO_RECORD_FOUND) self.data.record = record
def testCreateGradingRecord(self): """Test creating a GradingRecord. """ self.grading_record.delete() post_data = { 'group_key': self.survey_group.key().id_or_name() } response = self.post(self.UPDATE_RECORDS_URL, post_data) self.assertEqual(response.status_code, httplib.OK) self.assertTasksInQueue(n=1, url=self.UPDATE_RECORDS_URL) record = GSoCGradingRecord.all().get() self.assertFalse(record is None) self.assertEqual(record.grade_decision, 'pass')
def updateOrCreateRecordsFor(survey_group, projects): """Updates or creates GradingRecords in batch. Args: survey_group: GradingSurveyGroup entity projects: list of GSoCProjects which to process Returns: The list of updated and new records. """ records = [] for project in projects: q = GSoCGradingRecord.all() q.filter('grading_survey_group', survey_group) q.ancestor(project) # try to retrieve an existing record record = q.get() # retrieve the fields that should be set record_fields = getFieldsForGradingRecord( project, survey_group, record) if not record and project.status in ['failed', 'invalid'] \ and not record_fields['mentor_record'] \ and not record_fields['student_record']: # Don't create a new GradingRecord for an already failed project which # has no records attached. Because it does not matter. continue if record: # update existing GradingRecord for key, value in record_fields.iteritems(): setattr(record, key, value) else: # create a new GradingRecord record = GSoCGradingRecord(parent=project, **record_fields) # prepare the new/updated record for storage records.append(record) db.put(records) return records
def gradingSurveyRecordFromKwargs(self): """Sets a GradingSurveyRecord entry in the RequestData object. """ if not ('group' in self.data.kwargs and 'id' in self.data.kwargs): raise exception.BadRequest( message=access_checker.DEF_NOT_VALID_REQUEST) # url regexp ensures that it is a digit record_id = long(self.data.kwargs['record']) group_id = long(self.data.kwargs['group']) record = GSoCGradingRecord.get_by_id(record_id, parent=self.data.url_project) if not record or record.grading_survey_group.key().id() != group_id: raise exception.NotFound(message=DEF_NO_RECORD_FOUND) self.data.record = record
def updateProjectsForSurveyGroup(self, request, *args, **kwargs): """Updates each StudentProject for which a GradingRecord is found. Expects the following to be present in the POST dict: group_key: Specifies the GradingSurveyGroup key name. cursor: Optional, specifies the cursor for the GadingRecord query. send_mail: Optional, if this string evaluates to True mail will be send for each GradingRecord that's processed. Args: request: Django Request object """ post_dict = request.POST group_key = post_dict.get('group_key') if not group_key: # invalid task data, log and return OK return error_handler.logErrorAndReturnOK( 'Invalid updateRecordForSurveyGroup data: %s' % post_dict) # get the GradingSurveyGroup for the given keyname survey_group = GSoCGradingSurveyGroup.get_by_id(int(group_key)) if not survey_group: # invalid GradingSurveyGroup specified, log and return OK return error_handler.logErrorAndReturnOK( 'Invalid GradingSurveyGroup specified: %s' % group_key) q = GSoCGradingRecord.all() q.filter('grading_survey_group', survey_group) if 'cursor' in post_dict: q.with_cursor(post_dict['cursor']) # get the first batch_size number of GradingRecords records = q.fetch(self.DEF_BATCH_SIZE) if not records: # we are done return http.HttpResponse() grading_record.updateProjectsForGradingRecords(records) # check if we need to send an email for each GradingRecord send_mail = post_dict.get('send_mail', '') if send_mail: # enqueue a task to send mail for each GradingRecord for record in records: # pass along these params as POST to the new task task_params = {'record_key': str(record.key())} task_url = '/tasks/gsoc/grading_record/mail_result' mail_task = taskqueue.Task(params=task_params, url=task_url) mail_task.add('mail') # pass along these params as POST to the new task task_params = {'group_key': group_key, 'cursor': q.cursor(), 'send_mail': send_mail} new_task = taskqueue.Task(params=task_params, url=request.path) new_task.add() # task completed, return OK return http.HttpResponse('OK')
def convertGSoCProfileDBEntityGroup(profile_key): """Converts DB based part of entity group associated with the specified profile. Args: profile_key: db.Key of the profile to process """ # map that associate old keys with new ones which are created during # the conversion conversion_map = {} to_delete = [] do_put = True proposals = GSoCProposal.all().ancestor(profile_key).fetch(1000) for proposal in proposals: # update GSoCProposal.parent new_proposal = _convertParent(proposal) # update GSoCProposal.possible_mentors new_proposal.possible_mentors = _convertListProperty( GSoCProposal.possible_mentors, new_proposal) # update GSoCProposal.mentor new_proposal.mentor = _convertReferenceProperty( GSoCProposal.mentor, new_proposal) to_delete.append(proposal) if do_put: new_proposal.put() conversion_map[proposal.key()] = new_proposal.key() comments = GSoCComment.all().ancestor(proposal).fetch(1000) for comment in comments: # update GSoCComment.parent new_comment = _convertParent(comment, parent=new_proposal.key()) # update GSoCComment.author new_comment.author = _convertReferenceProperty( GSoCComment.author, new_comment) if do_put: new_comment.put() to_delete.append(comment) scores = GSoCScore.all().ancestor(proposal).fetch(1000) for score in scores: # update GSoCScore.parent new_score = _convertParent(score, parent=new_proposal.key()) # update GSoCScore.author new_score.author = _convertReferenceProperty(GSoCScore.author, new_score) if do_put: new_score.put() to_delete.append(score) projects = GSoCProject.all().ancestor(profile_key).fetch(1000) for project in projects: # update GSoCProject.parent new_project = _convertParent(project) # update GSoCProject.mentors new_project.mentors = _convertListProperty(GSoCProject.mentors, new_project) # update GSoCProject.proposal proposal_key = GSoCProject.proposal.get_value_for_datastore(project) if proposal_key: new_project.proposal = conversion_map.get( GSoCProject.proposal.get_value_for_datastore(project)) if do_put: new_project.put() conversion_map[project.key()] = new_project.key() to_delete.append(project) grading_records = GSoCGradingRecord.all().ancestor(project.key()) for grading_record in grading_records: # update GSoCGradingProjectSurveyRecord.project # this is another entity group, but XG transaction does the thing grading_project_survey_record_key = ( GSoCGradingRecord.mentor_record.get_value_for_datastore( grading_record)) if grading_project_survey_record_key: grading_project_survey_record = GSoCGradingProjectSurveyRecord.get( grading_project_survey_record_key) if grading_project_survey_record: grading_project_survey_record.project = new_project.key() if do_put: grading_project_survey_record.put() # update GSoCProjectSurveyRecord.project # this is another entity group, but XG transaction does the thing project_survey_record_key = ( GSoCGradingRecord.student_record.get_value_for_datastore( grading_record)) if project_survey_record_key: project_survey_record = GSoCProjectSurveyRecord.get( project_survey_record_key) if project_survey_record: project_survey_record.project = new_project.key() if do_put: project_survey_record.put() # update GSoCGradingRecord.parent new_grading_record = _convertParent( grading_record, parent=new_project.key()) if do_put: new_grading_record.put() code_samples = GSoCCodeSample.all().ancestor(project.key()) for code_sample in code_samples: # update GSoCCodeSample.parent new_code_sample = _convertParent(code_sample, parent=new_project.key()) if do_put: new_code_sample.put() to_delete.append(code_sample) db.delete(to_delete)
def convertGSoCProfileDBEntityGroup(profile_key): """Converts DB based part of entity group associated with the specified profile. Args: profile_key: db.Key of the profile to process """ # map that associate old keys with new ones which are created during # the conversion conversion_map = {} to_delete = [] do_put = True proposals = GSoCProposal.all().ancestor(profile_key).fetch(1000) for proposal in proposals: # update GSoCProposal.parent new_proposal = _convertParent(proposal) # update GSoCProposal.possible_mentors new_proposal.possible_mentors = _convertListProperty( GSoCProposal.possible_mentors, new_proposal) # update GSoCProposal.mentor new_proposal.mentor = _convertReferenceProperty( GSoCProposal.mentor, new_proposal) to_delete.append(proposal) if do_put: new_proposal.put() conversion_map[proposal.key()] = new_proposal.key() comments = GSoCComment.all().ancestor(proposal).fetch(1000) for comment in comments: # update GSoCComment.parent new_comment = _convertParent(comment, parent=new_proposal.key()) # update GSoCComment.author new_comment.author = _convertReferenceProperty( GSoCComment.author, new_comment) if do_put: new_comment.put() to_delete.append(comment) scores = GSoCScore.all().ancestor(proposal).fetch(1000) for score in scores: # update GSoCScore.parent new_score = _convertParent(score, parent=new_proposal.key()) # update GSoCScore.author new_score.author = _convertReferenceProperty( GSoCScore.author, new_score) if do_put: new_score.put() to_delete.append(score) projects = GSoCProject.all().ancestor(profile_key).fetch(1000) for project in projects: # update GSoCProject.parent new_project = _convertParent(project) # update GSoCProject.mentors new_project.mentors = _convertListProperty(GSoCProject.mentors, new_project) # update GSoCProject.proposal proposal_key = GSoCProject.proposal.get_value_for_datastore(project) if proposal_key: new_project.proposal = conversion_map.get( GSoCProject.proposal.get_value_for_datastore(project)) if do_put: new_project.put() conversion_map[project.key()] = new_project.key() to_delete.append(project) grading_records = GSoCGradingRecord.all().ancestor(project.key()) for grading_record in grading_records: # update GSoCGradingProjectSurveyRecord.project # this is another entity group, but XG transaction does the thing grading_project_survey_record_key = ( GSoCGradingRecord.mentor_record.get_value_for_datastore( grading_record)) if grading_project_survey_record_key: grading_project_survey_record = GSoCGradingProjectSurveyRecord.get( grading_project_survey_record_key) if grading_project_survey_record: grading_project_survey_record.project = new_project.key() if do_put: grading_project_survey_record.put() # update GSoCProjectSurveyRecord.project # this is another entity group, but XG transaction does the thing project_survey_record_key = ( GSoCGradingRecord.student_record.get_value_for_datastore( grading_record)) if project_survey_record_key: project_survey_record = GSoCProjectSurveyRecord.get( project_survey_record_key) if project_survey_record: project_survey_record.project = new_project.key() if do_put: project_survey_record.put() # update GSoCGradingRecord.parent new_grading_record = _convertParent(grading_record, parent=new_project.key()) if do_put: new_grading_record.put() code_samples = GSoCCodeSample.all().ancestor(project.key()) for code_sample in code_samples: # update GSoCCodeSample.parent new_code_sample = _convertParent(code_sample, parent=new_project.key()) if do_put: new_code_sample.put() to_delete.append(code_sample) db.delete(to_delete)
def sendMailAboutGradingRecordResult(self, request, *args, **kwargs): """Sends out a mail about the result of one GradingRecord. Expects the following to be present in the POST dict: record_key: Specifies the key for the record to process. Args: request: Django Request object """ post_dict = request.POST record_key = post_dict.get('record_key') if not record_key: # no GradingRecord key specified, log and return OK error_handler.logErrorAndReturnOK( 'No valid record_key specified in POST data: %s' % request.POST) record = GSoCGradingRecord.get(db.Key(record_key)) if not record: # no valid GradingRecord key specified, log and return OK error_handler.logErrorAndReturnOK( 'No valid GradingRecord key specified: %s' % record_key) survey_group_entity = record.grading_survey_group project_entity = record.parent() student_entity = project_entity.parent() org_entity = project_entity.org site_entity = site.singleton() mail_context = { 'survey_group': survey_group_entity, 'grading_record': record, 'project': project_entity, 'organization': org_entity, 'site_name': site_entity.site_name, 'to_name': student_entity.name() } # set the sender (_, sender_address) = mail_dispatcher.getDefaultMailSender() mail_context['sender'] = sender_address # set the receiver and subject mail_context['to'] = student_entity.email mail_context['cc'] = [] mail_context['subject'] = '%s results processed for %s' %( survey_group_entity.name, project_entity.title) q = GSoCProfile.all() q.filter('org_admin_for', org_entity) org_admins = q.fetch(1000) # collect all mentors mentors = db.get(project_entity.mentors) # add them all to the cc list for org_member in org_admins + mentors: mail_context['cc'].append(org_member.email) # send out the email using a template mail_template = 'modules/gsoc/grading_record/mail/result.html' mail_dispatcher.sendMailFromTemplate(mail_template, mail_context) # return OK return http.HttpResponse()
def createSurveys(self): """Creates the surveys and records required for the tests. """ survey_values = { 'author': self.founder, 'title': 'Title', 'modified_by': self.founder, 'link_id': 'link_id', 'scope': self.gsoc, 'scope_path': self.gsoc.key().id_or_name() } self.project_survey = ProjectSurvey(key_name='key_name', **survey_values) self.project_survey.put() self.grading_survey = GradingProjectSurvey(key_name='key_name', **survey_values) self.grading_survey.put() record_values = { 'user': self.student.user, 'org': self.org, 'project': self.project, 'survey': self.project_survey } self.project_survey_record = GSoCProjectSurveyRecord(**record_values) self.project_survey_record.put() self.grading_survey = GradingProjectSurvey(**survey_values) self.grading_survey.put() record_values = { 'user': self.student.user, 'org': self.org, 'project': self.project, 'survey': self.grading_survey, 'grade': True } self.grading_survey_record = GSoCGradingProjectSurveyRecord( **record_values) self.grading_survey_record.put() group_values = { 'name': 'Survey Group Name', 'grading_survey': self.grading_survey, 'student_survey': self.project_survey, 'program': self.gsoc } self.survey_group = GSoCGradingSurveyGroup(**group_values) self.survey_group.put() record_values = { 'grading_survey_group': self.survey_group, 'mentor_record': self.grading_survey_record, 'student_record': self.project_survey_record, 'grade_decision': 'pass' } self.grading_record = GSoCGradingRecord(parent=self.project, **record_values) self.grading_record.put()
class GradingSurveyGroupTest(MailTestCase, GSoCDjangoTestCase, TaskQueueTestCase): """Tests for accept_proposals task. """ UPDATE_RECORDS_URL = '/tasks/gsoc/grading_record/update_records' UPDATE_PROJECTS_URL = '/tasks/gsoc/grading_record/update_projects' SEND_URL = '/tasks/gsoc/grading_record/mail_result' def setUp(self): super(GradingSurveyGroupTest, self).setUp() self.init() self.createMentor() self.createStudent() self.createSurveys() def createMentor(self): """Creates a new mentor. """ profile_helper = GSoCProfileHelper(self.gsoc, self.dev_test) profile_helper.createOtherUser('*****@*****.**') self.mentor = profile_helper.createMentor(self.org) def createStudent(self): """Creates a Student with a project. """ profile_helper = GSoCProfileHelper(self.gsoc, self.dev_test) profile_helper.createOtherUser('*****@*****.**') self.student = profile_helper.createStudentWithProject( self.org, self.mentor) self.project = GSoCProject.all().ancestor(self.student).get() def createSurveys(self): """Creates the surveys and records required for the tests. """ survey_values = { 'author': self.founder, 'title': 'Title', 'modified_by': self.founder, 'link_id': 'link_id', 'scope': self.gsoc, 'scope_path': self.gsoc.key().id_or_name() } self.project_survey = ProjectSurvey(key_name='key_name', **survey_values) self.project_survey.put() self.grading_survey = GradingProjectSurvey(key_name='key_name', **survey_values) self.grading_survey.put() record_values = { 'user': self.student.user, 'org': self.org, 'project': self.project, 'survey': self.project_survey } self.project_survey_record = GSoCProjectSurveyRecord(**record_values) self.project_survey_record.put() self.grading_survey = GradingProjectSurvey(**survey_values) self.grading_survey.put() record_values = { 'user': self.student.user, 'org': self.org, 'project': self.project, 'survey': self.grading_survey, 'grade': True } self.grading_survey_record = GSoCGradingProjectSurveyRecord( **record_values) self.grading_survey_record.put() group_values = { 'name': 'Survey Group Name', 'grading_survey': self.grading_survey, 'student_survey': self.project_survey, 'program': self.gsoc } self.survey_group = GSoCGradingSurveyGroup(**group_values) self.survey_group.put() record_values = { 'grading_survey_group': self.survey_group, 'mentor_record': self.grading_survey_record, 'student_record': self.project_survey_record, 'grade_decision': 'pass' } self.grading_record = GSoCGradingRecord(parent=self.project, **record_values) self.grading_record.put() def testCreateGradingRecord(self): """Test creating a GradingRecord. """ self.grading_record.delete() post_data = {'group_key': self.survey_group.key().id_or_name()} response = self.post(self.UPDATE_RECORDS_URL, post_data) self.assertEqual(response.status_code, httplib.OK) self.assertTasksInQueue(n=1, url=self.UPDATE_RECORDS_URL) record = GSoCGradingRecord.all().get() self.assertFalse(record is None) self.assertEqual(record.grade_decision, 'pass') def testUpdateGradingRecord(self): """Test updating a GradingRecord. """ self.grading_record.grade_decision = 'undecided' self.grading_record.put() post_data = {'group_key': self.survey_group.key().id_or_name()} response = self.post(self.UPDATE_RECORDS_URL, post_data) self.assertEqual(response.status_code, httplib.OK) self.assertTasksInQueue(n=1, url=self.UPDATE_RECORDS_URL) record = GSoCGradingRecord.all().get() self.assertFalse(record is None) self.assertEqual(record.grade_decision, 'pass') def testUpdateProject(self): """Test updating a Project with a GradingRecord's result. """ post_data = { 'group_key': self.survey_group.key().id_or_name(), } response = self.post(self.UPDATE_PROJECTS_URL, post_data) self.assertEqual(response.status_code, httplib.OK) self.assertTasksInQueue(n=1, url=self.UPDATE_PROJECTS_URL) project = GSoCProject.all().get() self.assertFalse(project is None) self.assertEqual(project.passed_evaluations, [self.grading_record.key()]) self.assertEqual(1, project.parent().student_info.passed_evaluations) def testUpdateProjectWithSendMail(self): """Test updating a Project with a GradingRecord's result and sending mail. """ post_data = { 'group_key': self.survey_group.key().id_or_name(), 'send_mail': True, } response = self.post(self.UPDATE_PROJECTS_URL, post_data) self.assertEqual(response.status_code, httplib.OK) self.assertTasksInQueue(n=1, url=self.UPDATE_PROJECTS_URL) self.assertTasksInQueue(n=1, url=self.SEND_URL) project = GSoCProject.all().get() self.assertFalse(project is None) self.assertEqual(project.passed_evaluations, [self.grading_record.key()]) self.assertEqual(1, project.parent().student_info.passed_evaluations) def testSendMail(self): """Test sending mail about a GradingRecord's result. """ post_data = {'record_key': str(self.grading_record.key())} response = self.post(self.SEND_URL, post_data) self.assertEqual(response.status_code, httplib.OK) # URL explicitly added since the email task is in there self.assertTasksInQueue(n=0, url=self.SEND_URL) self.assertEmailSent(to=self.student.email)
class GradingSurveyGroupTest(MailTestCase, GSoCDjangoTestCase, TaskQueueTestCase): """Tests for accept_proposals task. """ UPDATE_RECORDS_URL = '/tasks/gsoc/grading_record/update_records' UPDATE_PROJECTS_URL = '/tasks/gsoc/grading_record/update_projects' SEND_URL = '/tasks/gsoc/grading_record/mail_result' def setUp(self): super(GradingSurveyGroupTest, self).setUp() self.init() self.createMentor() self.createStudent() self.createSurveys() def createMentor(self): """Creates a new mentor. """ profile_helper = GSoCProfileHelper(self.gsoc, self.dev_test) profile_helper.createOtherUser('*****@*****.**') self.mentor = profile_helper.createMentor(self.org) def createStudent(self): """Creates a Student with a project. """ profile_helper = GSoCProfileHelper(self.gsoc, self.dev_test) profile_helper.createOtherUser('*****@*****.**') self.student = profile_helper.createStudentWithProject(self.org, self.mentor) self.project = GSoCProject.all().ancestor(self.student).get() def createSurveys(self): """Creates the surveys and records required for the tests. """ survey_values = { 'author': self.founder, 'title': 'Title', 'modified_by': self.founder, 'link_id': 'link_id', 'scope': self.gsoc, 'scope_path': self.gsoc.key().id_or_name()} self.project_survey = ProjectSurvey(key_name='key_name', **survey_values) self.project_survey.put() self.grading_survey = GradingProjectSurvey(key_name='key_name', **survey_values) self.grading_survey.put() record_values = { 'user': self.student.user, 'org': self.org, 'project': self.project, 'survey': self.project_survey} self.project_survey_record = GSoCProjectSurveyRecord(**record_values) self.project_survey_record.put() self.grading_survey = GradingProjectSurvey(**survey_values) self.grading_survey.put() record_values = { 'user': self.student.user, 'org': self.org, 'project': self.project, 'survey': self.grading_survey, 'grade': True} self.grading_survey_record = GSoCGradingProjectSurveyRecord( **record_values) self.grading_survey_record.put() group_values = { 'name': 'Survey Group Name', 'grading_survey': self.grading_survey, 'student_survey': self.project_survey, 'program': self.gsoc} self.survey_group = GSoCGradingSurveyGroup(**group_values) self.survey_group.put() record_values = { 'grading_survey_group': self.survey_group, 'mentor_record': self.grading_survey_record, 'student_record': self.project_survey_record, 'grade_decision': 'pass'} self.grading_record = GSoCGradingRecord(parent=self.project, **record_values) self.grading_record.put() def testCreateGradingRecord(self): """Test creating a GradingRecord. """ self.grading_record.delete() post_data = { 'group_key': self.survey_group.key().id_or_name() } response = self.post(self.UPDATE_RECORDS_URL, post_data) self.assertEqual(response.status_code, httplib.OK) self.assertTasksInQueue(n=1, url=self.UPDATE_RECORDS_URL) record = GSoCGradingRecord.all().get() self.assertFalse(record is None) self.assertEqual(record.grade_decision, 'pass') def testUpdateGradingRecord(self): """Test updating a GradingRecord. """ self.grading_record.grade_decision = 'undecided' self.grading_record.put() post_data = { 'group_key': self.survey_group.key().id_or_name() } response = self.post(self.UPDATE_RECORDS_URL, post_data) self.assertEqual(response.status_code, httplib.OK) self.assertTasksInQueue(n=1, url=self.UPDATE_RECORDS_URL) record = GSoCGradingRecord.all().get() self.assertFalse(record is None) self.assertEqual(record.grade_decision, 'pass') def testUpdateProject(self): """Test updating a Project with a GradingRecord's result. """ post_data = { 'group_key': self.survey_group.key().id_or_name(), } response = self.post(self.UPDATE_PROJECTS_URL, post_data) self.assertEqual(response.status_code, httplib.OK) self.assertTasksInQueue(n=1, url=self.UPDATE_PROJECTS_URL) project = GSoCProject.all().get() self.assertFalse(project is None) self.assertEqual(project.passed_evaluations, [self.grading_record.key()]) self.assertEqual(1, project.parent().student_info.passed_evaluations) def testUpdateProjectWithSendMail(self): """Test updating a Project with a GradingRecord's result and sending mail. """ post_data = { 'group_key': self.survey_group.key().id_or_name(), 'send_mail': True, } response = self.post(self.UPDATE_PROJECTS_URL, post_data) self.assertEqual(response.status_code, httplib.OK) self.assertTasksInQueue(n=1, url=self.UPDATE_PROJECTS_URL) self.assertTasksInQueue(n=1, url=self.SEND_URL) project = GSoCProject.all().get() self.assertFalse(project is None) self.assertEqual(project.passed_evaluations, [self.grading_record.key()]) self.assertEqual(1, project.parent().student_info.passed_evaluations) def testSendMail(self): """Test sending mail about a GradingRecord's result. """ post_data = { 'record_key': str(self.grading_record.key()) } response = self.post(self.SEND_URL, post_data) self.assertEqual(response.status_code, httplib.OK) # URL explicitly added since the email task is in there self.assertTasksInQueue(n=0, url=self.SEND_URL) self.assertEmailSent(to=self.student.email)