Ejemplo n.º 1
0
 def mock_participants(self):
     unfinished_id = Participant.convert_uid(self.unfinished_id)
     finished_id = Participant.convert_uid(self.finished_id)
     participants = [
         Participant.create(id=unfinished_id,
                            name='unfinished',
                            organization_id='Org_foo'),
         Participant.create(id=finished_id,
                            name='finished',
                            organization_id='Org_foo'),
     ]
     Participant.put_multi(participants)
     return participants
Ejemplo n.º 2
0
    def test_get_for_team(self):
        """You can list participants for a team you own."""
        other, teammate, contact, captain, team, classroom, ppnt = self.create(
        )

        # Forbidden for non-members.
        response = self.testapp.get('/api/teams/{}/participants'.format(
            team.uid),
                                    headers=jwt_headers(other),
                                    status=403)

        # Make sure query excludes participants on other teams.
        other_ppnt = Participant.create(first_name='other',
                                        last_name='person',
                                        team_id='Team_foo',
                                        classroom_ids=['Classroom_foo'],
                                        student_id='STUDENTID001')
        other_ppnt.put()

        # Successful for members.
        response = self.testapp.get(
            '/api/teams/{}/participants'.format(team.uid),
            headers=jwt_headers(teammate),
        )
        response_list = json.loads(response.body)
        self.assertEqual(len(response_list), 1)
Ejemplo n.º 3
0
    def test_status_code_not_found_returned_when_student_id(self):
        """404 Not Found is returned when class exists but student_id doesn't."""

        code = 'forest temple'
        student_id = 'zelda'
        bad_student_id = 'NOTzelda'

        team = Team.create(
            name="Foo Team",
            captain_id="User_cap",
            program_id=self.program.uid,
        )
        team.put()

        classroom = Classroom.create(
            code=code,
            name='Adventuring 101',
            contact_id='User_LINK',
            team_id=team.uid,
        )
        classroom.put()

        participant = Participant.create(
            student_id=student_id,
            team_id=team.uid,
            classroom_ids=[classroom.uid],
        )
        participant.put()

        self.testapp.get(
            '/api/codes/{}/participants/{}'.format(code, bad_student_id),
            status=404,
        )
    def create_pd_context(self):
        program_label = 'demo-program'
        program_config = Program.get_config(program_label)
        template = program_config['surveys'][0]['survey_tasklist_template']

        project_cohort = ProjectCohort.create(
            program_label=program_label,
            organization_id='Organization_foo',
            project_id='Project_foo',
            cohort_label='2018',
        )
        project_cohort.put()

        survey = Survey.create(
            template,
            program_label=program_label,
            organization_id='Organization_foo',
            project_cohort_id=project_cohort.uid,
            ordinal=1,
        )
        survey.put()

        participant = Participant.create(name='Pascal',
                                         organization_id='PERTS')
        participant.put()

        return (project_cohort, survey, participant)
Ejemplo n.º 5
0
 def test_get_participant_by_id(self):
     p = Participant.create(
         name=
         'f7fbba6e0636f890e56fbbf3283e524c6fa3204ae298382d624741d0dc6638326e282c41be5e4254d8820772c5518a2c5a8c0c7f7eda19594a7eb539453e1ed7',
         organization_id='Organization_12345678',
     )
     p.put()
     fetched_p = Participant.get_by_id(p.uid)
     # Test that hashes up to 128 characters will fit.
     self.assertEqual(fetched_p.name, p.name)
Ejemplo n.º 6
0
    def create(self):
        team_id = 'Team_001'
        p1 = Participant.create(
            student_id='4321',
            team_id=team_id,
            classroom_ids=['Classroom_001'],
        )
        p2 = Participant.create(
            student_id='4322',
            team_id=team_id,
            classroom_ids=['Classroom_001', 'Classroom_002'],
        )
        p3 = Participant.create(
            student_id='4323',
            team_id=team_id,
            classroom_ids=['Classroom_003'],
        )
        Participant.put_multi([p1, p2, p3])

        return p1, p2, p3
Ejemplo n.º 7
0
 def test_completion_ids_exclude_testing(self):
     """Don't count testing pd as that participant being done."""
     pid = self.test_create_portal_pd(testing=True)
     participant = Participant.create(
         id=SqlModel.convert_uid(pid),
         name='Pascal',
         organization_id='Organization_PERTS',
     )
     participant.put()
     results = ParticipantData.completion_ids(
         project_cohort_id='ProjectCohort_12345678')
     self.assertEqual(results, [])
Ejemplo n.º 8
0
    def test_delete_disassociates_participants(self):
        captain, contact, classroom1, report1, report2 = \
            self.create_for_delete()

        # Create another classroom, so we check that participants remain on it
        # afterward.
        classroom2 = Classroom.create(
            name='Classroom Bar',
            code='steel snake',
            team_id=classroom1.team_id,
            contact_id=contact.uid,
            num_students=22,
        )
        classroom2.put()

        ppt_on_one = Participant.create(
            student_id='on_one',
            team_id=classroom1.team_id,
            classroom_ids=[classroom1.uid],
        )
        ppt_on_two = Participant.create(
            student_id='on_two',
            team_id=classroom1.team_id,
            classroom_ids=[classroom1.uid, classroom2.uid],
        )
        Participant.put_multi([ppt_on_one, ppt_on_two])

        url = '/api/classrooms/{}'.format(classroom1.uid)
        headers = self.login_headers(captain)

        # Delete the classroom.
        self.testapp.delete(url, headers=headers, status=204)

        # Both participants are still there, but neither is associated with
        # the deleted classroom.
        self.assertEqual(
            Participant.get_by_id(ppt_on_one.uid).classroom_ids, [])
        self.assertEqual(
            Participant.get_by_id(ppt_on_two.uid).classroom_ids,
            [classroom2.uid])
Ejemplo n.º 9
0
    def test_patch_with_disassociated_participant(self):
        """If a participant exists with no classrooms, they are found."""
        other, teammate, contact, captain, team, classroom, _ = self.create()

        student_id = 'disassociated'

        # Add an participant who is disassociated from all classrooms.
        ppt = Participant.create(
            team_id=team.uid,
            classroom_ids=[],
            student_id=student_id,
        )
        ppt.put()

        def postBody(ppt, id_modifier=''):
            ppt = ppt.copy()
            ppt['student_id'] += id_modifier
            return {'method': 'POST', 'path': '/api/participants', 'body': ppt}

        response = self.testapp.patch_json(
            '/api/participants',
            [{
                'method': 'POST',
                'path': '/api/participants',
                'body': {
                    'team_id': team.uid,
                    'classroom_id': classroom.uid,
                    'student_id': student_id,
                },
            }],
            headers=jwt_headers(contact),
        )
        response_list = json.loads(response.body)

        # The provided student id matched the disassociated user and the
        # db used that uid.
        self.assertEqual(len(response_list), 1)
        self.assertEqual(response_list[0]['uid'], ppt.uid)
        self.assertEqual(
            Participant.get_by_id(ppt.uid).classroom_ids,
            [classroom.uid],
        )

        # `num_students` has incremented after adding new participant to
        # classroom.
        updated_classroom = Classroom.get_by_id(classroom.uid)
        self.assertEqual(
            updated_classroom.num_students,
            classroom.num_students + 1,
        )
Ejemplo n.º 10
0
    def create(self):
        team = Team.create(name='foo', program_id=self.program.uid)
        classroom = Classroom.create(
            name="CompSci 101",
            team_id=team.uid,
            code="foo",
        )

        teammate = User.create(name='teammate',
                               email='*****@*****.**',
                               owned_teams=[team.uid])
        contact = User.create(name='contact',
                              email='*****@*****.**',
                              owned_teams=[team.uid])
        captain = User.create(name='captain',
                              email='*****@*****.**',
                              owned_teams=[team.uid])
        other = User.create(name='other', email='*****@*****.**')

        team.captain_id = captain.uid
        classroom.contact_id = contact.uid

        # O hedgehog of curses, generate for the Finns a part of the game of
        # ignominies!
        # http://clagnut.com/blog/2380/
        participant = Participant.create(
            first_name=u'Je\u017cu',
            last_name=u'Kl\u0105tw',
            team_id=team.uid,
            classroom_ids=[classroom.uid],
            student_id=u'Kl\[email protected]',
        )

        participant.put()
        User.put_multi((other, teammate, contact, captain))
        team.put()
        classroom.num_students = 1
        classroom.put()

        return (other, teammate, contact, captain, team, classroom,
                participant)
Ejemplo n.º 11
0
    def test_status_code_found_returned(self):
        """200 OK returned when student_id is found in classroom roster."""

        code = 'forest temple'
        student_id = 'Zelda 77!'

        team = Team.create(
            name="Foo Team",
            captain_id="User_cap",
            program_id=self.program.uid,
        )
        team.put()

        classroom = Classroom.create(
            code=code,
            name='Adventuring 101',
            contact_id='User_LINK',
            team_id=team.uid,
        )
        classroom.put()

        participant = Participant.create(
            student_id=student_id,
            team_id=team.uid,
            classroom_ids=[classroom.uid],
        )
        participant.put()

        # Exact match.
        self.testapp.get(
            '/api/codes/{}/participants/{}'.format(code, student_id),
            status=200,
        )

        # Stripped.
        self.testapp.get(
            '/api/codes/{}/participants/{}'.format(
                code, Participant.strip_token(student_id)),
            status=200,
        )
Ejemplo n.º 12
0
    def test_update_remove_from_multiple_rosters(self):
        """When ppt is updated to have one fewer classroom id."""
        other, teammate, contact, captain, team, classroom, _ = self.create()

        # Make a second classroom to associate with.
        classroom2 = Classroom.create(
            name="Second Classroom",
            team_id=team.uid,
            contact_id='User_contact',
            code="bar",
        )

        # Start with a ppt on two classrooms.
        ppnt = Participant.create(
            team_id=team.uid,
            classroom_ids=[classroom.uid, classroom2.uid],
            student_id='toremove',
        )
        ppnt.put()

        # Make sure count of students starts out correct.
        classroom2.num_students = 1
        classroom2.put()

        # Remove them from just one of their classrooms.
        response = self.testapp.put_json(
            '/api/participants/{}'.format(ppnt.uid),
            {'classroom_ids': [classroom.uid]},  # classroom2 removed
            headers=jwt_headers(contact),
        )

        # Check they're still on the other classroom.
        fetched = Participant.get_by_id(ppnt.uid)
        self.assertEqual(fetched.classroom_ids, [classroom.uid])

        # Check that classroom size is updated.
        fetched_classroom2 = Classroom.get_by_id(classroom2.uid)
        self.assertEqual(fetched_classroom2.num_students,
                         classroom2.num_students - 1)
Ejemplo n.º 13
0
 def test_completion_ids(self):
     pid = self.test_create_portal_pd()
     participant = Participant.create(
         id=SqlModel.convert_uid(pid),
         name='Pascal',
         organization_id='Organization_PERTS',
     )
     participant.put()
     results = ParticipantData.completion_ids(
         project_cohort_id='ProjectCohort_12345678')
     expected = [
         {
             'module': 1,
             'percent_progress': '100',
             'token': 'Pascal'
         },
         {
             'module': 2,
             'percent_progress': '33',
             'token': 'Pascal'
         },
     ]
     self.assertEqual(results, expected)
Ejemplo n.º 14
0
    def test_check_roster_cycle_data(self):
        team = Team.create(name='foo',
                           captain_id="User_cap",
                           program_id=self.program.uid)
        classroom = Classroom.create(
            name="CompSci 101",
            team_id=team.uid,
            contact_id="User_contact",
            code="foo bar",
            num_students=1,
        )
        ppt = Participant.create(team_id=team.uid,
                                 classroom_ids=[classroom.uid],
                                 student_id='STUDENTID001')
        today = datetime.date.today()
        cycle1 = Cycle.create(
            team_id=team.uid,
            ordinal=1,
            # schedule to not be current (starts and ends in the past)
            start_date=today - datetime.timedelta(days=3),
            end_date=today - datetime.timedelta(days=2),
        )
        cycle1.put()

        team.put()
        classroom.put()
        ppt.put()

        # Without a current cycle, no cycle data
        response = self.testapp.get(
            '/api/codes/{}/participants/{}'.format(classroom.url_code,
                                                   ppt.student_id),
            status=200,
        )
        self.assertEqual(
            json.loads(response.body),
            {
                'uid': ppt.uid,
                'team_id': ppt.team_id
            },
        )

        # Add a new cycle that is current.
        cycle2 = Cycle.create(
            team_id=team.uid,
            ordinal=2,
            # schedule to not be current (starts and ends in the past)
            start_date=today - datetime.timedelta(days=1),
            end_date=today + datetime.timedelta(days=1),
        )
        cycle2.put()

        # Cycle data present.
        response = self.testapp.get(
            '/api/codes/{}/participants/{}'.format(classroom.url_code,
                                                   ppt.student_id),
            status=200,
        )
        expected = {
            'uid': ppt.uid,
            'team_id': ppt.team_id,
            'cycle': {
                'uid': cycle2.uid,
                'team_id': cycle2.team_id,
                'ordinal': cycle2.ordinal,
                'start_date': util.datelike_to_iso_string(cycle2.start_date),
                'end_date': util.datelike_to_iso_string(cycle2.end_date),
            }
        }
        self.assertEqual(json.loads(response.body), expected)
Ejemplo n.º 15
0
    def test_check_roster(self):
        # Other apps (neptune) should be able to check the existence of
        # participants by name, and it should work on stripped versions.
        other, teammate, contact, captain, team, classroom, ppnt = self.create(
        )

        ppnt.student_id = u'ABC-123-def'
        ppnt.stripped_student_id = 'abc123def'
        ppnt.put()
        url_code = classroom.code.replace(' ', '-')

        # Unstripped name found.
        self.testapp.get(
            '/api/codes/{}/participants/{}'.format(url_code, ppnt.student_id),
            status=200,
        )
        # Stripped name (expected neptune behavior) found.
        self.testapp.get(
            '/api/codes/{}/participants/{}'.format(url_code,
                                                   ppnt.stripped_student_id),
            status=200,
        )
        # Unknown name not found.
        self.testapp.get(
            '/api/codes/{}/participants/{}'.format(url_code, 'dne'),
            status=404,
        )

        # Known name, unknown classroom code => not found.
        self.testapp.get(
            '/api/codes/{}/participants/{}'.format('bad-code',
                                                   ppnt.stripped_student_id),
            status=404,
        )

        # Known name and code, but student not on that classroom => not found.
        other_class = Classroom.create(
            name="Other Class",
            team_id=team.uid,
            contact_id='User_contact',
            code="bar",
        )
        other_class.put()
        self.testapp.get(
            '/api/codes/{}/participants/{}'.format('bar',
                                                   ppnt.stripped_student_id),
            status=404,
        )

        # Known name, but not on any classrooms => not found.
        disassociated = Participant.create(
            team_id=team.uid,
            classroom_ids=[],
            student_id='disassociated',
        )
        disassociated.put()
        self.testapp.get(
            '/api/codes/{}/participants/{}'.format(
                url_code, disassociated.stripped_student_id),
            status=404,
        )
Ejemplo n.º 16
0
 def create_participant(self):
     p = Participant.create(name='Rene', organization_id='Org_Eruditorum')
     p.put()
     return p