def test_url_classify_method(): """The classify method should update model fields from url parsing.""" url = 'http://www.example.com/TMA4130/2013h/oldExams/eksamen-bok_2006v.pdf' exam_url = PdfUrl(url=url) exam_url.classify() exam_url.save() assert exam_url.url == url # At first, the course does not exist, so only the string is saved assert exam_url.exam.course is None assert exam_url.exam.course_code == 'TMA4130' # All other fields have been inferred assert exam_url.filename == 'eksamen-bok_2006v.pdf' assert exam_url.probably_exam is True assert exam_url.exam.language == Language.BOKMAL assert exam_url.exam.year == 2006 assert exam_url.exam.season == Season.SPRING assert exam_url.exam.solutions is False assert exam_url.exam.content_type == DocumentInfo.EXAM assert exam_url.verified_by.count() == 0 assert exam_url.created_at assert exam_url.updated_at # Now we create the course and resave the exam model object course = CourseFactory(course_code='TMA4130') course.save() exam_url.exam.save() # The course should now be properly set assert exam_url.exam.course == course
def test_deriving_course_from_course_code(self): """Secondary course should be derived from secondary course code.""" primary = CourseFactory(course_code='TMA4122') secondary = CourseFactory(course_code='SIF5013') relation = ExamRelatedCourse.objects.create( primary_course=primary, secondary_course_code='SIF5013', ) assert relation.secondary_course.id == secondary.id
def test_setting_a_primary_course_as_a_secondary_one(self): """A course can't be secondary and primary at the same time.""" primary = CourseFactory(course_code='TMA4122') another_primary = CourseFactory(course_code='TMA4123') ExamRelatedCourse.objects.create( primary_course=primary, secondary_course_code='SIF5013', ) with pytest.raises(ValidationError): ExamRelatedCourse.objects.create( primary_course=another_primary, secondary_course_code='TMA4122', )
def test_creating_two_primary_courses_for_one_secondary_course(self): """One secondary course can't have two primary courses.""" primary = CourseFactory(course_code='TMA4122') new_primary = CourseFactory(course_code='TMA4123') ExamRelatedCourse.objects.create( primary_course=primary, secondary_course_code='SIF5013', ) with pytest.raises(ValidationError): ExamRelatedCourse.objects.create( primary_course=new_primary, secondary_course_code='SIF5013', )
def test_when_course_cant_be_derived_from_course_code(self): """Secondary course might not always exist in database.""" primary = CourseFactory(course_code='TMA4122') relation = ExamRelatedCourse.objects.create( primary_course=primary, secondary_course_code='SIF5013', ) assert relation.secondary_course is None
def test_derive_course_from_course_code_on_save(): """DocumentInfo model should connect course code and course on save.""" course = CourseFactory(course_code='TMA4130') exam = DocumentInfo.objects.create(course_code='TMA4130') assert exam.course == course url = 'http://www.example.com/TMA4130/2013h/oldExams/eksamen-bok_2006v.pdf' exam_url = PdfUrl(url=url) exam_url.classify() assert exam_url.exam.course == course assert exam_url.exam.content_type == DocumentInfo.EXAM
def test_primary_course_with_several_secondary_courses(self): """But one primary course may have several secondary ones.""" primary = CourseFactory(course_code='TMA4122') ExamRelatedCourse.objects.create( primary_course=primary, secondary_course_code='SIF5013', ) ExamRelatedCourse.objects.create( primary_course=primary, secondary_course_code='SIF5014', ) assert primary.secondary_courses.count() == 2
def test_derive_course_code_from_course_on_save(): """The course code should be derived from the course foreign key.""" course = CourseFactory(course_code='TMA4130') exam = DocumentInfo.objects.create(course=course) assert exam.course_code == 'TMA4130'
def test_queryset_organize_method(): """ExamURLs should be organizable in hierarchy.""" # All links are related to this course CourseFactory( full_name='Mathematics 1', display_name='Maths 1', course_code='TMA4000', ) exam1 = DocumentInfo.objects.create( course_code='TMA4000', year=2016, season=Season.SPRING, language=Language.ENGLISH, ) exam_url1 = PdfUrl.objects.create( url='http://exams.com/exam', exam=exam1, ) exam1_solutions = DocumentInfo.objects.create( course_code='TMA4000', year=2016, season=Season.SPRING, solutions=True, language=Language.ENGLISH, ) exam_url_solutions = PdfUrl.objects.create(url='http://exams.com/solution', exam=exam1_solutions) eksamen_losning = DocumentInfo.objects.create( course_code='TMA4000', year=2016, season=Season.SPRING, solutions=True, language=Language.BOKMAL, ) eksamen_url_losning = PdfUrl.objects.create( url='http://exams.com/losning', exam=eksamen_losning, ) # The URL classifier could not determine the language url_exam_2015 = DocumentInfo.objects.create( course_code='TMA4000', year=2015, season=Season.SPRING, solutions=False, language=Language.UNKNOWN, ) # But the PDF classifier managed to determine it pdf_exam_2015 = DocumentInfo.objects.create( course_code='TMA4000', year=2015, season=Season.SPRING, solutions=False, language=Language.ENGLISH, ) sha1_hash = '0000000000000000000000000000000000000000' exam_2015_pdf = Pdf(sha1_hash=sha1_hash) exam_2015_pdf.file.save(sha1_hash + '.pdf', ContentFile('exam text')) DocumentInfoSource.objects.create( document_info=pdf_exam_2015, pdf=exam_2015_pdf, ) # The pdf is scraped exam_2015_url = PdfUrl.objects.create( url='http://exams.com/exam_2015', exam=url_exam_2015, scraped_pdf=exam_2015_pdf, ) organization = DocumentInfo.objects.all().organize() assert organization == { 'TMA4000': { 'full_name': 'Mathematics 1', 'nick_name': 'Maths 1', 'years': { 2016: { 'Vår': { 'exams': { 'Engelsk': [exam_url1] }, 'solutions': { 'Bokmål': [eksamen_url_losning], 'Engelsk': [exam_url_solutions], }, }, }, 2015: { 'Vår': { 'exams': { 'Engelsk': [exam_2015_url] }, 'solutions': {}, }, }, }, }, }
def test_verify_random_pdf_view(client, django_user_model): """Test PDF verification view.""" # We have one PDF sha1_hash = '0000000000000000000000000000000000000000' pdf = Pdf(sha1_hash=sha1_hash) content = ContentFile('exam text') pdf.file.save(name=sha1_hash + '.pdf', content=content) # And three courses course1 = CourseFactory(course_code='TMA1000') course2 = CourseFactory(course_code='TMA2000') course3 = CourseFactory(course_code='TMA3000') # The PDF has been inferred to contain the two first of these courses common_docinfo_attrs = { 'language': 'Bokmål', 'year': 2010, 'solutions': False, 'content_type': 'Exam', } exam1 = DocumentInfo.objects.create( course=course1, **common_docinfo_attrs, ) DocumentInfoSource.objects.create(pdf=pdf, document_info=exam1) exam2 = DocumentInfo.objects.create( course=course2, **common_docinfo_attrs, ) DocumentInfoSource.objects.create(pdf=pdf, document_info=exam2) # We verify a random PDF in this case our PDF since there is only one user = django_user_model.objects.create_user(username='******', password='******') client.login(username='******', password='******') url = reverse('examiner:verify_random') response = client.get(url) assert response.status_code == 200 # The form instance is populated with the first exam form = response.context['form'] data = form.initial assert form.instance == exam1 assert data['language'] == 'Bokmål' assert data['pdf'] == pdf assert data['season'] is None assert data['verifier'] == user # But both courses appear in the courses field assert data['courses'].count() == 2 assert set(data['courses']) == {course1.id, course2.id} # The user now changes the 2 courses form = VerifyExamForm({ 'courses': [course2.id, course3.id], 'pdf': pdf.id, 'verifier': user.id, **common_docinfo_attrs, }) assert form.is_valid() response = client.post(url, form.data) assert response.status_code == 302 # We have two new verified exams verified_exams = DocumentInfoSource.objects.filter(verified_by__in=[user]) assert verified_exams.count() == 2 # Both are connected to our pdf exam_pdf1 = verified_exams.first() exam_pdf2 = verified_exams.last() assert exam_pdf1.pdf == pdf assert exam_pdf2.pdf == pdf assert exam_pdf1.verified_by.first() == user assert exam_pdf2.verified_by.first() == user # With two different courses docinfo1 = exam_pdf1.document_info docinfo2 = exam_pdf2.document_info assert docinfo1.course == course2 assert docinfo2.course == course3 # But all other attributes being equeal for key, value in common_docinfo_attrs.items(): assert getattr(docinfo1, key) == value assert getattr(docinfo2, key) == value # The two other unverified infos have now been removed assert not DocumentInfoSource.objects.filter( verified_by__isnull=True, ).exists() # And we have alltogether 3 DocumentInfo objects assert DocumentInfo.objects.count() == 3 # And only two through relations assert DocumentInfoSource.objects.count() == 2