def test_simple_file_assignment_task(db_test_client): from application import db from .assignment_test import test_simple_assignment with generate_random_file() as temp, generate_random_file() as task_temp: file_name = get_random_unicode(10) task_file_name = get_random_unicode(10) werk_file = FileStorage(temp, file_name) werk_task_file = FileStorage(task_temp, task_file_name) test_simple_assignment(db_test_client) teach = db.get_user("opettaja", "opettaja") c = db.select_courses_teacher(teach.id)[0] name = get_random_unicode(10) reveal = pytz.utc.localize(datetime.datetime.now()) deadline = random_datetime() a_id = db.insert_assignment(teach.id, c.id, name, deadline, reveal, [werk_file]) task_name = get_random_unicode(10) points = random.randint(5,100) t_id = db.insert_task(teach.id, a_id, task_name, points, [werk_task_file]) files = db.select_file_details(assignment_id=a_id) assert len(files)==1 file = files[0] assert file.name == secure_filename(file_name) assert file.date.date() == datetime.date.today() temp.seek(0) bin_data = temp.read() db_bin_data, name=db.get_file(file.id) assert name == file.name assert len(bin_data) > 1000 assert len(bin_data)==len(db_bin_data) assert type(bin_data)==type(db_bin_data), "Wrong types (can't compare) "+str(type(bin_data))+" vs "+str(type(db_bin_data)) assert bin_data==db_bin_data task_files = db.select_file_details(task_id=t_id) assert len(task_files)==1 file = task_files[0] task_temp.seek(0) real_task_bin_data = task_temp.read() db_bin_task_data, name = db.get_file(file.id) assert name == secure_filename(task_file_name) assert real_task_bin_data == db_bin_task_data
def test_select_file_details_multiple(db_test_client): from application import db db.insert_user("turha", "turha", "turha", "turha", role="TEACHER") user_id = db.get_user("turha","turha").id case = unittest.TestCase() case.maxDiff = None c_id, _ =db.insert_course(Course("something","somthing", datetime.datetime.now()),user_id) for _ in range(20): id_dic = create_dummy(db, user_id=user_id, course=c_id) correct_files= [] for i in range(20): rand_bytes= os.urandom(20) name = "task"+str(id_dic["task_id"])+str(i) id = file_insert_helper(db,binary_file=rand_bytes, task_id=id_dic["task_id"], name=name, user_id=user_id) correct_files.append(File(id, name, datetime.datetime.now())) files = db.select_file_details(task_id=id_dic["task_id"]) assert len(files) == 20 case.assertCountEqual(files, correct_files) correct_bytes, _ = db.get_file(id) assert rand_bytes == correct_bytes rand_bytes= os.urandom(20) id = file_insert_helper(db,binary_file=rand_bytes,submit_id=id_dic["submit_id"], name="submit_id"+str(id_dic["submit_id"]), user_id=user_id) sub_id = id_dic["submit_id"] files = db.select_file_details(submit_id=sub_id) assert len(files) == 1 assert files[0].name == "submit_id"+str(id_dic["submit_id"]) assert files[0].id == id correct_bytes, _ = db.get_file(id) assert rand_bytes == correct_bytes rand_bytes= os.urandom(20) id = file_insert_helper(db,binary_file=rand_bytes,assignment_id=id_dic["assignment_id"], name="assignment_id"+str(id_dic["task_id"]), user_id=user_id) files = db.select_file_details(assignment_id=id_dic["assignment_id"]) assert len(files) == 1 assert files[0].name == "assignment_id"+str(id_dic["assignment_id"]) assert files[0].id == id correct_bytes, _ = db.get_file(id) assert rand_bytes == correct_bytes rand_bytes= os.urandom(20) id = file_insert_helper(db,binary_file=rand_bytes,answer_id=id_dic["answer_id"], name="answer_id"+str(id_dic["task_id"]), user_id=user_id) files = db.select_file_details(answer_id=id_dic["answer_id"]) assert len(files) == 1 assert files[0].name == "answer_id"+str(id_dic["answer_id"]) assert files[0].id == id correct_bytes, _ = db.get_file(id) assert rand_bytes == correct_bytes
def task_overview(course_id, assignment_id, task_id): if current_user.role == "USER": app.logger.info("student attempted access to task overview. id: "+str(current_user.get_id())) return redirect(url_for("index")) form = None if request.method == "POST": app.logger.info("attempting answer update") form = AnswerForm(request.form) if not request.form.get("reveal_after") and not form.validate(): app.logger.info("form validation failed") pass else: app.logger.info("updating answer for "+str(task_id)) reveal = None if not request.form.get("reveal_after"): app.logger.info("custom date for reveal "+str(task_id)) reveal = pytz.timezone("Europe/Helsinki").localize(form.reveal.data) files_to_delete = request.form.getlist("del_files", int) description = None if form.description.data: description=form.description.data db.update_answer(current_user.get_id(), task_id, request.files.getlist("files"), description, reveal=reveal, files_to_delete=files_to_delete ) app.logger.info("update success, redirecting") form = None return redirect(url_for("task_overview", course_id=course_id, assignment_id=assignment_id, task_id=task_id)) app.logger.info("viewing task overview") assignment = db.select_assignment(assignment_id, task_id=task_id) if not assignment: return redirect(url_for("index")) if assignment.deadline is None: deadline_not_passed = True else: deadline_not_passed = assignment.deadline.astimezone(pytz.utc) > datetime.datetime.now(pytz.utc) try: task = assignment.tasks[0] #all assigs have at least 1 task, so will only happen for manual urls except: return redirect(url_for("index")) db.set_submits(assignment,current_user.get_id(), task_id=task.id) task.files = db.select_file_details(task_id=task_id) db.set_task_answer(task, for_student=False) assignment.set_timezones("Europe/Helsinki") if form is None: form = AnswerForm() submits = db.get_all_submits(assignment_id, task_id=task.id, convert_to_timezone = "Europe/Helsinki", join_feedback=True) all_students = db.select_students(course_id, current_user.get_id()) student_ids_with_submits = [s.id for s in all_students if submits.get(s.id)] student_ids_with_submits.append("id"+str(task_id)) session.pop("next_list", None) session["next_list"] = student_ids_with_submits print(submits) return render_template("/teacher/overview/task.html",course_id=course_id, task = task, assignment=assignment, deadline_not_passed=deadline_not_passed, form = form, students = all_students, submits = submits)
def test_select_file_details_single(db_test_client): from application import db db.insert_user("turha", "turha", "turha", "turha", role="TEACHER") user_id = db.get_user("turha","turha").id c_id, _ =db.insert_course(Course("something","somthing", datetime.datetime.now()),user_id) for _ in range(20): id_dic = create_dummy(db, user_id=user_id, course=c_id) rand_bytes= os.urandom(20) id = file_insert_helper(db,binary_file=rand_bytes, task_id=id_dic["task_id"], name="task"+str(id_dic["task_id"]), user_id=user_id) files = db.select_file_details(task_id=id_dic["task_id"]) assert len(files) == 1 assert files[0].name == "task"+str(id_dic["task_id"]) assert files[0].id == id assert rand_bytes, _ == db.get_file(id) rand_bytes= os.urandom(20) id = file_insert_helper(db,binary_file=rand_bytes,submit_id=id_dic["submit_id"], name="submit_id"+str(id_dic["submit_id"]), user_id=user_id) sub_id = id_dic["submit_id"] files = db.select_file_details(submit_id=sub_id) assert len(files) == 1 assert files[0].name == "submit_id"+str(id_dic["submit_id"]) assert files[0].id == id assert rand_bytes, _ == db.get_file(id) rand_bytes= os.urandom(20) id = file_insert_helper(db,binary_file=rand_bytes,assignment_id=id_dic["assignment_id"], name="assignment_id"+str(id_dic["task_id"]), user_id=user_id) files = db.select_file_details(assignment_id=id_dic["assignment_id"]) assert len(files) == 1 assert files[0].name == "assignment_id"+str(id_dic["assignment_id"]) assert files[0].id == id db_bytes, name = db.get_file(id) assert rand_bytes == db_bytes rand_bytes= os.urandom(20) id = file_insert_helper(db,binary_file=rand_bytes,answer_id=id_dic["answer_id"], name="answer_id"+str(id_dic["task_id"]), user_id=user_id) files = db.select_file_details(answer_id=id_dic["answer_id"]) assert len(files) == 1 assert files[0].name == "answer_id"+str(id_dic["answer_id"]) assert files[0].id == id assert rand_bytes, _ == db.get_file(id)
def view_task(course_id, assignment_id, task_id): if request.method == "GET": assignment = db.select_assignment(assignment_id, task_id=task_id) if assignment.deadline is None: deadline_not_passed = True else: deadline_not_passed = assignment.deadline.astimezone( pytz.utc) > datetime.datetime.now(pytz.utc) try: task = assignment.tasks[ 0] #all assigs have at least 1 task, so will only happen for manual urls except: return redirect(url_for("index")) db.set_submits(assignment, current_user.get_id(), task_id=task.id) task.files = db.select_file_details(task_id=task.id) db.set_task_answer(task, for_student=True) assignment.set_timezones("Europe/Helsinki") submit = assignment.submits[0] points = "" if submit: feedback = db.select_feedback(current_user.get_id(), submit_id=submit.id) if feedback: points = feedback.points return render_template("/student/assignment/view_task.html", course_id=course_id, task=task, assignment=assignment, deadline_not_passed=deadline_not_passed, comment_target="ts:" + str(task_id), points=points) else: if current_user.role != "USER": return redirect(url_for("index")) files = request.files.getlist("files") db.update_submit(current_user.get_id(), task_id, assignment_id, files) return redirect( url_for("view_task", course_id=course_id, assignment_id=assignment_id, task_id=task_id))
def test_large_assignment_with_files_insert_with_access_rights(db_test_client): from application import db teachers = insert_users(db, 8, roles=["TEACHER"]) assert len(teachers)>=8 students = insert_users(db, 50, roles=["USER"]) assert len(students) > 49 all_courses = [] for t in teachers: insert_courses(db, t.id, 6) t_c = db.select_courses_teacher(t.id) assert len(t_c) ==6 all_courses+=t_c assert len(all_courses) student_enlists = {} for s in students: student_enlists[s.id] = [] courses_to_enlist =random.sample(all_courses, random.randint(4,8)) for c in courses_to_enlist: db.enlist_student(c.code, s.id) student_enlists[s.id].append(c) assert student_enlists file_storage = FileMultiDict() not_hidden_file_storage = FileMultiDict() assert len(teachers) == 8 for t in teachers: courses = db.select_courses_teacher(t.id) assert len(courses) == 6 for c in courses: for _ in range(5): hidden = bool(random.randint(0,1)) a_name, a_reveal, a_deadline = random_assignment(c.id, t.id, hidden=hidden) werk_files = [] for _ in range(random.randint(2,4)): file = generate_random_file(length=10) file_name = secure_filename(get_random_unicode(20)) werk_file = FileStorage(file, file_name) werk_files.append(werk_file) a_id = db.insert_assignment(t.id, c.id, a_name, a_deadline, a_reveal,werk_files) with db.engine.connect() as conn: sql = select([db.assignment]).where(db.assignment.c.id == a_id) rs = conn.execute(sql) row = rs.first() assert row is not None assert row[db.assignment.c.id] == a_id assert row[db.assignment.c.name] == a_name for file in werk_files: file_storage.add_file("a"+str(a_id), file, file.filename) if not hidden: not_hidden_file_storage.add_file("a"+str(a_id), file, file.filename) file.close() assert werk_files[0].filename assert len(file_storage.getlist("a"+str(a_id))) >=2 assert file_storage.getlist("a"+str(a_id))[0].filename == werk_files[0].filename for __ in range(random.randint(3,5)): werk_files = [] n = random.randint(1,3) for _ in range(n): file = generate_random_file(length=10) file_name = secure_filename(get_random_unicode(20)) werk_file = FileStorage(file, file_name) werk_files.append(werk_file) task = random_task(a_id, werk_files) task.id = db.insert_task(t.id, a_id, task.description, task.points, werk_files) for file in werk_files: file_storage.add_file("t"+str(task.id), file, file.filename) if not hidden: not_hidden_file_storage.add_file("t"+str(task.id), file, file.filename) file.close() assert len(file_storage.getlist("t"+str(task.id))) == n for t in teachers: courses = db.select_courses_teacher(t.id) for c in courses: db.set_assignments(c, for_student=False) for a in c.assignments: assert isinstance(a, Assignment) assert not a.files a.files = db.select_file_details(assignment_id=a.id) correct_files = file_storage.getlist("a"+str(a.id)) assert len(correct_files)>=2 correct_file_names = [file.filename for file in correct_files] db_filenames = [file.name for file in a.files] case = unittest.TestCase() case.assertCountEqual(correct_file_names, db_filenames), "incorrect filenames in db filename for assign "+str(a.id) for file in a.files: db_files = db.select_file_details(file_id =file.id) assert len(db_files)==1 assert db_files[0] == file for t in a.tasks: assert isinstance(t, Task) t_id = t.id correct_files = file_storage.getlist("t"+str(t_id)) t.files = db.select_file_details(task_id=t_id) assert len(correct_files)>=1 correct_file_names = [file.filename for file in correct_files] db_filenames = [file.name for file in t.files] case.assertCountEqual(correct_file_names, db_filenames), "incorrect filenames in db filename for task "+str(t.id) for file in t.files: db_files = db.select_file_details(file_id = file.id) assert len(db_files)==1 assert db_files[0] == file assert len(students) > 30 for s in students: courses = student_enlists[s.id] db_courses = db.select_courses_student(s.id) case = unittest.TestCase() case.assertCountEqual(courses, db_courses) assert db_courses for c in db_courses: db.set_assignments(c, for_student=True) for a in c.assignments: assert isinstance(a, Assignment) assert a.reveal <= pytz.utc.localize(datetime.datetime.utcnow()) a.files=db.select_file_details(assignment_id=a.id) correct_files = not_hidden_file_storage.getlist("a"+str(a.id)) correct_file_names = [file.filename for file in correct_files] db_filenames = [file.name for file in a.files] case = unittest.TestCase() case.assertCountEqual(correct_file_names, db_filenames)
def test_large_answer_insert_and_update(db_test_client): from application import db visible_reveal = pytz.utc.localize( datetime.datetime.utcnow()) - datetime.timedelta(minutes=1) teacher = insert_users(db, 1, roles=["TEACHER"])[0] course_id, _ = db.insert_course( Course("something", "somthing", visible_reveal, visible_reveal), teacher.id) f = generate_random_file() file_name = secure_filename(get_random_unicode(30)) werk_file = FileStorage(f, file_name) assignment_id = db.insert_assignment(teacher.id, course_id, "somthing", random_datetime(), visible_reveal, [werk_file]) werk_file.close() all_answers = [] visible_answers = [] visible_tasks = [] correct_files = FileMultiDict() for _ in range(100): task_id = db.insert_task(teacher.id, assignment_id, get_random_unicode(20), 20, []) hidden = random.randint(0, 1) if not hidden: visible_tasks.append(task_id) reveal = visible_reveal else: reveal = random_datetime() files = [] for i in range(3): f = generate_random_file(length=10) file_name = str(task_id) + "t" + str(i) werk_file = FileStorage(f, file_name) files.append(werk_file) correct_files.add_file(task_id, werk_file, werk_file.filename) desc = get_random_unicode(30) id = db.update_answer(teacher.id, task_id, files, desc, reveal=reveal) answer = Answer(id, desc, reveal.replace(tzinfo=None), db.select_file_details(answer_id=id)) all_answers.append(answer) if not hidden: visible_answers.append(answer) for f in files: f.close() assignment = db.select_assignment(assignment_id, for_student=False) all_db_answers = [] case = unittest.TestCase() assert len(assignment.tasks) == 100 for t in assignment.tasks: assert isinstance(t, Task) db.set_task_answer(t, for_student=False) assert t.answer is not None a = t.answer assert isinstance(a, Answer) assert len(a.files) == 3 correct_filenames = [ file.filename for file in correct_files.getlist(t.id) ] assert len(correct_filenames) == 3 db_filenames = [file.name for file in a.files] case.assertCountEqual(db_filenames, correct_filenames) all_db_answers.append(a) assert len(all_answers) == len(all_db_answers) case.maxDiff = None case.assertCountEqual(all_answers, all_db_answers) assignment = db.select_assignment(assignment_id, for_student=True) assert len(assignment.tasks) == 100 db_visibles = [] for t in assignment.tasks: assert isinstance(t, Task) db.set_task_answer(t, for_student=True) if t.id not in visible_tasks: assert t.answer is None continue assert t.answer is not None db_visibles.append(t.answer) a = t.answer assert isinstance(a, Answer) assert len(a.files) == 3 correct_filenames = [ file.filename for file in correct_files.getlist(t.id) ] assert len(correct_filenames) == 3 db_filenames = [file.name for file in a.files] case.assertCountEqual(db_filenames, correct_filenames) case.assertCountEqual(db_visibles, visible_answers)