Exemple #1
0
def test_find_length(add_test_data, get_first_feedback, get_second_feedback):
    student = Student(first_name='Harry', last_name='Lewis')
    student2 = Student(first_name='bob', last_name='alice')
    student3 = Student(first_name='Charlie', last_name='Bob')

    grader = Grader(id=1, name='Zesje', oauth_id='Zesje')
    grader2 = Grader(id=2, name='Alice', oauth_id='Smith')

    sub = Submission(id=25, student=student, exam_id=42)
    sub2 = Submission(id=26, student=student2, exam_id=42)
    sub3 = Submission(id=27, student=student3, exam_id=42)

    sol = Solution(problem_id=20,
                   submission=sub,
                   graded_by=grader,
                   graded_at=datetime.now())
    db.session.add(sol)
    sol2 = Solution(problem_id=20,
                    submission=sub2,
                    graded_by=grader2,
                    graded_at=datetime.now())
    db.session.add(sol2)
    sol3 = Solution(problem_id=20,
                    submission=sub3,
                    graded_by=grader2,
                    graded_at=datetime.now())
    db.session.add(sol3)

    sol.feedback = get_first_feedback
    sol2.feedback = get_second_feedback
    sol3.feedback = get_first_feedback

    result = find_number_of_matches(Problem.query.get(20), False, [1], [], 2)
    assert result == 1
Exemple #2
0
def test_find_next(add_test_data, get_first_feedback, get_second_feedback):
    student = Student(first_name='', last_name='')
    student2 = Student(first_name='bob', last_name='alice')

    grader = Grader(name='Zesje', oauth_id='Zesje')

    sub = Submission(id=25, student=student, exam_id=42)
    sub2 = Submission(id=26, student=student2, exam_id=42)

    sol = Solution(problem_id=20,
                   submission=sub,
                   graded_by=grader,
                   graded_at=datetime.now())
    db.session.add(sol)
    sol2 = Solution(problem_id=20,
                    submission=sub2,
                    graded_by=grader,
                    graded_at=datetime.now())
    db.session.add(sol2)

    sol.feedback = get_first_feedback
    sol2.feedback = get_second_feedback

    result = _find_submission(sub, Problem.query.get(20), 1, 'next', False,
                              set([3]), set([2]), None)
    assert result == sub2
Exemple #3
0
def add_test_submissions(app):
    student = Student(first_name='Harry', last_name='Lewis')
    student2 = Student(first_name='bob', last_name='alice')
    student3 = Student(first_name='Charlie', last_name='Bob')

    grader = Grader(id=1, name='Zesje', oauth_id='Zesje')
    grader2 = Grader(id=2, name='Alice', oauth_id='Smith')

    sub = Submission(id=25, student=student, exam_id=42)
    sub2 = Submission(id=26, student=student2, exam_id=42)
    sub3 = Submission(id=27, student=student3, exam_id=42)

    sol = Solution(problem_id=20,
                   submission=sub,
                   graded_by=grader,
                   graded_at=datetime.now())
    db.session.add(sol)
    sol2 = Solution(problem_id=20,
                    submission=sub2,
                    graded_by=grader2,
                    graded_at=datetime.now())
    db.session.add(sol2)
    sol3 = Solution(problem_id=20,
                    submission=sub3,
                    graded_by=grader2,
                    graded_at=datetime.now())
    db.session.add(sol3)
    yield app
Exemple #4
0
def test_reupload_page(app_with_data, zip_file):
    app, exam, students = app_with_data
    student = students[0]
    file_name = 'old.txt'

    sub = Submission(exam=exam, student_id=student.id, validated=True)
    copy = Copy(submission=sub, number=1)
    page = Page(copy=copy, number=0, path=file_name)
    db.session.add_all([sub, copy, page])
    db.session.commit()

    old_path = Path(app.config['DATA_DIRECTORY']) / file_name
    old_path.write_text('old image data')

    image = Image.new('RGB', (10, 10))
    page_info = (student.id, page.number, copy.number)
    file_info = [f'{student.id}-{page.number+1}-{page.copy.number}.jpg']
    exam_config = exam_metadata(exam)
    output_directory = app.config['DATA_DIRECTORY']

    process_page(image, page_info, file_info, exam_config, output_directory)

    # Only a single page entry
    assert Page.query.filter(Page.copy == copy,
                             Page.number == page.number).one()

    # Path was updated and only new image still exists
    assert page.path != file_name
    assert not old_path.exists()
    assert Path(page.abs_path).exists()
Exemple #5
0
def _fake_process_pdf(app, exam, scan, pages, student_ids, copies_per_student):
    validate = exam.layout == ExamLayout.unstructured
    copy_number = 0
    for student_id, number_of_copies in zip(student_ids, copies_per_student):
        for _ in range(number_of_copies):
            copy_number += 1
            copy = Copy(number=copy_number)

            base_copy_path = os.path.join(app.config['DATA_DIRECTORY'],
                                          f'{exam.id}_data', 'submissions', f'{copy_number}')
            os.makedirs(base_copy_path)
            for page in range(pages + 1):
                path = os.path.join(base_copy_path, f'page{page:02d}.jpeg')
                generate_random_page_image(path, A4)
                db.session.add(Page(path=path, copy=copy, number=page))

            sub = Submission(copies=[copy], exam=scan.exam, student_id=student_id, validated=validate)
            db.session.add(sub)

            for problem in scan.exam.problems:
                db.session.add(Solution(problem=problem, submission=sub))

    scan.status = 'success'
    scan.message = 'Successfully skipped processing.'
    db.session.commit()
Exemple #6
0
def test_get_exams(test_client, no_with_subs, no_without_subs):
    for i in range(no_without_subs):
        db.session.add(Exam(name=f'No Submissions {i}'))

    for i in range(no_with_subs):
        exam = Exam(name=f'Submissions {i}')
        db.session.add(exam)
        for _ in range(i):
            db.session.add(Submission(exam=exam))

    db.session.commit()

    response = test_client.get('/api/exams')

    assert response.status_code == 200

    data = json.loads(response.data)
    exams = {exam['name']: exam['submissions'] for exam in data}

    assert len(exams) == no_with_subs + no_without_subs

    for i in range(no_without_subs):
        exam_name = f'No Submissions {i}'
        assert exam_name in exams
        assert exams[exam_name] == 0

    for i in range(no_with_subs):
        exam_name = f'Submissions {i}'
        assert exam_name in exams
        assert exams[exam_name] == i
Exemple #7
0
def test_has_all_required(get_first_feedback):
    student = Student(first_name='', last_name='')
    grader = Grader(name='Zesje', oauth_id='Zesje')
    sub = Submission(student=student, exam_id=42)
    sol = Solution(problem_id=20,
                   submission=sub,
                   graded_by=grader,
                   graded_at=datetime.now())
    sol.feedback = get_first_feedback

    assert has_all_required_feedback(sol, set([1, 2]), set([3]))
Exemple #8
0
def test_find_next_graded_by(add_test_data):
    student = Student(first_name='', last_name='')
    student2 = Student(first_name='bob', last_name='alice')

    grader = Grader(id=1, name='Zesje', oauth_id='Zesje')
    grader2 = Grader(id=2, name='Alice', oauth_id='Smith')

    sub = Submission(id=25, student=student, exam_id=42)
    sub2 = Submission(id=26, student=student2, exam_id=42)

    sol = Solution(problem_id=20,
                   submission=sub,
                   graded_by=grader,
                   graded_at=datetime.now())
    db.session.add(sol)
    sol2 = Solution(problem_id=20,
                    submission=sub2,
                    graded_by=grader2,
                    graded_at=datetime.now())
    db.session.add(sol2)

    result = _find_submission(sub, Problem.query.get(20), 1, 'next', False,
                              set(), set(), 2)
    assert result == sub2
Exemple #9
0
def test_solution_pdf(app, datadir, layout, anonymous):
    exam = Exam(name='Email', layout=layout, finalized=True)
    student = Student(id=1234323,
                      first_name='Jamy',
                      last_name='Macgiver',
                      email='*****@*****.**')
    db.session.add(exam)
    db.session.add(student)
    db.session.commit()

    if layout == ExamLayout.templated:
        db.session.add(
            ExamWidget(
                name='student_id_widget',
                x=50,
                y=50,
                exam=exam,
            ))
        db.session.commit()

    sub = Submission(exam=exam, student=student, validated=True)
    db.session.add(sub)

    copy = Copy(submission=sub, number=1)
    db.session.add(copy)

    for index, filepath in enumerate(
        ['studentnumbers/1234323.jpg', 'studentnumbers/4300947.jpg']):
        page = Page(number=index, path=os.path.join(datadir, filepath))
        db.session.add(page)
        copy.pages.append(page)
    db.session.commit()

    with Pdf.open(solution_pdf(exam.id, student.id,
                               anonymous=anonymous)) as pdf:
        pagecount = len(pdf.pages)
        assert pagecount == 2

        if anonymous and layout == ExamLayout.templated:
            image = extract_image_pikepdf(pdf.pages[0])
            _, coords = exam_student_id_widget(exam.id)
            widget_area = get_box(np.array(image),
                                  np.array(coords, dtype=float) / 72,
                                  padding=-.3)
            w, h, *_ = widget_area.shape

            assert 145 < (np.mean(widget_area[:w // 2]) +
                          np.mean(widget_area[:, :h // 2])) / 2 < 155
Exemple #10
0
def test_delete_problem_graded(test_client, add_test_data, exam_id,
                               problem_id):
    student = Student(first_name='', last_name='')
    db.session.add(student)
    grader = Grader(name='Zesje', oauth_id='zesje')
    db.session.add(grader)
    db.session.commit()
    sub = Submission(student=student, exam_id=exam_id)
    db.session.add(sub)
    db.session.commit()
    sol = Solution(problem_id=problem_id,
                   submission=sub,
                   graded_by=grader,
                   graded_at=datetime.now())
    db.session.add(sol)
    db.session.commit()

    result = test_client.delete(f'/api/problems/{problem_id}')

    assert result.status_code == 403
    assert Problem.query.get(problem_id) is not None
Exemple #11
0
def add_submissions(exam, student, type, with_student=True):
    subs = []
    student_none = student if with_student else None
    if type == 'unvalidated':
        subs.append(Submission(exam=exam, student=student_none, copies=[next_copy()]))
    elif type == 'unvalidated_multiple':
        subs.append(Submission(exam=exam, student=student_none, copies=[next_copy()]))
        subs.append(Submission(exam=exam, student=student, copies=[next_copy()]))
    elif type == 'validated':
        subs.append(Submission(exam=exam, student=student, validated=True, copies=[next_copy()]))
    elif type == 'validated_multiple':
        subs.append(Submission(exam=exam, student=student, validated=True, copies=[next_copy(), next_copy()]))
    elif type == 'mixed':
        subs.append(Submission(exam=exam, student=student_none, copies=[next_copy()]))
        subs.append(Submission(exam=exam, student=student, validated=True, copies=[next_copy()]))
    elif type == 'mixed_inverse':
        subs.append(Submission(exam=exam, student=student, validated=True, copies=[next_copy()]))
        subs.append(Submission(exam=exam, student=student_none, copies=[next_copy()]))
    elif type == 'mixed_multiple':
        subs.append(Submission(exam=exam, student=student_none, copies=[next_copy()]))
        subs.append(Submission(exam=exam, student=student, copies=[next_copy()]))
        subs.append(Submission(exam=exam, student=student, validated=True, copies=[next_copy(), next_copy()]))
    elif type == 'mixed_multiple_inverse':
        subs.append(Submission(exam=exam, student=student, validated=True, copies=[next_copy(), next_copy()]))
        subs.append(Submission(exam=exam, student=student_none, copies=[next_copy()]))
        subs.append(Submission(exam=exam, student=student, copies=[next_copy()]))

    for sub in subs:
        db.session.add(sub)
    db.session.commit()
    return [(sub, [copy for copy in sub.copies]) for sub in subs]
Exemple #12
0
def test_create_copy(app_with_data):
    app, exam, students = app_with_data
    submission = Submission(exam=exam, student=students[0])
    copy = create_copy(submission)

    assert copy.id == copy.number
Exemple #13
0
def submission():
    return Submission()