def add_users(db: Session) -> None:
    """Add demo users to db."""

    one = User(id=USER_ONE_ID,
               email="*****@*****.**",
               username="******",
               password_hash=SECRET)
    db.add(one)
    logger.info("User added", username=one.username)

    two = User(id=USER_TWO_ID,
               email="*****@*****.**",
               username="******",
               password_hash=SECRET)
    db.add(two)
    two.follows.append(one)
    logger.info("User added", username=two.username)

    # Postman tests expect this user to be present
    johnjacob = User(
        id=USER_JOHNJACOB_ID,
        email="*****@*****.**",
        username="******",
        password_hash=SECRET,
    )
    db.add(johnjacob)
    johnjacob.follows.append(one)
    logger.info("User added", username=johnjacob.username)

    db.flush()
def test_favorite_unfavorite_article(
    testapp: TestApp, db: Session, democontent: None
) -> None:
    """Test POST/DELETE /api/articles/{slug}/favorite."""
    user = User.by_username("one", db=db)
    assert user.favorites == []  # type: ignore

    res = testapp.post_json(
        "/api/articles/foo/favorite",
        headers={"Authorization": f"Token {USER_ONE_JWT}"},
        status=200,
    )
    assert res.json["article"]["favorited"] is True
    assert res.json["article"]["favoritesCount"] == 1
    user = User.by_username("one", db=db)
    assert [article.slug for article in user.favorites] == ["foo"]  # type: ignore

    res = testapp.delete(
        "/api/articles/foo/favorite",
        headers={"Authorization": f"Token {USER_ONE_JWT}"},
        status=200,
    )
    user = User.by_username("one", db=db)
    assert res.json["article"]["favorited"] is False
    assert res.json["article"]["favoritesCount"] == 0
    assert user.favorites == []  # type: ignore
def add_articles(db: Session) -> None:
    """Add demo articles to db."""

    foo = Article(
        id=ARTICLE_FOO_ID,
        slug="foo",
        title="Foö",
        description="Foö desc",
        body="Foö body",
        author=User.by_username("one", db=db),
        created=datetime(2019, 1, 1, 1, 1, 1),
        updated=datetime(2019, 2, 2, 2, 2, 2),
        tags=[Tag(name="dogs"), Tag(name="cats")],
        comments=[
            Comment(
                id=99,
                body="I like this!",
                author=User.by_username("two", db=db),
                created=datetime(2019, 7, 7, 7, 7, 7),
                updated=datetime(2019, 8, 8, 8, 8, 8),
            )
        ],
    )

    db.add(foo)
    logger.info("Article added", slug=foo.slug)

    bar = Article(
        id=ARTICLE_BAR_ID,
        slug="bar",
        title="Bär",
        description="Bär desc",
        body="Bär body",
        author=User.by_username("one", db=db),
        created=datetime(2019, 3, 3, 3, 3, 3),
        updated=datetime(2019, 4, 4, 4, 4, 4),
    )
    db.add(bar)
    logger.info("Article added", slug=bar.slug)

    # Postman tests require this user to have at least one article
    johnjacob = Article(
        id=ARTICLE_JOHNJACOB_ID,
        slug="i-am-johnjacob",
        title="I am John Jacob",
        description="johnjacob desc",
        body="johnjacob body",
        author=User.by_username("johnjacob", db=db),
        created=datetime(2019, 5, 5, 5, 5, 5),
        updated=datetime(2019, 6, 6, 6, 6, 6),
    )
    db.add(johnjacob)
    logger.info("Article added", slug=johnjacob.slug)

    db.flush()
def test_json_renderer(db: Session, democontent: None) -> None:
    """Test that Article is correctly rendered for an OpenAPI JSON response."""
    user = User.by_username("two", db=db)
    article = Article.by_slug("foo", db=db)

    request = DummyRequest()
    request.user = user

    renderer = json_renderer()
    output = renderer(None)(article, {"request": request})

    assert json.loads(output) == {
        "author": {
            "bio": None,
            "following": True,
            "image": None,
            "username": "******"
        },
        "body": "Foö body",
        "createdAt": "2019-01-01T01:01:01.000Z",
        "description": "Foö desc",
        "favorited": False,
        "favoritesCount": 0,
        "slug": "foo",
        "tagList": ["dogs", "cats"],
        "title": "Foö",
        "updatedAt": "2019-02-02T02:02:02.000Z",
    }
def test_register(testapp: TestApp, db: Session, democontent: None) -> None:
    """Test POST /api/users."""
    res = testapp.post_json(
        "/api/users",
        {
            "user": {
                "email": "*****@*****.**",
                "password": "******",
                "username": "******"
            }
        },
        status=201,
    )

    response = copy.deepcopy(res.json)
    response["user"]["token"] = jwt.decode(res.json["user"]["token"],
                                           "secret",
                                           algorithms=["HS512"])
    user = User.by_username("foo", db=db)
    assert response == {
        "user": {
            "email": "*****@*****.**",
            "token": {
                "sub": str(user.id),
                "iat": 1546300800
            },  # type: ignore
            "username": "******",
            "bio": None,
            "image": None,
        }
    }
예제 #6
0
def test_follow(db: Session, democontent: None) -> None:
    """Test following a user."""
    one = User.by_username("one", db)
    two = User.by_username("two", db)

    assert two not in one.follows  # type: ignore

    one.follow(two)  # type: ignore
    assert two in one.follows  # type: ignore

    one.follow(two)  # type: ignore # again, to test idempotence
    assert two in one.follows  # type: ignore

    one.unfollow(two)  # type: ignore
    assert two not in one.follows  # type: ignore

    one.unfollow(two)  # type: ignore # again, to test idempotence
    assert two not in one.follows  # type: ignore
예제 #7
0
def login(request: Request) -> UserResponse:
    """User logs in."""
    body = request.openapi_validated.body

    user = User.by_email(body.user.email, db=request.db)
    if user and user.verify_password(body.user.password):
        return {"user": user}

    raise exception_response(
        422, json_body={"errors": {"email or password": ["is invalid"]}}
    )
def test_follow_unfollow_profile(testapp: TestApp, db: Session,
                                 democontent: None) -> None:
    """Test POST/DELETE /api/profiles/{username}/follow."""
    one = User.by_username("one", db=db)
    two = User.by_username("two", db=db)
    assert one.follows == []  # type: ignore

    res = testapp.post_json(
        "/api/profiles/two/follow",
        headers={"Authorization": f"Token {USER_ONE_JWT}"},
        status=200,
    )
    assert res.json == {
        "profile": {
            "username": "******",
            "bio": None,
            "image": None,
            "following": True
        }
    }
    one = User.by_username("one", db=db)  # refetch db values
    assert [u.username
            for u in one.follows] == [  # type: ignore  # pragma: no branch
                u.username for u in [two]  # type: ignore
            ]

    res = testapp.delete(
        "/api/profiles/two/follow",
        headers={"Authorization": f"Token {USER_ONE_JWT}"},
        status=200,
    )
    assert res.json == {
        "profile": {
            "username": "******",
            "bio": None,
            "image": None,
            "following": False
        }
    }
    one = User.by_username("one", db=db)  # refetch db values
    assert one.follows == []  # type: ignore
예제 #9
0
def register(request: Request) -> UserResponse:
    """User registers to Conduit app."""
    body = request.openapi_validated.body

    user = User(
        email=body.user.email,
        username=body.user.username,
        password_hash=argon2.hash(body.user.password),
    )
    request.db.add(user)
    request.db.flush()  # so that user.id is set and JWT token can be generated
    request.response.status_code = 201
    return {"user": user}
def test_json_renderer(db: Session, democontent: None) -> None:
    """Test that Profile is correctly rendered for an OpenAPI JSON response."""
    user = User.by_username("one", db=db)
    request = DummyRequest()
    request.user = user

    profile = Profile(user=user)  # type: ignore

    renderer = json_renderer()
    output = renderer(None)(profile, {"request": request})

    assert json.loads(output) == {
        "username": "******",
        "following": False,
        "bio": None,
        "image": None,
    }
예제 #11
0
def test_favorite(db: Session, democontent: None) -> None:
    """Test favoriting an article."""
    user = User.by_username("one", db)
    article = Article.by_slug("foo", db)

    assert article not in user.favorites  # type: ignore

    user.favorite(article)  # type: ignore
    assert article in user.favorites  # type: ignore

    user.favorite(article)  # type: ignore # again, to test idempotence
    assert article in user.favorites  # type: ignore

    user.unfavorite(article)  # type: ignore
    assert article not in user.favorites  # type: ignore

    user.unfavorite(article)  # type: ignore # again, to test idempotence
    assert article not in user.favorites  # type: ignore
예제 #12
0
def test_json_renderer(db: Session, democontent: None) -> None:
    """Test that Comment is correctly rendered for an OpenAPI JSON response."""
    user = User.by_username("two", db=db)
    article = Article.by_slug("foo", db=db)
    comment = article.comments[0]  # type: ignore

    request = DummyRequest()
    request.user = user

    renderer = json_renderer()
    output = renderer(None)(comment, {"request": request})

    assert json.loads(output) == {
        "id": 99,
        "body": "I like this!",
        "createdAt": "2019-07-07T07:07:07.000Z",
        "updatedAt": "2019-08-08T08:08:08.000Z",
        "author": {"username": "******", "bio": None, "image": None, "following": False},
    }
예제 #13
0
def test_json_renderer(dummy_request: DummyRequest) -> None:
    """Test that User is correctly rendered for an OpenAPI JSON response."""
    dummy_request.create_jwt_token = mock.Mock()
    dummy_request.create_jwt_token.return_value = "token"
    user = User(id=1,
                username="******",
                email="*****@*****.**",
                bio="biö",
                image="imäge")

    renderer = json_renderer()
    output = renderer(None)(user, {"request": dummy_request})

    assert json.loads(output) == {
        "bio": "biö",
        "email": "*****@*****.**",
        "image": "imäge",
        "token": "token",
        "username": "******",
    }
예제 #14
0
def articles(request: Request) -> MultipleArticlesResponse:
    """Get recent articles globally."""

    q = request.db.query(Article)

    if request.openapi_validated.parameters["query"].get("author"):
        author = User.by_username(
            request.openapi_validated.parameters["query"]["author"],
            db=request.db)
        q = q.filter(Article.author == author)

    if request.openapi_validated.parameters["query"].get("tag"):
        q = q.filter(
            Article.tags.any(Tag.name == request.openapi_validated.
                             parameters["query"]["tag"]))

    q = q.order_by(desc("created"))
    q = paginate(q, request)

    articles = q.all()
    count = q.count()
    return {"articles": articles, "articlesCount": count}
예제 #15
0
def test_by_shortcuts(db: Session, democontent: None) -> None:
    """Test that by_* shortcuts work."""
    assert User.by_username("one", db) == User.by_email("*****@*****.**", db)
    assert User.by_username("one", db) == User.by_id(USER_ONE_ID, db)
def test_by_shortcuts(db: Session, democontent: None) -> None:
    """Test that by_* shortcuts work."""
    assert Profile.by_username("one",
                               db).user == User.by_username(  # type: ignore
                                   "one", db)
    assert Profile.by_username("foo", db) is None
예제 #17
0
def get_user(request: Request) -> t.Optional[User]:
    """Never to be called directly, exposes request.user."""
    return User.by_id(request.authenticated_userid, db=request.db)
예제 #18
0
def test_verify_password(db: Session, democontent: None) -> None:
    """Test verifying user's password."""
    user = User.by_username("one", db)
    assert user.verify_password("secret")  # type: ignore
    assert not user.verify_password("invalid")  # type: ignore