Ejemplo n.º 1
0
async def test_create_user(client, users):
    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()
    assert "data" in body
    assert isinstance(body["data"], dict)

    all_users = await User.query.gino.all()
    assert len(all_users) == len(users) + 1
    assert profile_created_from_origin(new_user, all_users[-1].to_dict())

    # Ignore param args
    # POST request will have its query parameter (args) ignored.
    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()
    assert "data" in body
    assert isinstance(body["data"], dict)

    all_users = await User.query.gino.all()
    assert len(all_users) == len(users) + 2
    assert profile_created_from_origin(new_user, all_users[-1].to_dict())
Ejemplo n.º 2
0
async def test_get_quizzes_with_after_id(client, quizzes, token_user):
    # Use after_id in query parameter.
    res = await client.get(
        "/quizzes?after_id={}".format(quizzes[2]["id"]),
        headers={"Authorization": token_user},
    )
    assert res.status == 200

    body = await res.json()
    assert "data" in body
    assert isinstance(body["data"], list)
    assert len(body["data"]) == 15  # Default offset for quiz is 15

    # Check if all profiles match from id 3 to 18
    assert all(
        profile_created_from_origin(origin, created)
        for origin, created in zip(quizzes[3:18], body["data"]))

    # Check that next page is valid
    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,
                           headers={"Authorization": token_user})
    assert res.status == 200

    body = await res.json()
    assert "data" in body
    assert isinstance(body["data"], list)
    assert len(body["data"]) == len(
        quizzes[18:])  # Default offset for quiz is 15

    # Check if all profiles match from id 4 to 19
    assert all(
        profile_created_from_origin(origin, created)
        for origin, created in zip(quizzes[18:], body["data"]))

    # Check that next page is empty
    # Check that next page is valid
    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,
                           headers={"Authorization": token_user})
    assert res.status == 200

    body = await res.json()
    assert "data" in body
    assert isinstance(body["data"], list)
    assert not body["data"]

    # Invalid after_id
    res = await client.get("/quizzes?after_id=3",
                           headers={"Authorization": token_user})
    assert res.status == 404

    res = await client.get("/quizzes?after_id=",
                           headers={"Authorization": token_user})
    assert res.status == 400
Ejemplo n.º 3
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"})
Ejemplo n.º 4
0
async def test_get_questions(client, questions, quizzes, token_user):
    # Without token
    res = await client.get("/quizzes/{}/questions".format(quizzes[2]["id"]))
    assert res.status == 401

    # Get one quiz with id
    res = await client.get(
        "/quizzes/{}/questions".format(quizzes[2]["id"]),
        headers={"Authorization": token_user},
    )
    assert res.status == 200

    body = await res.json()
    assert "data" in body
    assert isinstance(body["data"], list)
    for question_origin, question_retrieved in zip(questions[2], body["data"]):
        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"})

    # quiz doesnt exist
    res = await client.get("/quizzes/{}/questions".format("9" * 32),
                           headers={"Authorization": token_user})
    assert res.status == 404

    res = await client.get("/quizzes/3/questions",
                           headers={"Authorization": token_user})
    assert res.status == 404
Ejemplo n.º 5
0
async def test_update_one_user(client, users, token_user):
    new_changes = {
        "full_name": "this name surely doesnt exist",
        "password": "******",
    }

    # Without token
    res = await client.patch("/users/{}".format(users[0]["id"]),
                             json=new_changes)
    assert res.status == 401

    # An user cannot update another user
    res = await client.patch(
        "/users/{}".format(users[3]["id"]),
        json=new_changes,
        headers={"Authorization": token_user},
    )
    assert res.status == 403

    # With id
    res = await client.patch(
        "/users/{}".format(users[0]["id"]),
        json=new_changes,
        headers={"Authorization": token_user},
    )
    assert res.status == 200

    body = await res.json()
    assert "data" in body
    assert isinstance(body["data"], dict)
    updated_user = await get_one(User, internal_id=1)
    updated_user = updated_user.to_dict()

    ## Assert the new password has been updated
    assert profile_created_from_origin(
        {
            **body["data"], "password": hash_password(new_changes["password"])
        },
        updated_user,
        ignore=["updated_at"],
    )

    # User doesnt exist
    res = await client.patch(
        "/users/{}".format("9" * 32),
        json=new_changes,
        headers={"Authorization": token_user},
    )
    assert res.status == 404

    # Update to a weak password
    new_changes = {"password": "******"}
    res = await client.patch(
        "/users/{}".format(users[1]["id"]),
        json=new_changes,
        headers={"Authorization": token_user},
    )
    assert res.status == 400
Ejemplo n.º 6
0
async def test_login_user(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
        assert "user" in body
        assert profile_created_from_origin(user, body["user"])

    # Login with wrong password
    user = users[-1]
    res = await client.post("/login",
                            json={
                                "email": user["email"],
                                "password": "******"
                            })
    assert res.status == 401

    # Login with weak password
    user = users[-1]
    res = await client.post("/login",
                            json={
                                "email": user["email"],
                                "password": "******"
                            })
    assert res.status == 400

    # Login with missing password
    user = users[-1]
    res = await client.post("/login", json={"email": user["email"]})
    assert res.status == 400

    # Login with missing email
    user = users[-1]
    res = await client.post("/login", json={"password": user["password"]})
    assert res.status == 400
Ejemplo n.º 7
0
async def test_get_one_user(client, users):
    res = await client.get("/users/{}".format(users[0]["id"]))
    assert res.status == 200

    body = await res.json()
    assert "data" in body
    assert isinstance(body["data"], dict)
    assert profile_created_from_origin(users[0], body["data"])

    # User doesnt exist
    res = await client.get("/users/{}".format("9" * 32))
    assert res.status == 404

    res = await client.get("/users/true")
    assert res.status == 404

    # Invalid query
    res = await client.get("/users?id=")
    assert res.status == 400
Ejemplo n.º 8
0
async def test_get_users_with_after_id(client, users):
    # Use after_id in query parameter.
    res = await client.get("/users?after_id={}".format(users[2]["id"]))
    assert res.status == 200

    body = await res.json()
    assert "data" in body
    assert isinstance(body["data"], list)
    assert len(body["data"]) == 15  # Default offset for User is 15

    # Check if all profiles match from id 4 to 19
    assert all(
        profile_created_from_origin(origin, created)
        for origin, created in zip(users[3:20], body["data"]))

    # Invalid after_id
    res = await client.get("/users?after_id=2")
    assert res.status == 404

    res = await client.get("/users?after_id=")
    assert res.status == 400
Ejemplo n.º 9
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))
Ejemplo n.º 10
0
async def test_replace_user(client, users, token_user):
    new_user = get_fake_user()
    new_user.pop("id")

    # Missing token
    res = await client.put("/users/{}".format(users[0]["id"]), json=new_user)
    assert res.status == 401

    # Valid request
    res = await client.put(
        "/users/{}".format(users[0]["id"]),
        json=new_user,
        headers={"Authorization": token_user},
    )
    assert res.status == 200

    body = await res.json()
    assert "data" in body
    assert isinstance(body["data"], dict)

    updated_user = await get_one(User, internal_id=1)
    updated_user = updated_user.to_dict()
    assert profile_created_from_origin(new_user, updated_user)
Ejemplo n.º 11
0
async def test_get_one_quiz(client, quizzes, token_user):
    # Without token
    # Get one quiz with id
    res = await client.get("/quizzes/{}".format(quizzes[2]["id"]))
    assert res.status == 401

    # Get one quiz with id
    res = await client.get("/quizzes/{}".format(quizzes[2]["id"]),
                           headers={"Authorization": token_user})
    assert res.status == 200

    body = await res.json()
    assert "data" in body
    assert isinstance(body["data"], dict)
    assert profile_created_from_origin(quizzes[2], body["data"])
    assert body["data"]["num_attempts"] == 0

    # quiz doesnt exist
    res = await client.get("/quizzes/{}".format("9" * 32),
                           headers={"Authorization": token_user})
    assert res.status == 404

    res = await client.get("/quizzes/3", headers={"Authorization": token_user})
    assert res.status == 404
Ejemplo n.º 12
0
async def test_get_all_quizzes(client, quizzes, token_user):
    # Without token
    res = await client.get("/quizzes")
    assert res.status == 401

    res = await client.get("/quizzes", headers={"Authorization": token_user})
    assert res.status == 200

    body = await res.json()
    assert "data" in body
    assert isinstance(body["data"], list)
    assert len(body["data"]) == 15  # Default offset for quiz is 15
    assert all(
        profile_created_from_origin(origin, created)
        and created["num_attempts"] == 0
        for origin, created in zip(quizzes, body["data"]))

    # GET request will have its body ignored.
    res = await client.get("/quizzes",
                           json={"num_attempts": 0},
                           headers={"Authorization": token_user})
    assert res.status == 200

    body = await res.json()
    assert "data" in body
    assert isinstance(body["data"], list)
    assert len(body["data"]) == 15  # Default offset for quiz is 15

    # Get one quiz by id with many=True
    res = await client.get("/quizzes?id={}".format(quizzes[2]["id"]),
                           headers={"Authorization": token_user})
    assert res.status == 200

    body = await res.json()
    assert "data" in body
    assert isinstance(body["data"], list)
    assert len(body["data"]) == 1
    assert profile_created_from_origin(quizzes[2], body["data"][0])

    ## LIMIT ##
    # No quizzes
    res = await client.get("/quizzes?limit=0",
                           headers={"Authorization": token_user})
    assert res.status == 200

    body = await res.json()
    assert "data" in body
    assert isinstance(body["data"], list)
    assert not body["data"]

    # 10 quizzes
    res = await client.get("/quizzes?limit=10",
                           headers={"Authorization": token_user})
    assert res.status == 200

    body = await res.json()
    assert "data" in body
    assert isinstance(body["data"], list)
    assert len(body["data"]) == 10
    assert all(
        profile_created_from_origin(origin, created)
        for origin, created in zip(quizzes[:10], body["data"]))

    # -1 quizzes
    res = await client.get("/quizzes?limit=-1",
                           headers={"Authorization": token_user})
    assert res.status == 400
Ejemplo n.º 13
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"},
        )
Ejemplo n.º 14
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"},
        )
Ejemplo n.º 15
0
async def test_get_all_users(client, users):
    res = await client.get("/users")
    assert res.status == 200

    body = await res.json()
    assert "data" in body
    assert isinstance(body["data"], list)
    assert len(body["data"]) == 15  # Default offset for User is 15
    assert all(
        profile_created_from_origin(origin, created)
        for origin, created in zip(users, body["data"]))

    # GET request will have its body ignored.
    res = await client.get("/users", json={"id": 3})
    assert res.status == 200

    body = await res.json()
    assert "data" in body
    assert isinstance(body["data"], list)
    assert len(body["data"]) == 15  # Default offset for User is 15

    # Get one user by id
    res = await client.get("/users?id={}".format(users[2]["id"]))
    assert res.status == 200

    body = await res.json()
    assert "data" in body
    assert isinstance(body["data"], list)
    assert len(body["data"]) == 1
    assert profile_created_from_origin(users[2], body["data"][0])

    ## LIMIT ##
    # No users
    res = await client.get("/users?limit=0")
    assert res.status == 200

    body = await res.json()
    assert "data" in body
    assert isinstance(body["data"], list)
    assert not body["data"]

    # 10 users
    res = await client.get("/users?limit=10")
    assert res.status == 200

    body = await res.json()
    assert "data" in body
    assert isinstance(body["data"], list)
    assert len(body["data"]) == 10
    assert all(
        profile_created_from_origin(origin, created)
        for origin, created in zip(users[:10], body["data"]))

    # Get the next 10 users
    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"]) == 10
    assert all(
        profile_created_from_origin(origin, created)
        for origin, created in zip(users[10:20], body["data"]))

    # -1 users
    res = await client.get("/users?limit=-1")
    assert res.status == 400
Ejemplo n.º 16
0
async def test_replace_user_with_invalid_args(client, users):
    res = await client.put("/users/{}".format(users[0]["id"]), json={})
    assert res.status == 400

    res = await client.put("/users/{}".format(users[0]["id"]), json={"id": 4})
    assert res.status == 400

    res = await client.put("/users/{}".format(users[0]["id"]),
                           json={"full_name": ""})
    assert res.status == 400

    res = await client.put("/users/{}".format(users[0]["id"]),
                           json={"full_name": ""})
    assert res.status == 400

    res = await client.put("/users/{}".format(users[0]["id"]),
                           json={
                               "full_name": "Josh",
                               "password": ""
                           })
    assert res.status == 400

    res = await client.put("/users/{}".format(users[0]["id"]),
                           json={"email": ""})
    assert res.status == 400

    res = await client.put("/users/{}".format(users[0]["id"]),
                           json={"location": 2})
    assert res.status == 400

    res = await client.put("/users/{}".format(users[0]["id"]),
                           json={"created_at": 2})
    assert res.status == 400

    res = await client.put("/users/{}".format(users[0]["id"]),
                           json={"updated_at": 2})
    assert res.status == 400

    # Invalid or weak password
    res = await client.put(
        "/users/{}".format(users[0]["id"]),
        json={
            "full_name": "Josh",
            "password": "******"
        },
    )
    assert res.status == 400

    res = await client.put(
        "/users/{}".format(users[0]["id"]),
        json={
            "full_name": "Josh",
            "password": "******"
        },
    )
    assert res.status == 400

    # Assert no new users are created
    all_users = await User.query.gino.all()
    assert len(all_users) == len(users)
    updated_user = await get_one(User, internal_id=1)
    updated_user = updated_user.to_dict()
    assert profile_created_from_origin(users[0], updated_user)