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, } }
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
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
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, }
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
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}, }
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": "******", }
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}
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
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)
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