def get_other_user_by_user_id(*, token: str = Depends(oauth2_scheme), user_id: int): try: user_repo = UsersRepository() other_user = user_repo.get_other_user(token=token, user_id=user_id) except Exception as e: raise e return other_user
def get_user_from_token( *, token: str = Depends(oauth2_scheme), ) -> Optional[UserInDB]: try: user_repo = UsersRepository() user = user_repo.get_current_user(token=token) except Exception as e: raise e return user
async def test_users_saved_password_is_hashed_and_has_salt( self, app: FastAPI, client: AsyncClient, db: Database, ) -> None: user_repo = UsersRepository(db) new_user = { 'email': '*****@*****.**', 'username': '******', 'password': '******' } # send post request to create user and ensure it is successful res = await client.post(app.url_path_for('users:register-new-user'), json={'new_user': new_user}) assert res.status_code == HTTP_201_CREATED # ensure the user password is hashed in the db # and that we can verify it using our auth service user_in_db = await user_repo.get_user_by_email(email=new_user['email']) assert user_in_db is not None assert user_in_db.salt is not None and user_in_db.salt != '123' assert user_in_db.password != new_user['password'] assert auth_service.verify_password( password=new_user['password'], salt=user_in_db.salt, hashed_pw=user_in_db.password, )
async def test_users_can_register_successfully(self, app: FastAPI, client: AsyncClient, db: Database) -> None: user_repo = UsersRepository(db) new_user = { "email": "*****@*****.**", "username": "******", "password": "******", } # make sure user doesn't exist yet user_in_db = await user_repo.get_user_by_email(email=new_user["email"]) assert user_in_db is None # send post request to create user and ensure it is successfuly res = await client.post(app.url_path_for("users:register-new-user"), json={"new_user": new_user}) assert res.status_code == HTTP_201_CREATED # ensure that the user now exist in db user_in_db = await user_repo.get_user_by_email(email=new_user["email"], populate=False) assert user_in_db is not None assert user_in_db.email == new_user["email"] assert user_in_db.username == new_user["username"] # check that the user returned in the response is equal to the user in the database # We exclude the password and salt attributes from the user record queried from our # database, as those should not be made available by any request that returns a user. # created_user = UserInDB(**res.json(), password="******", salt="123").dict( # exclude={"password", "salt"} # ) created_user = UserPublic(**res.json()).dict( exclude={"access_token", "profile"}) assert created_user == user_in_db.dict(exclude={"password", "salt"})
async def test_users_can_register_successfully( self, app: FastAPI, client: AsyncClient, db: Database, ) -> None: user_repo = UsersRepository(db) new_user = { 'email': '*****@*****.**', 'username': '******', 'password': '******' } # make sure user doesn't exist yet user_in_db = await user_repo.get_user_by_email(email=new_user['email']) assert user_in_db is None # send post request to create user and ensure it is successful res = await client.post(app.url_path_for('users:register-new-user'), json={'new_user': new_user}) assert res.status_code == HTTP_201_CREATED # ensure that the user now exists in the db user_in_db = await user_repo.get_user_by_email(email=new_user['email']) assert user_in_db is not None assert user_in_db.email == new_user['email'] assert user_in_db.username == new_user['username'] # check that the user returned in the response is equal to the user in the database created_user = UserPublic(**res.json()).dict(exclude={'access_token'}) assert created_user == user_in_db.dict(exclude={'password', 'salt'})
async def test_user_can_change_following_for_another_user( app: FastAPI, authorized_client: AsyncClient, db: Database, test_user: UserInDB, api_method: str, route_name: str, following: bool, ) -> None: async with db.pool.acquire() as conn: users_repo = UsersRepository(conn) user = await users_repo.create_user( username="******", email="*****@*****.**", password="******", ) if not following: profiles_repo = ProfilesRepository(conn) await profiles_repo.add_user_into_followers( target_user=user, requested_user=test_user) change_following_response = await authorized_client.request( api_method, app.url_path_for(route_name, username=user.username)) assert change_following_response.status_code == status.HTTP_200_OK response = await authorized_client.get( app.url_path_for("profiles:get-profile", username=user.username)) profile = ProfileInResponse(**response.json()) assert profile.profile.username == user.username assert profile.profile.following == following
async def test_users_saved_password_is_hashed_and_has_salt( self, app: FastAPI, client: AsyncClient, db: Database, ) -> None: user_repo = UsersRepository(db) new_user = { "email": "*****@*****.**", "username": "******", "password": "******" } # send post request to create user and ensure it is successful res = await client.post(app.url_path_for("users:register-new-user"), json={"new_user": new_user}) assert res.status_code == HTTP_201_CREATED # ensure that the users password is hashed in the db # and that we can verify it using our auth service user_in_db = await user_repo.get_user_by_email(email=new_user["email"], populate=False) assert user_in_db is not None assert user_in_db.salt is not None and user_in_db.salt != "123" assert user_in_db.password != new_user["password"] assert auth_service.verify_password( password=new_user["password"], salt=user_in_db.salt, hashed_pw=user_in_db.password, )
async def test_user_can_not_change_following_state_to_the_same_twice( app: FastAPI, authorized_client: AsyncClient, db: Database, test_user: UserInDB, api_method: str, route_name: str, following: bool, ) -> None: async with db.pool.acquire() as conn: users_repo = UsersRepository(conn) user = await users_repo.create_user( username="******", email="*****@*****.**", password="******", ) if following: profiles_repo = ProfilesRepository(conn) await profiles_repo.add_user_into_followers( target_user=user, requested_user=test_user) response = await authorized_client.request( api_method, app.url_path_for(route_name, username=user.username)) assert response.status_code == status.HTTP_400_BAD_REQUEST
async def user_fixture_helper(*, db: Database, new_user: UserCreate) -> UserInDB: user_repo = UsersRepository(db) existing_user = await user_repo.get_user_by_email(email=new_user.email) if existing_user: return existing_user return await user_repo.register_new_user(new_user=new_user)
async def test_user_can_not_modify_article_that_is_not_authored_by_him( app: FastAPI, authorized_client: Client, pool: Pool, api_method: str, route_name: str, ) -> None: async with pool.acquire() as connection: users_repo = UsersRepository(connection) user = await users_repo.create_user(username="******", email="*****@*****.**", password="******") articles_repo = ArticlesRepository(connection) await articles_repo.create_article( slug="test-slug", title="Test Slug", description="Slug for tests", body="Test " * 100, author=user, tags=["tests", "testing", "pytest"], ) response = await authorized_client.request( api_method, app.url_path_for(route_name, slug="test-slug"), json={"article": { "title": "Updated Title" }}, ) assert response.status_code == status.HTTP_403_FORBIDDEN
async def test_empty_feed_if_user_has_not_followings( app: FastAPI, authorized_client: Client, test_article: Article, test_user: UserInDB, pool: Pool, ) -> None: async with pool.acquire() as connection: users_repo = UsersRepository(connection) articles_repo = ArticlesRepository(connection) for i in range(5): user = await users_repo.create_user(username=f"user-{i}", email=f"user-{i}@email.com", password="******") for j in range(5): await articles_repo.create_article( slug=f"slug-{i}-{j}", title="tmp", description="tmp", body="tmp", author=user, tags=[f"tag-{i}-{j}"], ) response = await authorized_client.get( app.url_path_for("articles:get-user-feed-articles")) articles = ListOfArticlesInResponse(**response.json()) assert articles.articles == []
async def test_user_can_not_take_already_used_credentials( app: FastAPI, authorized_client: AsyncClient, db: Database, token: str, credentials_part: str, credentials_value: str, ) -> None: user_dict = { "username": "******", "password": "******", "email": "*****@*****.**", } user_dict.update({credentials_part: credentials_value}) async with db.pool.acquire() as conn: users_repo = UsersRepository(conn) await users_repo.create_user(**user_dict) response = await authorized_client.put( app.url_path_for("users:update-current-user"), json={"user": { credentials_part: credentials_value }}, ) assert response.status_code == status.HTTP_400_BAD_REQUEST
async def test_users_can_register_successfully( self, app: FastAPI, client: AsyncClient, db: Database, ) -> None: user_repo = UsersRepository(db) new_user = { "email": "*****@*****.**", "username": "******", "password": "******" } # make sure user doesn't exist yet user_in_db = await user_repo.get_user_by_email(email=new_user["email"]) assert user_in_db is None # send post request to create user and ensure it is successful res = await client.post(app.url_path_for("users:register-new-user"), json={"new_user": new_user}) assert res.status_code == HTTP_201_CREATED # ensure that the user now exists in the db user_in_db = await user_repo.get_user_by_email(email=new_user["email"], populate=False) assert user_in_db is not None assert user_in_db.email == new_user["email"] assert user_in_db.username == new_user["username"] # check that the user returned in the response is equal to the user in the database created_user = UserPublic(**res.json()).dict( exclude={"access_token", "profile"}) assert created_user == user_in_db.dict(exclude={"password", "salt"})
async def test_user2(db: Database) -> UserInDB: new_user = UserCreate( email="*****@*****.**", username="******", password="******", ) user_repo = UsersRepository(db) existing_user = await user_repo.get_user_by_email(email=new_user.email) if existing_user: return existing_user return await user_repo.register_new_user(new_user=new_user)
async def test_user(db: Database) -> UserInDB: new_user = UserCreate( email="*****@*****.**", username="******", password="******", ) user_repo = UsersRepository(db) existing_user = await user_repo.get_user_by_email(email=new_user.email) if existing_user: return existing_user return await user_repo.register_new_user(new_user=new_user)
async def test_user_success_registration(client: AsyncClient, app: FastAPI, pool: Pool): email, username, password = "******", "user", "password" response = await post_user(email, username, password, app, client) assert response.status_code == HTTP_201_CREATED async with pool.acquire() as connection: repo = UsersRepository(connection) user = await repo.get_user_by_email(email=email) assert user.email == email assert user.username == username assert user.check_password(password)
async def test_filtering_by_favorited( app: FastAPI, authorized_client: Client, test_user: UserInDB, pool: Pool, favorited: str, result: int, ) -> None: async with pool.acquire() as connection: users_repo = UsersRepository(connection) articles_repo = ArticlesRepository(connection) fan1 = await users_repo.create_user(username="******", email="*****@*****.**", password="******") fan2 = await users_repo.create_user(username="******", email="*****@*****.**", password="******") article1 = await articles_repo.create_article(slug=f"slug-1", title="tmp", description="tmp", body="tmp", author=test_user) article2 = await articles_repo.create_article(slug=f"slug-2", title="tmp", description="tmp", body="tmp", author=test_user) await articles_repo.add_article_into_favorites(article=article1, user=fan1) await articles_repo.add_article_into_favorites(article=article1, user=fan2) await articles_repo.add_article_into_favorites(article=article2, user=fan2) for i in range(5, 10): await articles_repo.create_article( slug=f"slug-{i}", title="tmp", description="tmp", body="tmp", author=test_user, ) response = await authorized_client.get( app.url_path_for("articles:list-articles"), params={"favorited": favorited}) articles = ListOfArticlesInResponse(**response.json()) assert articles.articles_count == result
async def test_user_that_does_not_follows_another_will_receive_profile_without_follow( app: FastAPI, authorized_client: AsyncClient, db: Database) -> None: async with db.pool.acquire() as conn: users_repo = UsersRepository(conn) user = await users_repo.create_user( username="******", email="*****@*****.**", password="******", ) response = await authorized_client.get( app.url_path_for("profiles:get-profile", username=user.username)) profile = ProfileInResponse(**response.json()) assert profile.profile.username == user.username assert not profile.profile.following
async def test_filtering_by_authors( app: FastAPI, authorized_client: AsyncClient, test_user: UserInDB, pool: Pool, author: str, result: int, ) -> None: async with pool.acquire() as connection: users_repo = UsersRepository(connection) articles_repo = ArticlesRepository(connection) author1 = await users_repo.create_user(username="******", email="*****@*****.**", password="******") author2 = await users_repo.create_user(username="******", email="*****@*****.**", password="******") await articles_repo.create_article(slug=f"slug-1", title="tmp", description="tmp", body="tmp", author=author1) await articles_repo.create_article(slug=f"slug-2-1", title="tmp", description="tmp", body="tmp", author=author2) await articles_repo.create_article(slug=f"slug-2-2", title="tmp", description="tmp", body="tmp", author=author2) for i in range(5, 10): await articles_repo.create_article( slug=f"slug-{i}", title="tmp", description="tmp", body="tmp", author=test_user, ) response = await authorized_client.get( app.url_path_for("articles:list-articles"), params={"author": author}) articles = ListOfArticlesInResponse(**response.json()) assert articles.articles_count == result
async def test_user_success_registration( app: FastAPI, client: AsyncClient, pool: Pool ) -> None: email, username, password = "******", "username", "password" registration_json = { "user": {"email": email, "username": username, "password": password} } response = await client.post( app.url_path_for("auth:register"), json=registration_json ) assert response.status_code == HTTP_201_CREATED async with pool.acquire() as conn: repo = UsersRepository(conn) user = await repo.get_user_by_email(email=email) assert user.email == email assert user.username == username assert user.check_password(password)
async def test_user_will_receive_only_following_articles( app: FastAPI, authorized_client: AsyncClient, test_article: Article, test_user: UserInDB, pool: Pool, ) -> None: following_author_username = "******" async with pool.acquire() as connection: users_repo = UsersRepository(connection) profiles_repo = ProfilesRepository(connection) articles_repo = ArticlesRepository(connection) for i in range(5): user = await users_repo.create_user( username=f"user-{i}", email=f"user-{i}@email.com", password="******" ) if i == 2: await profiles_repo.add_user_into_followers( target_user=user, requested_user=test_user ) for j in range(5): await articles_repo.create_article( slug=f"slug-{i}-{j}", title="tmp", description="tmp", body="tmp", author=user, tags=[f"tag-{i}-{j}"], ) response = await authorized_client.get( app.url_path_for("articles:get-user-feed-articles") ) articles_from_response = ListOfArticlesInResponse(**response.json()) assert len(articles_from_response.articles) == 5 all_from_following = ( article.author.username == following_author_username for article in articles_from_response.articles ) assert all(all_from_following)
async def test_user_receiving_feed_with_limit_and_offset( app: FastAPI, authorized_client: Client, test_article: Article, test_user: UserInDB, pool: Pool, ) -> None: async with pool.acquire() as connection: users_repo = UsersRepository(connection) profiles_repo = ProfilesRepository(connection) articles_repo = ArticlesRepository(connection) for i in range(5): user = await users_repo.create_user(username=f"user-{i}", email=f"user-{i}@email.com", password="******") if i == 2: await profiles_repo.add_user_into_followers( target_user=user, requested_user=test_user) for j in range(5): await articles_repo.create_article( slug=f"slug-{i}-{j}", title="tmp", description="tmp", body="tmp", author=user, tags=[f"tag-{i}-{j}"], ) full_response = await authorized_client.get( app.url_path_for("articles:get-user-feed-articles")) full_articles = ListOfArticlesInResponse(**full_response.json()) response = await authorized_client.get( app.url_path_for("articles:get-user-feed-articles"), params={ "limit": 2, "offset": 3 }, ) articles_from_response = ListOfArticlesInResponse(**response.json()) assert full_articles.articles[3:] == articles_from_response.articles
async def test_user(db: Database) -> UserInDB: new_user = UserCreate( email="*****@*****.**", username="******", password="******", ) user_repo = UsersRepository(db) # So why are we checking for user existence? Remember # that our database persists for the duration of the # testing session. With that in mind, also recall that # both the username and email attributes have unique # constraints on them. This is important, since we don't # want more than one user with the same email or with the # same username in our system. existing_user = await user_repo.get_user_by_email(email=new_user.email) if existing_user: return existing_user return await user_repo.register_new_user(new_user=new_user)
async def test_user_that_follows_another_will_receive_profile_with_follow( app: FastAPI, authorized_client: AsyncClient, pool: Pool, test_user: UserInDB) -> None: async with pool.acquire() as conn: users_repo = UsersRepository(conn) user = await users_repo.create_user( username="******", email="*****@*****.**", password="******", ) profiles_repo = ProfilesRepository(conn) await profiles_repo.add_user_into_followers(target_user=user, requested_user=test_user) response = await authorized_client.get( app.url_path_for("profiles:get-profile", username=user.username)) profile = ProfileInResponse(**response.json()) assert profile.profile.username == user.username assert profile.profile.following
async def test_user_can_not_delete_not_authored_comment( app: FastAPI, authorized_client: Client, test_article: Article, pool: Pool) -> None: async with pool.acquire() as connection: users_repo = UsersRepository(connection) user = await users_repo.create_user(username="******", email="*****@*****.**", password="******") comments_repo = CommentsRepository(connection) comment = await comments_repo.create_comment_for_article( body="tmp", article=test_article, user=user) forbidden_response = await authorized_client.delete( app.url_path_for( "comments:delete-comment-from-article", slug=test_article.slug, comment_id=str(comment.id), )) assert forbidden_response.status_code == status.HTTP_403_FORBIDDEN
async def test_user_can_change_password( app: FastAPI, authorized_client: AsyncClient, test_user: UserInDB, token: str, db: Database, ) -> None: response = await authorized_client.put( app.url_path_for("users:update-current-user"), json={"user": { "password": "******" }}, ) assert response.status_code == status.HTTP_200_OK user_profile = UserInResponse(**response.json()) async with db.pool.acquire() as connection: users_repo = UsersRepository(connection) user = await users_repo.get_user_by_username( username=user_profile.user.username) assert user.check_password("new_password")
def __init__(self, conn: Connection): super().__init__(conn) self._users_repo = UsersRepository(conn)
def __init__(self, db: Database) -> None: super().__init__(db) self.users_repo = UsersRepository(db)