Beispiel #1
0
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
Beispiel #2
0
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"})
Beispiel #3
0
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
Beispiel #4
0
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))
Beispiel #5
0
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
Beispiel #6
0
    },
    {
        "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]
Beispiel #7
0
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)
Beispiel #8
0
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"},
        )
Beispiel #9
0
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"},
        )