async def test_delete_quiz(client, users, quizzes, token_user): # Create a dummy quiz fake_quiz = get_fake_quiz() fake_quiz.pop("creator_id") new_quiz = { **fake_quiz, "questions": get_fake_quiz_questions(has_id=False) } new_quiz.pop("id", None) res = await client.post("/quizzes", json=new_quiz, headers={"Authorization": token_user}) assert res.status == 200 created_quiz_id = (await res.json()).get("data", {})["id"] # Without token res = await client.delete("/quizzes/{}".format(created_quiz_id)) assert res.status == 401 # Delete your own quiz res = await client.delete("/quizzes/{}".format(created_quiz_id), headers={"Authorization": token_user}) assert res.status == 200 body = await res.json() assert body is None all_quizzes = await Quiz.query.gino.all() assert len(all_quizzes) == len(quizzes) assert all(quiz.to_dict()["id"] != created_quiz_id for quiz in all_quizzes) # Delete a deleted quiz res = await client.delete("/quizzes/{}".format(created_quiz_id), headers={"Authorization": token_user}) assert res.status == 404
async def test_create_quiz(client, users, quizzes, token_user): fake_quiz = get_fake_quiz() fake_quiz.pop("creator_id") new_quiz = { **fake_quiz, "questions": get_fake_quiz_questions(has_id=False) } new_quiz.pop("id", None) # Cannot create an quiz without token res = await client.post("/quizzes", json=new_quiz) assert res.status == 401 # Create a quiz with valid args res = await client.post("/quizzes", json=new_quiz, headers={"Authorization": token_user}) assert res.status == 200 body = await res.json() assert "data" in body assert isinstance(body["data"], dict) all_quizzes = await Quiz.query.gino.all() assert len(all_quizzes) == len(quizzes) + 1 assert profile_created_from_origin(new_quiz, all_quizzes[-1].to_dict(), ignore={"questions"})
async def test_create_internal_id_quizzes(client, quizzes, token_user): """Ensure that `internal_id` cannot be created""" fake_quiz = get_fake_quiz() fake_quiz.pop("creator_id") new_quiz = { **fake_quiz, "questions": get_fake_quiz_questions(has_id=False), "internal_id": 12, } new_quiz.pop("id", None) res = await client.post("/quizzes", json=new_quiz, headers={"Authorization": token_user}) assert res.status == 400
async def test_get_questions_after_create(client, questions, quizzes, token_user): fake_quiz = get_fake_quiz() fake_quiz.pop("creator_id") quiz_questions = get_fake_quiz_questions(has_id=False) new_quiz = {**fake_quiz, "questions": quiz_questions} new_quiz.pop("id", None) # Create a quiz with valid args res = await client.post("/quizzes", json=new_quiz, headers={"Authorization": token_user}) assert res.status == 200 body = await res.json() quiz_id = body["data"]["id"] # Get the created questions res = await client.get("/quizzes/{}/questions".format(quiz_id), headers={"Authorization": token_user}) assert res.status == 200 body = await res.json() created_questions = body["data"] for question_origin, question_retrieved in zip(quiz_questions, created_questions): assert "correct_option" not in question_retrieved assert all(key in question_retrieved for key in ["text", "quiz_id", "id", "options"]) assert profile_created_from_origin(question_origin, question_retrieved, ignore={"correct_option"}) # If created quiz has the correct questions' IDs res = await client.get("/quizzes/{}".format(quiz_id), headers={"Authorization": token_user}) assert res.status == 200 body = await res.json() assert len(quiz_questions) == len(body["data"]["questions"]) assert all(quiz_question_id == created_question["id"] for quiz_question_id, created_question in zip( body["data"]["questions"], created_questions))
async def test_refresh_token(client, users): for user in users[-1:-4]: res = await client.post("/login", json={ "email": user["email"], "password": user["password"] }) assert res.status == 200 body = await res.json() assert "data" in body assert isinstance(body, dict) assert "access_token" in body and "refresh_token" in body refresh_token = body["refresh_token"] # Get a new access token res = await client.post("/refresh", headers={"Authorization": refresh_token}) assert res.status == 200 body = await res.json() assert "data" in body assert isinstance(body, dict) assert "access_token" in body new_access_token = body["access_token"] # Try to create a quiz using the created refresh_token fake_quiz = get_fake_quiz() fake_quiz.pop("creator_id") new_quiz = { **fake_quiz, "questions": get_fake_quiz_questions(has_id=False) } new_quiz.pop("id", None) # Create a quiz with valid args res = await client.post("/quizzes", json=new_quiz, headers={"Authorization": new_access_token}) assert res.status == 200
}, { "full_name": "User 1", "email": "user1", "password": "******" }, { "full_name": "User 2", "email": "user2", "password": "******" }, { "full_name": "User 3", "email": "user3", "password": "******" }, ] quizzes = [ get_fake_quiz(users[index]["id"]) for index in range(number_of_quizzes) ] questions_list = [get_fake_questions_for_quiz(quiz["id"]) for quiz in quizzes] # Update the questions' order in all quizzes for index, quiz in enumerate(quizzes): quizzes[index]["questions"] = [ question["id"] for question in questions_list[index] ] # Flatten the questions, for `setup_dev_db` questions = [item for sublist in questions_list for item in sublist]
async def test_create_quiz_with_invalid_args(client, quizzes, token_user): # Empty questions fake_quiz = get_fake_quiz() fake_quiz.pop("creator_id") new_quiz = {**fake_quiz, "questions": []} new_quiz.pop("id", None) # Create a quiz with empty questions res = await client.post("/quizzes", json=new_quiz, headers={"Authorization": token_user}) assert res.status == 400 # Invalid correct_option questions = get_fake_quiz_questions(has_id=False) questions[0]["correct_option"] = 5 new_quiz = {**fake_quiz, "questions": questions} res = await client.post("/quizzes", json=new_quiz, headers={"Authorization": token_user}) assert res.status == 400 # Invalid args res = await client.post("/quizzes", json={}, headers={"Authorization": token_user}) assert res.status == 400 res = await client.post("/quizzes", json={"id": 4}, headers={"Authorization": token_user}) assert res.status == 400 res = await client.post("/quizzes", json={"title": ""}, headers={"Authorization": token_user}) assert res.status == 400 res = await client.post( "/quizzes", json={ "title": "", "num_attempts": 2 }, headers={"Authorization": token_user}, ) assert res.status == 400 res = await client.post( "/quizzes", json={ "title": "Josh", "num_attempts": 2, "unknown_field": "" }, headers={"Authorization": token_user}, ) assert res.status == 400 res = await client.post("/quizzes", json={"created_at": 2}, headers={"Authorization": token_user}) assert res.status == 400 res = await client.post("/quizzes", json={"updated_at": 2}, headers={"Authorization": token_user}) assert res.status == 400 # Assert no new quizzes are created all_quizzes = await Quiz.query.gino.all() assert len(all_quizzes) == len(quizzes)
async def test_pagination_created_attempted_quizzes(app, client, users, questions, quizzes, token_user): # Create a fresh user, as the created user already has some previously created quizzes new_user = get_fake_user() new_user.pop("id") res = await client.post("/users", json=new_user) assert res.status == 200 body = await res.json() new_user_id = body["data"]["id"] new_user_token = await get_access_token_for_user(body["data"], app) # Create a few quizzes created_quizzes = [] for _ in range(35): fake_quiz = get_fake_quiz() fake_quiz.pop("creator_id") new_quiz = { **fake_quiz, "questions": get_fake_quiz_questions(has_id=False) } new_quiz.pop("id", None) # Create a quiz with valid args res = await client.post("/quizzes", json=new_quiz, headers={"Authorization": new_user_token}) assert res.status == 200 body = await res.json() created_quizzes.append(body["data"]) # Check pagination res = await client.get("/users/{}/quizzes/created".format(new_user_id)) assert res.status == 200 body = await res.json() assert "data" in body assert isinstance(body["data"], list) assert len(body["data"]) == 15 for created, retrieve in zip(created_quizzes[:15], body["data"]): assert profile_created_from_origin(retrieve, created, ignore={"questions", "updated_at"}) # Check second page next_page_link = body["links"]["next"] # Strip the host, as it is a testing host next_page_link = "/" + "/".join(next_page_link.split("/")[3:]) res = await client.get(next_page_link) assert res.status == 200 body = await res.json() assert "data" in body assert isinstance(body["data"], list) assert len(body["data"]) == 15 for created, retrieve in zip(created_quizzes[15:30], body["data"]): assert profile_created_from_origin(retrieve, created, ignore={"questions", "updated_at"}) # Check last page next_page_link = body["links"]["next"] # Strip the host, as it is a testing host next_page_link = "/" + "/".join(next_page_link.split("/")[3:]) res = await client.get(next_page_link) assert res.status == 200 body = await res.json() assert "data" in body assert isinstance(body["data"], list) assert len(body["data"]) == 5 for created, retrieve in zip(created_quizzes[30:], body["data"]): assert profile_created_from_origin(retrieve, created, ignore={"questions", "updated_at"}) ## ATTEMPTED # Attempt to do a few quizzes as well attempt_user_id = users[0]["id"] attempted_quizzes = created_quizzes[::-1] for quiz in created_quizzes: question_index = 5 selected_option = 3 res = await client.post( "/quizzes/{}/questions/{}/answers".format( quiz["id"], quiz["questions"][question_index]), json={"selected_option": selected_option}, headers={"Authorization": token_user}, ) assert res.status == 200 body = await res.json() # Check pagination res = await client.get( "/users/{}/quizzes/attempted".format(attempt_user_id)) assert res.status == 200 body = await res.json() assert "data" in body assert isinstance(body["data"], list) assert len(body["data"]) == 15 assert "links" in body assert "next" in body["links"] for created, retrieve in zip(attempted_quizzes[:15], body["data"]): assert profile_created_from_origin( retrieve, { **created, "num_attempts": 1, "is_finished": False }, ignore={"questions", "updated_at"}, ) # Check second page next_page_link = body["links"]["next"] # Strip the host, as it is a testing host next_page_link = "/" + "/".join(next_page_link.split("/")[3:]) res = await client.get(next_page_link) assert res.status == 200 body = await res.json() assert "data" in body assert isinstance(body["data"], list) assert len(body["data"]) == 15 for created, retrieve in zip(attempted_quizzes[15:30], body["data"]): assert profile_created_from_origin( retrieve, { **created, "num_attempts": 1, "is_finished": False }, ignore={"questions", "updated_at"}, ) # Check last page next_page_link = body["links"]["next"] # Strip the host, as it is a testing host next_page_link = "/" + "/".join(next_page_link.split("/")[3:]) res = await client.get(next_page_link) assert res.status == 200 body = await res.json() assert "data" in body assert isinstance(body["data"], list) assert len(body["data"]) == 5 for created, retrieve in zip(attempted_quizzes[30:], body["data"]): assert profile_created_from_origin( retrieve, { **created, "num_attempts": 1, "is_finished": False }, ignore={"questions", "updated_at"}, )
async def test_get_own_created_and_attempted_quizzes(app, client, users, questions, quizzes): # Create a fresh user new_user = get_fake_user() new_user.pop("id") res = await client.post("/users", json=new_user) assert res.status == 200 body = await res.json() new_user_id = body["data"]["id"] new_user_token = await get_access_token_for_user(body["data"], app) # Create a few quizzes created_quizzes = [] for _ in range(20): fake_quiz = get_fake_quiz() fake_quiz.pop("creator_id") new_quiz = { **fake_quiz, "questions": get_fake_quiz_questions(has_id=False) } new_quiz.pop("id", None) # Cannot create an quiz without token res = await client.post("/quizzes", json=new_quiz) assert res.status == 401 # Create a quiz with valid args res = await client.post("/quizzes", json=new_quiz, headers={"Authorization": new_user_token}) assert res.status == 200 body = await res.json() created_quizzes.append(body["data"]) # Attempt to do a few quizzes as well attempted_quizzes = [] for quiz_index in range(1, 17): question_index = 3 selected_option_3 = 1 res = await client.post( "/quizzes/{}/questions/{}/answers".format( quizzes[quiz_index]["id"], questions[quiz_index][question_index]["id"]), json={"selected_option": selected_option_3}, headers={"Authorization": new_user_token}, ) assert res.status == 200 body = await res.json() attempted_quizzes.append(quizzes[quiz_index]) # Check if the attempted and created quizzes are correct res = await client.get("/users/{}/quizzes/created".format(new_user_id)) assert res.status == 200 body = await res.json() assert "data" in body assert isinstance(body["data"], list) assert len(body["data"]) == 15 # Check if the created quizzes are correct for created, retrieve in zip(created_quizzes, body["data"]): assert profile_created_from_origin(retrieve, created, ignore={"questions", "updated_at"}) # Check if the attempted quizzes are correct res = await client.get("/users/{}/quizzes/attempted".format(new_user_id)) assert res.status == 200 body = await res.json() assert "data" in body assert isinstance(body["data"], list) assert len(body["data"]) == 15 for expected_quiz, actual_quiz in zip(attempted_quizzes[::-1], body["data"]): assert profile_created_from_origin( { **expected_quiz, "is_finished": False }, actual_quiz, ignore={"questions", "updated_at"}, )