def test_post_submision_piks_first_instance_of_param_b( app, clear_database): # noqa: F811 with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_instructor): r = yield async_requests.post( app.url + "/assignment?course_id=course_2&assignment_id=assign_a", files=files, ) with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_student): r = yield async_requests.get( app.url + "/assignment?course_id=course_2&assignment_id=assign_a") with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_student): r = yield async_requests.post( app.url + "/submission?course_id=course_2&assignment_id=assign_a", files=files, ) assert r.status_code == 200 response_data = r.json() assert response_data["success"] is True assert response_data["note"] == "Submitted"
def test_post_location_different_each_time(app, clear_database): with patch.object( BaseHandler, "get_current_user", return_value=user_kiz_instructor ): r = yield async_requests.post( app.url + "/assignment?course_id=course_2&assignment_id=assign_a", files=files, ) r = yield async_requests.post( app.url + "/assignment?course_id=course_2&assignment_id=assign_a", files=files, ) r = yield async_requests.post( app.url + "/assignment?course_id=course_2&assignment_id=assign_a", files=files, ) r = yield async_requests.get(app.url + "/assignments?course_id=course_2") assert r.status_code == 200 response_data = r.json() assert response_data["success"] == True assert "note" not in response_data # just that it's missing paths = list(map(lambda assignment: assignment["path"], response_data["value"])) actions = list(map(lambda assignment: assignment["status"], response_data["value"])) assert len(paths) == 3 assert paths[0] != paths[1] # 1st relase is not the same path as the 2nd release assert paths[1] != paths[2] # 2nd not the same as 3rd assert paths[0] != paths[2] # 1st not the same as third assert actions == ["released", "released", "released"]
def test_post_submision_oversize_blocked(app, clear_database): # noqa: F811 with patch.object(BaseHandler, "max_buffer_size", return_value=int(50)): with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_instructor): r = yield async_requests.post( app.url + "/assignment?course_id=course_2&assignment_id=assign_a", files=files, ) with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_student): r = yield async_requests.get( app.url + "/assignment?course_id=course_2&assignment_id=assign_a") with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_student): r = yield async_requests.post( app.url + "/submission?course_id=course_2&assignment_id=assign_a", files=files, ) assert r.status_code == 200 response_data = r.json() assert response_data["success"] is False assert ( response_data["note"] == "File upload oversize, and rejected. Please reduce the files in your submission and try again." )
def test_feedback_post_authenticated_with_correct_params_student_submitter( app, clear_database): assignment_id = "assign_a" course_id = "course_2" notebook = "notebook" student = user_kiz_student timestamp = datetime.datetime.utcnow().isoformat(" ") checksum = notebook_hash( feedback_filename, make_unique_key(course_id, assignment_id, notebook, student["name"], timestamp), ) # XXX: Doing this in a separate function doesn't work for some reason (Exchange doesn't get called) kwargs = {"data": {"notebooks": [notebook]}} with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_instructor): r = yield async_requests.post( app.url + f"/assignment?course_id={course_id}&assignment_id={assignment_id}", files=files, **kwargs, ) with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_student): r = yield async_requests.get( app.url + f"/assignment?course_id={course_id}&assignment_id={assignment_id}") with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_student): r = yield async_requests.post( app.url + f"/submission?course_id={course_id}&assignment_id={assignment_id}", files=files, ) url = (f"/feedback?assignment_id={assignment_id}" f"&course_id={course_id}" f"¬ebook={notebook}" f"&student={student['name']}" f"×tamp={timestamp}" f"&checksum={checksum}") with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_student): r = yield async_requests.post(app.url + url, files=feedbacks) response_data = r.json() assert response_data["success"] is False assert response_data[ "note"] == f"User not an instructor to course {course_id}"
def test_fetch_after_rerelease_gets_different_file(app, clear_database): with patch.object( BaseHandler, "get_current_user", return_value=user_kiz_instructor ): r = yield async_requests.post( app.url + "/assignment?course_id=course_2&assignment_id=assign_a", files=files, ) r = yield async_requests.post( app.url + "/assignment?course_id=course_2&assignment_id=assign_a", files=files, ) r = yield async_requests.post( app.url + "/assignment?course_id=course_2&assignment_id=assign_a", files=files, ) with patch.object( BaseHandler, "get_current_user", return_value=user_brobbere_student ): r = yield async_requests.get( app.url + "/assignment?&course_id=course_2&assignment_id=assign_a" ) r = yield async_requests.get(app.url + "/assignments?course_id=course_2") with patch.object( BaseHandler, "get_current_user", return_value=user_kiz_instructor ): r = yield async_requests.post( app.url + "/assignment?course_id=course_2&assignment_id=assign_a", files=files, ) with patch.object( BaseHandler, "get_current_user", return_value=user_brobbere_student ): r = yield async_requests.get( app.url + "/assignment?&course_id=course_2&assignment_id=assign_a" ) r = yield async_requests.get(app.url + "/assignments?course_id=course_2") assert r.status_code == 200 response_data = r.json() assert response_data["success"] == True assert "note" not in response_data # just that it's missing paths = list(map(lambda assignment: assignment["path"], response_data["value"])) actions = list(map(lambda assignment: assignment["status"], response_data["value"])) assert len(paths) == 6 assert actions == [ "released", "released", "released", "fetched", "released", "fetched", ] assert paths[2] == paths[3] # First fetch = third release assert paths[4] == paths[5] # Second fetch = fourth release assert paths[3] != paths[5] # First fetch is not the same as the second fetch
def test_collections_with_two_users_submitting(app, clear_database): # noqa: F811 assignment_id_1 = "assign_a" assignment_id_2 = "b_assign" course_id = "course_2" notebook = "notebook" # XXX: Doing this in a separate function doesn't work for some reason # (Exchange doesn't get called) kwargs = {"data": {"notebooks": [notebook]}} with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_instructor): r = yield async_requests.post( app.url + f"/assignment?course_id={course_id}&assignment_id={assignment_id_1}", files=files, **kwargs, ) # Release r = yield async_requests.post( app.url + f"/assignment?course_id={course_id}&assignment_id={assignment_id_2}", files=files, **kwargs, ) # Release 2nd assignment # Submissions check for a released action, not a fetched one with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_student): r = yield async_requests.post( app.url + f"/submission?course_id={course_id}&assignment_id={assignment_id_1}", files=files, ) # submit with patch.object(BaseHandler, "get_current_user", return_value=user_brobbere_student): r = yield async_requests.post( app.url + f"/submission?course_id={course_id}&assignment_id={assignment_id_1}", files=files, ) # submit 2nd user with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_instructor): r = yield async_requests.get( app.url + f"/collections?course_id={course_id}&assignment_id={assignment_id_1}" ) # collect response_data = r.json() assert response_data["success"] is True assert len(response_data["value"]) == 2
def test_get_collection_with_a_blank_feedback_path_injected( app, clear_database): # noqa: F811 with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_instructor): r = yield async_requests.post( app.url + "/assignment?course_id=course_2&assignment_id=assign_a", files=files, ) with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_student): r = yield async_requests.get( app.url + "/assignment?course_id=course_2&assignment_id=assign_a") with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_student): r = yield async_requests.post( app.url + "/submission?course_id=course_2&assignment_id=assign_a", files=files, ) # Now manually inject a `feedback_fetched` action import nbexchange.models.actions from nbexchange.database import scoped_session with scoped_session() as session: action = nbexchange.models.actions.Action( user_id=3, assignment_id="assign_a", action="feedback_fetched", location=None, ) session.add(action) with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_instructor): collected_data = None r = yield async_requests.get( app.url + "/collections?course_id=course_2&assignment_id=assign_a" ) # Get the data we need to make test the call we want to make response_data = r.json() collected_data = response_data["value"][0] r = yield async_requests.get( app.url + f"/collection?course_id={collected_data['course_id']}&path={collected_data['path']}&assignment_id={collected_data['assignment_id']}" # noqa: E501 ) assert r.status_code == 200 assert r.headers["Content-Type"] == "application/gzip" assert int(r.headers["Content-Length"]) > 0
def test_post_assignments1(app): with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_instructor): r = yield async_requests.post(app.url + "/assignments?course_id=course_2") assert r.status_code == 501
def test_collections_no_post_action_even_authenticated(app, clear_database): with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_instructor): r = yield async_requests.post(app.url + "/collections?course_id=course_2") assert r.status_code == 501
def test_post_no_file_provided(app, clear_database): # noqa: F811 with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_instructor): r = yield async_requests.post( app.url + "/assignment?course_id=course_2&assignment_id=assign_a") assert r.status_code == 412
def test_post_student_cannot_release(app, clear_database): with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_student): r = yield async_requests.post( app.url + "/assignment?course_id=course_2&assignment_id=assign_a" ) assert r.status_code == 200 response_data = r.json() assert response_data["success"] == False assert response_data["note"] == "User not an instructor to course course_2"
def test_post_no_params(app, clear_database): # noqa: F811 with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_instructor): r = yield async_requests.post(app.url + "/assignment") response_data = r.json() assert response_data["success"] is False assert response_data[ "note"] == "Posting an Assigment requires a course code and an assignment code"
def test_post_release_broken_nbex_user(app, clear_database, caplog): # noqa: F811 with patch.object(BaseHandler, "get_current_user", return_value=user_kiz): r = yield async_requests.post( app.url + "/assignment?course_id=course_2&assignment_id=assign_a", files=files, ) assert r.status_code == 500 assert "Both current_course ('None') and current_role ('None') must have values. User was '1-kiz'" in caplog.text
def test_post_submision_requires_files(app, clear_database): # noqa: F811 with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_instructor): r = yield async_requests.post( app.url + "/assignment?course_id=course_2&assignment_id=assign_a", files=files, ) with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_student): r = yield async_requests.get( app.url + "/assignment?course_id=course_2&assignment_id=assign_a") with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_student): r = yield async_requests.post( app.url + "/submission?course_id=course_2&assignment_id=assign_a") assert r.status_code == 412
def test_collections_with_named_user_check_full_name_missing( app, clear_database): assignment_id_1 = "assign_a" course_id = "course_2" notebook = "notebook" student = "1-brobbere" # XXX: Doing this in a separate function doesn't work for some reason # (Exchange doesn't get called) kwargs = {"data": {"notebooks": [notebook]}} with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_instructor): r = yield async_requests.post( app.url + f"/assignment?course_id={course_id}&assignment_id={assignment_id_1}", files=files, **kwargs, ) ## Released # Submissions check for a released action, not a fetched one with patch.object(BaseHandler, "get_current_user", return_value=user_brobbere_student): r = yield async_requests.post( app.url + f"/submission?course_id={course_id}&assignment_id={assignment_id_1}", files=files, ) with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_instructor): r = yield async_requests.get( app.url + f"/collections?course_id={course_id}&assignment_id={assignment_id_1}&user_id={student}" ) response_data = r.json() assert response_data["success"] is True # 2 if run solo, 8 is run in the complete suite assert len(response_data["value"]) == 1 for value in response_data["value"]: assert value["full_name"] is None
def test_post_submision_requires_two_params(app, clear_database): # noqa: F811 with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_instructor): r = yield async_requests.post(app.url + "/submission") assert r.status_code == 200 response_data = r.json() assert response_data["success"] is False assert response_data[ "note"] == "Submission call requires both a course code and an assignment code"
def test_post_submision_checks_subscription(app, clear_database): # noqa: F811 with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_student): r = yield async_requests.post( app.url + "/submission?course_id=course_2&assignment_id=assign_c") assert r.status_code == 200 response_data = r.json() assert response_data["success"] is False assert response_data["note"] == "User not fetched assignment assign_c"
def test_post_wrong_course(app, clear_database): # noqa: F811 with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_instructor): r = yield async_requests.post( app.url + "/assignment?course_id=course_1&assignment_id=assign_a") assert r.status_code == 200 response_data = r.json() assert response_data["success"] is False assert response_data["note"] == "User not subscribed to course course_1"
def test_feedback_post_authenticated_no_params(app, clear_database): with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_instructor): r = yield async_requests.post(app.url + "/feedback", files=feedbacks) response_data = r.json() assert response_data["success"] is False assert ( response_data["note"] == "Feedback call requires a course id, assignment id, notebook name, student id, checksum and timestamp." )
def test_student_can_fetch(app, clear_database): # noqa: F811 with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_instructor): r = yield async_requests.post( app.url + "/assignment?course_id=course_2&assignment_id=assign_a", files=files, ) with patch.object(BaseHandler, "get_current_user", return_value=user_brobbere_student): r = yield async_requests.get(app.url + "/assignment?course_id=course_2&assignment_id=assign_a") assert r.status_code == 200 assert r.headers["Content-Type"] == "application/gzip" assert int(r.headers["Content-Length"]) > 0
def test_post_release_ok(app, clear_database): with patch.object( BaseHandler, "get_current_user", return_value=user_kiz_instructor ): r = yield async_requests.post( app.url + "/assignment?course_id=course_2&assignment_id=assign_a", files=files, ) assert r.status_code == 200 response_data = r.json() assert response_data["success"] == True assert response_data["note"] == "Released"
def test_post_missing_course(app, clear_database): with patch.object( BaseHandler, "get_current_user", return_value=user_kiz_instructor ): r = yield async_requests.post(app.url + "/assignment?assignment_id=assign_a") assert r.status_code == 200 response_data = r.json() assert response_data["success"] == False assert ( response_data["note"] == "Posting an Assigment requires a course code and an assignment code" )
def test_get_collection_catches_missing_path(app, clear_database): with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_instructor): r = yield async_requests.post( app.url + "/assignment?course_id=course_2&assignment_id=assign_a", files=files, ) with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_student): r = yield async_requests.get( app.url + "/assignment?course_id=course_2&assignment_id=assign_a") with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_student): r = yield async_requests.post( app.url + "/submission?course_id=course_2&assignment_id=assign_a", files=files, ) with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_instructor): collected_data = None r = yield async_requests.get( app.url + "/collections?course_id=course_2&assignment_id=assign_a" ) ## Get the data we need to make test the call we want to make response_data = r.json() collected_data = response_data["value"][0] r = yield async_requests.get( app.url + f"/collection?course_id={collected_data['course_id']}&assignment_id={collected_data['assignment_id']}" ) assert r.status_code == 200 response_data = r.json() assert response_data["success"] == False assert ( response_data["note"] == "Collection call requires a course code, an assignment code, and a path" )
def test_post_picks_first_instance_of_param_gets_it_wrong(app, clear_database): with patch.object( BaseHandler, "get_current_user", return_value=user_kiz_instructor ): r = yield async_requests.post( app.url + "/assignment?course_id=course_1&course_id=course_2&assignment_id=assign_a", files=files, ) assert r.status_code == 200 response_data = r.json() assert response_data["success"] == False assert response_data["note"] == "User not subscribed to course course_1"
def test_get_collection_broken_nbex_user(app, clear_database, caplog): # noqa: F811 with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_instructor): r = yield async_requests.post( app.url + "/assignment?course_id=course_2&assignment_id=assign_a", files=files, ) with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_student): r = yield async_requests.get( app.url + "/assignment?course_id=course_2&assignment_id=assign_a") with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_student): r = yield async_requests.post( app.url + "/submission?course_id=course_2&assignment_id=assign_a", files=files, ) with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_instructor): collected_data = None r = yield async_requests.get( app.url + "/collections?course_id=course_2&assignment_id=assign_a" ) # Get the data we need to make test the call we want to make response_data = r.json() collected_data = response_data["value"][0] with patch.object(BaseHandler, "get_current_user", return_value=user_kiz): r = yield async_requests.get( app.url + f"/collection?course_id={collected_data['course_id']}&path={collected_data['path']}&assignment_id={collected_data['assignment_id']}" # noqa: E501 ) assert r.status_code == 500 assert "Both current_course ('None') and current_role ('None') must have values. User was '1-kiz'" in caplog.text
def test_get_collection_checks_for_user_subscription( app, clear_database): # noqa: F811 with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_instructor): r = yield async_requests.post( app.url + "/assignment?course_id=course_2&assignment_id=assign_a", files=files, ) with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_student): r = yield async_requests.get( app.url + "/assignment?course_id=course_2&assignment_id=assign_a") with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_student): r = yield async_requests.post( app.url + "/submission?course_id=course_2&assignment_id=assign_a", files=files, ) with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_instructor): collected_data = None r = yield async_requests.get( app.url + "/collections?course_id=course_2&assignment_id=assign_a" ) # Get the data we need to make test the call we want to make response_data = r.json() collected_data = response_data["value"][0] r = yield async_requests.get( app.url + f"/collection?course_id=course_1&path={collected_data['path']}&assignment_id={collected_data['assignment_id']}" # noqa: E501 ) assert r.status_code == 200 response_data = r.json() assert response_data["success"] is False assert response_data["note"] == "User not subscribed to course course_1"
def test_get_collection_confirm_instructor_does_download( app, clear_database): # noqa: F811 with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_instructor): r = yield async_requests.post( app.url + "/assignment?course_id=course_2&assignment_id=assign_a", files=files, ) with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_student): r = yield async_requests.get( app.url + "/assignment?course_id=course_2&assignment_id=assign_a") with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_student): r = yield async_requests.post( app.url + "/submission?course_id=course_2&assignment_id=assign_a", files=files, ) with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_instructor): collected_data = None r = yield async_requests.get( app.url + "/collections?course_id=course_2&assignment_id=assign_a" ) # Get the data we need to make test the call we want to make response_data = r.json() collected_data = response_data["value"][0] r = yield async_requests.get( app.url + f"/collection?course_id={collected_data['course_id']}&path={collected_data['path']}&assignment_id={collected_data['assignment_id']}" # noqa: E501 ) assert r.status_code == 200 assert r.headers["Content-Type"] == "application/gzip" assert int(r.headers["Content-Length"]) > 0
def test_feedback_post_authenticated_with_params(app, clear_database): assignment_id = "my_assignment" url = (f"/feedback?assignment_id={assignment_id}" f"&course_id=course_2" f"¬ebook=faked" f"&student=faked" f"×tamp=faked" f"&checksum=faked") with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_instructor): r = yield async_requests.post(app.url + url, files=feedbacks) assert r.status_code == 404
def test_blocks_filesize(app, clear_database): with patch.object(BaseHandler, "max_buffer_size", return_value=int(50)): with patch.object( BaseHandler, "get_current_user", return_value=user_kiz_instructor ): r = yield async_requests.post( app.url + "/assignment?course_id=course_2&assignment_id=assign_a", files=files, ) assert r.status_code == 200 response_data = r.json() assert response_data["success"] == False assert ( response_data["note"] == "File upload oversize, and rejected. Please reduce the contents of the assignment, re-generate, and re-release" )
def test_assignment_missing(app, clear_database): # noqa: F811 with patch.object(BaseHandler, "get_current_user", return_value=user_kiz_instructor): r = yield async_requests.post( app.url + "/assignment?course_id=course_2&assignment_id=assign_a", files=files, ) r = yield async_requests.delete( app.url + "/assignment?course_id=course_2&assignment_id=noexist", files=files, ) assert r.status_code == 200 response_data = r.json() assert response_data["success"] is False assert response_data[ "note"] == "Missing assignment for noexist and course_2, cannot delete"