示例#1
0
def test_show_lunchmates_of_external_lunch(reset_mock):
    # Current decision: show private students in another lunch
    # Can be blocked in frontend

    viewer = Student('hpeng2021', 'Michael Peng')
    viewer.schedules = {1: {'C': 'Smith', 'F': 'Shea'}}
    smith = Class('Smith', 'C', 1, lunch=2)
    shea = Class('Shea', 'F', 1, lunch=None)

    class_repo.load.side_effect = switch({
        ('Smith', 'C', 1): smith,
        ('Shea', 'F', 1): shea
    })
    class_repo.names_of_teachers_in_lunch.side_effect = switch({
        (1, 'C', 2): ['Messina', 'Smith', 'Caveney'],
        (1, 'C', 4): ['Emery', 'Gonzalez', 'Parsons']
    })

    lunchmates = [
        Student('divanovich2021', 'Daniel', is_public=False),
        Student('azenith2021', 'Ayush', is_public=True)
    ]

    student_repo.students_in_class.side_effect = switch({
        (1, 'C', 'Emery'): [lunchmates[1]],
        (1, 'C', 'Parsons'): [lunchmates[0]],
        (1, 'C', 'Gonzalez'): []
    })

    output = case.show_lunchmates(viewer, 1, 'C', 4)

    assert set(output) == set(lunchmates)
示例#2
0
def test_show_lunch_number(reset_mock):
    viewer = Student('hpeng2021', 'Michael Peng')
    viewer.schedules = {
        1: {
            'C': 'Ream',
            'D': 'DiBenedetto',
            'E': 'Emery'
        },
        2: {
            'C': 'Ream',
            'D': 'DiBenedetto',
            'E': 'Messina'
        }
    }
    emery = Class('Emery', 'E', 1, lunch=2)
    messina = Class('Messina', 'E', 2, lunch=None)

    class_repo.load.side_effect = switch({
        ('Emery', 'E', 1): emery,
        ('Messina', 'E', 2): messina
    })

    e1_out = case.show_lunch_number(viewer, 1, 'E')
    e2_out = case.show_lunch_number(viewer, 2, 'E')

    assert e1_out == 2
    assert e2_out is None
示例#3
0
def test_own_schedule_exists():
    student = Student('hpeng2021', 'Michael')
    student.schedules = {1: {'D': 'Yes'}}

    output = case.own_schedule(student, 1)

    assert output == {'D': 'Yes'}
示例#4
0
def test_read_schedule_of_private_without_reader_schedule():
    reader = Student('hpeng2021', 'Michael')

    student = Student('divanovich2021', 'Daniel')
    student.schedules = {2: {'D': 'Givens'}}

    assert case.show_schedule(reader, student, 2) == {}
示例#5
0
def test_semester_schedule_with_schedule():
    student = Student('hpeng2021', 'Michael')
    student.schedules = {1: {'A': 'glee', 'B': '', 'C': 'see', 'D': 'dee'}}

    output = student.semester_schedule(1)

    assert output == student.schedules[1]
    assert student.semester_schedule(2) is None
示例#6
0
def test_read_no_schedule_student():
    reader = Student('a', 'A')
    student = Student('b', 'B')
    student.is_public = True
    student.schedules = None

    with pytest.raises(MissingScheduleError, match='B'):
        case.show_schedule(reader, student, 1)
示例#7
0
def test_read_schedule_of_public():
    reader = Student('hpeng2021', 'Michael')
    student = Student('divanovich2021', 'Daniel')
    student.is_public = True
    student.schedules = {1: {'G': 'Ream'}}

    result = case.show_schedule(reader, student, 1)

    assert result == {'G': 'Ream'}
示例#8
0
def test_pass_query_to_repo():
    student_repo.search.return_value = [
        Student('qry', 'Que Ry'),
        Student('mquery', 'Myq Uery')
    ]

    results = case.perform_search('my query')

    student_repo.search.assert_called_once_with('my query')
    assert list(results) == student_repo.search.return_value
示例#9
0
    def show_schedule(viewer: Student, target: Student,
                      semester: Semester) -> SemesterSchedule:
        """ Missing blocks means 'Private'; MissingScheduleError means not available """
        schedule = target.semester_schedule(semester)
        if schedule is None:
            raise MissingScheduleError(target)

        if target.is_public:
            return schedule

        viewer_schedule = viewer.semester_schedule(semester)
        if viewer_schedule is None:
            return {}

        return dict(set(schedule.items()) & set(viewer_schedule.items()))
示例#10
0
def do_login():
    if request.method == 'GET':
        if logged_handle() is not None:
            flash('You are already logged in')
            return redirect(request.args.get('redirect', DEFAULT_HOME))
        return render_template('login.html',
                               redirect=request.args.get('redirect', ''))

    # expected form argument: id_token, redirect (optional)
    if missing_form_field('id_token'):
        return error(422, 'Missing token from Google sign-in')

    try:
        (handle, name) = adapt.google.verify(request.form['id_token'])
        session_log_in(handle)
        have_user = adapt.student_repo.exists(handle)

        flash('Successfully logged in as ' + name)

        default = DEFAULT_HOME

        if not have_user:
            session['name'] = name
            default = '/update'
            new = Student(handle, name)
            adapt.student_repo.save(new)
            # Fact: if user is logged in, then the user must have a database entry

        if missing_form_field('redirect'):
            return redirect(default)
        return redirect(request.form.get('redirect', default))

    except ValueError as e:
        return error(403, 'Authentication failed: ' + str(e))
示例#11
0
def test_load_student_without_discord(reset_mock):
    db_entry = {
        'name': 'Michael Peng',
        'semesters': {
            '1': {
                'A': 'Holm-Andersen',
                'B': 'Gonzalez',
                'C': 'Ream',
                'D': 'Givens'
            },
            '2': {
                'E': 'Messina',
                'F': 'Parsons',
                'G': 'Reidy'
            }
        },
        'is_public': True,
        'cohort': 'blue'
    }
    mock_db.collection('students').document(
        'hpeng2021').get().to_dict.return_value = db_entry
    mock_db.collection('students').document('hpeng2021').get().id = 'hpeng2021'

    student = student_repo.load('hpeng2021')

    assert student == Student(handle='hpeng2021',
                              name='Michael Peng',
                              schedules={
                                  1: db_entry['semesters']['1'],
                                  2: db_entry['semesters']['2']
                              },
                              is_public=True,
                              discord_id=None,
                              cohort=Cohort.blue)
示例#12
0
def test_set_student_without_discord(reset_mock):
    student = Student('hpeng2021',
                      'Michael Peng',
                      schedules={
                          1: {
                              'C': 'Messina'
                          },
                          2: {
                              'F': 'Parsons'
                          }
                      },
                      cohort=Cohort.blue)

    student_repo.save(student)

    mock_db.collection('students').document(
        'hpeng2021').set.assert_called_once_with({
            'name': 'Michael Peng',
            'semesters': {
                '1': {
                    'C': 'Messina'
                },
                '2': {
                    'F': 'Parsons'
                }
            },
            'is_public': student.is_public,
            'cohort': 'blue'
        })
示例#13
0
 def _generate_day_events(student: Student, day: datetime.date) -> List[Event]:
     output = []
     time = arrow.get(datetime.datetime.combine(day, START_TIME, TIMEZONE))
     for block in BLOCK_SEQ[time.weekday()]:
         output.append(IcsCalendarCase._generate_event(
             block, teacher=student.semester_schedule(2)[block], begin=time))
         time += BLOCK_LEN + BLOCK_SPACING
     return output
示例#14
0
def test_add_existing_user(reset_mock):
    mock_db.collection('students').document('hpeng2021').get().exists = True
    mock_db.document('counters/user').get().get.side_effect = require(
        ('value', ), 412)

    student_repo.save(Student('hpeng2021', 'Michael'))

    mock_db.document.assert_called_with('counters/user')
示例#15
0
def test_read_schedule_of_private():
    reader = Student('hpeng2021', 'Michael')
    reader.schedules = {
        1: {
            'A': 'Holm-Andersen',
            'D': 'Givens',
            'E': 'Messina',
            'F': 'Parsons',
            'G': 'Hibino, Krista'
        }
    }

    student = Student('divanovich2021', 'Daniel')
    student.schedules = {
        1: {
            'A': 'Holm-Andersen',
            'D': 'Givens',
            'E': 'Reusch',
            'F': 'Scarfo',
            'G': 'Ream'
        }
    }
    student.is_public = False

    result = case.show_schedule(reader, student, 1)

    assert result == {'A': 'Holm-Andersen', 'D': 'Givens'}
示例#16
0
    def show_classmates(self, viewer: Student, semester: Semester,
                        block: Block) -> Iterable[Student]:
        schedule = viewer.semester_schedule(semester)
        if schedule is None:
            raise MissingScheduleError(viewer)

        roster = self.student_repo.students_in_class(semester, block,
                                                     schedule[block])
        return roster
示例#17
0
def test_add_new_user(reset_mock):
    mock_db.collection('students').document('hpeng2021').get().exists = False
    mock_db.document('counters/user').get().get.side_effect = require(
        ('value', ), 412)

    student_repo.save(Student('hpeng2021', 'Michael'))

    mock_db.document.assert_called_with('counters/user')
    mock_db.document('counters/user').update.assert_called_once_with(
        {'value': 413})
示例#18
0
    def integrate_discord(self, student: Student, code: str,
                          state: str) -> DiscordUser:
        if student.schedules is None:
            raise MissingScheduleError(student)

        user = self.discord_verifier.verify(code, state)
        student.discord_id = user.id
        self.student_repo.save(student)

        return user
示例#19
0
def test_students_in_class(reset_mock):
    classmates = [Student('a', 'A'), Student('b', 'B'), Student('c', 'C')]

    def mock_student_doc_snapshot(student):
        snapshot = Mock(id=student.handle)
        snapshot.to_dict.return_value = {
            'name': student.name,
            'semesters': None,
            'is_public': False,
            'discord_id': None,
            'cohort': None
        }
        return snapshot

    mock_db.collection('students').where('semesters.1.D', '==', 'Caveney')\
        .stream.return_value = map(mock_student_doc_snapshot, classmates)

    results = student_repo.students_in_class(1, 'D', 'Caveney')

    assert set(results) == set(classmates)
示例#20
0
    def show_lunch_number(self, target: Student, semester: Semester,
                          block: Block) -> Optional[LunchNumber]:
        """ None: teacher does not have this lunch recorded
        MissingScheduleError: viewer has no schedule """
        schedule = target.semester_schedule(semester)
        if schedule is None:
            raise MissingScheduleError(target)
        klass = self.class_repo.load(schedule[block], block, semester)
        if klass is None:
            return None

        return klass.lunch
示例#21
0
def match_score(a: Student, b: Student):
    name_score = ((name_hash(a.name) + name_hash(b.name)) % 117) / 117
    shared_classes = 0

    for semester in [1, 2]:
        schedule_a = a.semester_schedule(semester)
        schedule_b = b.semester_schedule(semester)
        if schedule_a is None or schedule_b is None:
            break
        for block in BLOCKS:
            if schedule_a[block] == schedule_b[block]:
                shared_classes += 1

    # max theoretical shared classes: BLOCKS*2
    # use a sqrt curve
    classes_score = -4 / (0.8 * shared_classes * shared_classes + 4) + 1

    # same grade?
    grade_score = (3 - abs(a.graduating_year() - b.graduating_year())) / 3

    print(f"match score query between {a.handle} and {b.handle}: name_score={name_score:.3f} classes_score={classes_score:.3f} grade_score={grade_score:.3f}")
    return name_score * 0.4 + classes_score * 0.4 + grade_score * 0.2
示例#22
0
    def update_lunches(self, student: Student, update: Dict[Semester,
                                                            SemesterLunches]):
        batch_update: List[Class] = []

        for (semester, lunches) in update.items():
            schedule = student.semester_schedule(semester)
            if schedule is None:
                raise MissingScheduleError(student)
            for (block, number) in lunches.items():
                batch_update.append(
                    Class(schedule[block], block, semester, lunch=number))

        self.class_repo.update_batch(batch_update)
示例#23
0
    def _read_doc(entry: firestore.DocumentSnapshot) -> Optional[Student]:
        data = entry.to_dict()

        if data is None:
            return None

        return Student(
            handle=entry.id,
            name=data['name'],
            schedules=None if data.get('semesters') is None else key_transform(data['semesters'], int),
            is_public=data['is_public'],
            discord_id=data.get('discord_id'),
            cohort=Cohort[data.get('cohort')] if data.get('cohort') is not None else None
        )
示例#24
0
    def show_lunchmates(self, viewer: Student, semester: Semester,
                        block: Block,
                        number: LunchNumber) -> Iterable[Student]:
        schedule = viewer.semester_schedule(semester)
        if schedule is None:
            raise MissingScheduleError(viewer)

        # TODO restrict
        teachers = self.class_repo.names_of_teachers_in_lunch(
            semester, block, number)

        for teacher in teachers:
            yield from self.student_repo.students_in_class(
                semester, block, teacher)
示例#25
0
def test_show_classmates(reset_mock):
    classmates = [Student('a', 'A'), Student('b', 'B'), Student('c', 'C')]
    student_repo.students_in_class.return_value = classmates
    student = Student('hpeng2021', 'Michael')
    student.schedules = {1: {'D': 'Givens'}}

    output = case.show_classmates(student, 1, 'D')

    assert output == classmates
    student_repo.students_in_class.assert_called_once_with(1, 'D', 'Givens')
示例#26
0
def test_set_student_with_discord(reset_mock):
    student = Student('hpeng2021',
                      'Michael Peng',
                      schedules=None,
                      discord_id='1040293723984713431')

    student_repo.save(student)

    mock_db.collection('students').document(
        'hpeng2021').set.assert_called_once_with({
            'name': 'Michael Peng',
            'semesters': None,
            'is_public': student.is_public,
            'discord_id': student.discord_id,
            'cohort': None
        })
示例#27
0
def test_load_student_with_discord_without_schedule(reset_mock):
    db_entry = {
        'name': 'Michael Peng',
        'semesters': None,
        'accepts_terms': True,
        'accepts_privacy': True,
        'is_public': True,
        'discord_id': '100923842098207349',
        'cohort': 'remote'
    }
    mock_db.collection('students').document(
        'hpeng2021').get().to_dict.return_value = db_entry

    student = student_repo.load('hpeng2021')

    assert student == Student(handle='hpeng2021',
                              name='Michael Peng',
                              schedules=None,
                              is_public=True,
                              discord_id=db_entry['discord_id'],
                              cohort=Cohort.remote)
示例#28
0
def test_show_lunchmates_of_own_lunch(reset_mock):
    viewer = Student('hpeng2021', 'Michael Peng')
    viewer.schedules = {1: {'D': 'Smith'}}
    lunchmates = [
        Student('pcess', 'Pro Cess'),
        Student('azenith', 'Ayush Zenith'),
        Student('jmann', 'Jordan Mann')
    ]
    klass = Class('Smith', 'D', 1, lunch=3)

    class_repo.load.side_effect = require(('Smith', 'D', 1), klass)
    class_repo.names_of_teachers_in_lunch.side_effect = require((1, 'D', 3),
                                                                ['Smith'])
    student_repo.students_in_class.side_effect = require((1, 'D', 'Smith'),
                                                         lunchmates)

    output = case.show_lunchmates(viewer, 1, 'D', 3)

    assert list(output) == list(lunchmates)
示例#29
0
from entities.student import Student
from entities.types import SemesterSchedule
from use_cases.calendar import IcsCalendarCase

student_schedule: SemesterSchedule = {
    'A': 'Aubrey',
    'B': 'Bach',
    'C': 'Conrad',
    'D': 'Donovan',
    'E': 'Emery',
    'F': 'Frisk',
    'G': 'Gonzalez'
}
student: Student = Student('hpeng2021',
                           'Michael Peng',
                           schedules={2: student_schedule})
case = IcsCalendarCase()

ahs_timezone = 'America/New_York'
expected_events = {
    Event(name='A Block with Aubrey',
          begin=Arrow(2020, 4, 6, 8, 30, tzinfo=ahs_timezone),
          end=Arrow(2020, 4, 6, 9, 15, tzinfo=ahs_timezone),
          categories=['AHS at home', 'AHS at home: A Block'],
          alarms=[AudioAlarm(-datetime.timedelta(minutes=5))]),
    Event(name='C Block with Conrad',
          begin=Arrow(2020, 4, 6, 9, 30, tzinfo=ahs_timezone),
          end=Arrow(2020, 4, 6, 10, 15, tzinfo=ahs_timezone),
          categories=['AHS at home', 'AHS at home: C Block'],
          alarms=[AudioAlarm(-datetime.timedelta(minutes=5))]),
示例#30
0
            'is_public': False,
            'discord_id': None,
            'cohort': None
        }
        return snapshot

    mock_db.collection('students').where('semesters.1.D', '==', 'Caveney')\
        .stream.return_value = map(mock_student_doc_snapshot, classmates)

    results = student_repo.students_in_class(1, 'D', 'Caveney')

    assert set(results) == set(classmates)


search_students = [
    Student('tbowlin', 'Tamekia Bowlin'),
    Student('blanterman', 'Brock Lanterman'),
    Student('hmateo', 'Hedwig Mateo'),
    Student('skrzeminski', 'Sadye Krzeminski'),
    Student('choltz', 'Clayton Holtz'),
    Student('mmchaney', 'Maryam Mchaney'),
    Student('lcuen', 'Liane Cuen'),
    Student('calbrecht', 'Cristobal Albrecht'),
    Student('dhohman', 'Dianna Hohman'),
    Student('ksecrist', 'Katelynn Secrist')
]


def populate_search_students():
    ret_val = []
    for student in search_students: