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
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
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
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()
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()
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
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]))
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
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
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
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]
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
def submission(): return Submission()