diff --git a/CMakeLists.txt b/CMakeLists.txt index 98fe862..46ee7d8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -77,8 +77,6 @@ add_library(${PROJECT_NAME}_objs OBJECT src/handlers/auth/auth_bearer.cpp src/dto/article.cpp src/dto/article.hpp - src/dto/profile.cpp - src/dto/profile.hpp src/dto/comment.hpp src/dto/comment.cpp src/db/sql.hpp @@ -123,7 +121,6 @@ userver_target_generate_chaotic(${PROJECT_NAME}-chgen ARGS -n "/components/schemas/([^/]*)/=real_medium::handlers::{0}" -f "(.*)={0}" - --clang-format= --generate-serializers OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/src diff --git a/README.md b/README.md index 6cb3fee..e70cfa1 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,7 @@ Anna Volkova Nikita Semenov Vadim Romanyuk artemiev.kk +Elizaveta Rudneva **Maintainer:** diff --git a/docs/api/api.yaml b/docs/api/api.yaml index 7108976..a29c3c9 100644 --- a/docs/api/api.yaml +++ b/docs/api/api.yaml @@ -8,113 +8,219 @@ servers: description: local paths: -# /api/profiles/{username}: -# get: -# description: Get user profile + /api/profiles/{username}: + get: + description: Get a profile of a user + parameters: + - name: username + in: path + description: Username of the profile to get + required: true + schema: + type: string + responses: + '200': + description: Profile has been successfully received + $ref: '#/components/schemas/Profile' + '404': + description: There is no user with this nickname + + /api/profiles/{username}/follow: + post: + description: Follow the user by username + parameters: + - name: username + in: path + required: true + schema: + type: string + responses: + '200': + description: Successfully subscribed + $ref: '#/components/schemas/Profile' + '404': + description: There is no user with this nickname + '400': + description: Username is author of the request or already followed + delete: + summary: Unfollow the user by username + parameters: + - name: username + in: path + required: true + schema: + type: string + responses: + '200': + description: Successfully unfollowed + $ref: '#/components/schemas/Profile' + '404': + description: There is no user with this nickname + '400': + description: Username is author of the request or already unfollowed -# /api/profiles/{username}/follow: -# post: -# description: Follow user -# delete: -# description: Unfollow user /api/user: -# get: -# description: Get user profile + get: + description: Get an user's profile + responses: + '200': + description: Successfully received a profile + '404': + description: Invalid user_id put: - description: Update user profile + description: Update an user's profile requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/UserUpdateDTO' + $ref: '#/components/schemas/UserUpdateDTO' responses: '200': - description: User profile successfully updated + description: Successfully updated an user's profile + '422': + description: Invalid input data /api/users: post: - description: Register user + description: Register a new user requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/UserRegistrationDTO' + $ref: '#/components/schemas/UserRegistrationDTO' responses: '200': description: Successfully registered + '422': + description: Invalid input data /api/users/login: post: description: Login user requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/UserLoginDTO' + $ref: '#/components/schemas/UserLoginDTO' responses: '200': description: Successfully logged in + '422': + description: Invalid input data + '404': + description: User has not found /api/articles: -# get: -# description: Get list of articles + get: + description: Get recent articles globally + requestBody: + $ref: '#/components/schemas/ArticleFilterDTO' + responses: + '200': + description: Successfully received a list of articles + '422': + description: Invalid filters entered post: - description: Create article + description: Create an article requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/CreateArticleRequest' + $ref: '#/components/schemas/CreateArticleRequest' responses: '200': - description: Successfully created article + description: Successfully created an article + '422': + description: Invalid input data /api/articles/{slug}: -# get: -# description: Get an article + get: + description: Get an article + responses: + '200': + description: Successfully received an article + '422': + description: Invalid input data put: - description: Update article + description: Update an article requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/UpdateArticleRequest' + $ref: '#/components/schemas/UpdateArticleRequest' + responses: + '200': + description: Successfully updated an article + '422': + description: Invalid input data + '404': + description: Article has not found + delete: + description: Delete an article responses: '200': - description: Successfully updated article -# delete: -# description: Delete article + description: Successfully deleted an article + '403': + description: Forbidden to delete an article + '404': + description: Article has not found /api/articles/{slug}/favorite: -# post: -# description: Make an article favorite -# delete: -# description: Remove an article from favorites + post: + description: Favorite an article + responses: + '200': + description: Successfully favorited an article + '404': + description: Article has not found + delete: + description: Remove an article from favorites + responses: + '200': + description: Successfully unfavorited an article + '404': + description: Article has not found + + /api/articles/feed: + get: + description: Get recent articles from users you follow + requestBody: + $ref: '#/components/schemas/FeedArticleFilterDTO' + responses: + '200': + description: Successfully received recent articles + '422': + description: Invalid input data /api/articles/{slug}/comments: post: - description: Add comment + description: Create a comment for an article parameters: - name: slug in: path required: true schema: type: string + requestBody: + $ref: '#/components/schemas/AddComment' responses: '200': description: Comment successfully added - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/AddComment' -# get: -# description: Get comments list + '422': + description: Invalid input data + '404': + description: Invalid article_id + '501': + description: Unknown error. Comment was not added + get: + description: Get comments for an article + responses: + '200': + description: Successfully received a list of comments + '404': + description: Invalid slug + + /api/articles/{slug}/comments/{id}: + delete: + description: Delete a comment for an article + '200': + description: Successfully deleted a comment + '404': + description: Invalid comment_id + '403': + description: This user does not own this comment -# /api/articles/{slug}/comments/{id}: -# delete: -# description: Delete comment + /api/tags: + get: + description: Get tags + '200': + description: Successfully received a list of tags components: schemas: @@ -137,6 +243,10 @@ components: type: string password: type: string + bio: + type: string + image: + type: string UserUpdateDTO: type: object @@ -186,40 +296,95 @@ components: body: type: string -# Comment: - # Article: - -# Profile: +# required: +# - profile +# - body +# - createdAt +# - description +# - isFavorited +# - favoritesCount +# - slug +# - title +# - updatedAt # type: object -# additionalProperties: false # properties: -# username: +# slug: +# type: string +# title: +# type: string +# description: +# type: string +# body: # type: string -# bio: -# type: string -# image: +# tags: +# type: array +# items: +# type: string +# createdAt: # type: string -# following: +# format: date-time +# updatedAt: +# type: string +# format: date-time +# isFavorited: # type: boolean -# required: -# - username -# - following - -# securitySchemes: -# bearerAuth: -# type: http -# scheme: bearer -# bearerFormat: JWT - - responses: - UnauthorizedError: - description: User is not authorized - content: - application/json: - schema: - type: object - properties: - error: - type: string - example: "Unauthorized" +# favoritesCount: +# type: integer +# profile: +# $ref: '#/components/schemas/Profile' +# additionalProperties: false + + ArticleFilterDTO: + type: object + additionalProperties: false + properties: + tag: + type: string + author: + type: string + favorited: + type: string + limit: + type: integer + format: int32 + default: 20 + offset: + type: integer + format: int32 + required: + - limit + - offset + + FeedArticleFilterDTO: + type: object + additionalProperties: false + properties: + limit: + type: integer + format: int32 + default: 20 + offset: + type: integer + format: int32 + required: + - limit + - offset + + Profile: + type: object + additionalProperties: false + properties: + username: + type: string + bio: + type: string + image: + type: string + following: + type: boolean + required: + - username + - following + - bio + - image diff --git a/src/cache/articles_cache.cpp b/src/cache/articles_cache.cpp index 17895c6..01d20e7 100644 --- a/src/cache/articles_cache.cpp +++ b/src/cache/articles_cache.cpp @@ -37,7 +37,7 @@ ArticlesCacheContainer::ArticlePtr ArticlesCacheContainer::findArticleBySlug( std::vector ArticlesCacheContainer::getRecent( - real_medium::dto::ArticleFilterDTO& filter) const { + real_medium::handlers::ArticleFilterDTO& filter) const { std::vector articles; int offset = 0; for (const auto& it : recentArticles_) { @@ -64,7 +64,7 @@ ArticlesCacheContainer::getRecent( return articles; } std::vector ArticlesCacheContainer::getFeed( - real_medium::dto::FeedArticleFilterDTO& filter, UserId authId) const { + real_medium::handlers::FeedArticleFilterDTO& filter, UserId authId) const { auto followedArticlesUMap = articlesByFollower_.find(authId); if (followedArticlesUMap == articlesByFollower_.end()) return {}; diff --git a/src/cache/articles_cache.hpp b/src/cache/articles_cache.hpp index 51a1fc8..d8df3cd 100644 --- a/src/cache/articles_cache.hpp +++ b/src/cache/articles_cache.hpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "../db/sql.hpp" #include "../dto/filter.hpp" #include "../models/article.hpp" @@ -23,9 +24,9 @@ class ArticlesCacheContainer { ArticlePtr findArticleBySlug(const Slug& slug) const; std::vector getRecent( - real_medium::dto::ArticleFilterDTO& filter_) const; + real_medium::handlers::ArticleFilterDTO& filter_) const; std::vector getFeed( - real_medium::dto::FeedArticleFilterDTO& filter_, UserId authId_) const; + real_medium::handlers::FeedArticleFilterDTO& filter_, UserId authId_) const; private: struct TimepointedArticle { diff --git a/src/db/sql.hpp b/src/db/sql.hpp index cc8e460..43dccd6 100644 --- a/src/db/sql.hpp +++ b/src/db/sql.hpp @@ -5,8 +5,8 @@ namespace real_medium::sql { inline constexpr std::string_view kInsertUser = R"~( -INSERT INTO real_medium.users(username, email, password_hash, salt) -VALUES($1, $2, $3, $4) +INSERT INTO real_medium.users(username, email, bio, image, password_hash, salt) +VALUES($1, $2, $3, $4, $5, $6) RETURNING * )~"; diff --git a/src/dto/article.hpp b/src/dto/article.hpp index ca0ad77..da5c631 100644 --- a/src/dto/article.hpp +++ b/src/dto/article.hpp @@ -4,9 +4,9 @@ #include #include #include +#include #include #include "models/article.hpp" -#include "profile.hpp" namespace real_medium::dto { struct Article final { @@ -22,7 +22,7 @@ struct Article final { userver::storages::postgres::TimePointTz updatedAt; std::int64_t favoritesCount{}; bool isFavorited{false}; - dto::Profile profile; + handlers::Profile profile; }; userver::formats::json::Value Serialize( diff --git a/src/dto/comment.hpp b/src/dto/comment.hpp index 989a1ac..ba9f1a4 100644 --- a/src/dto/comment.hpp +++ b/src/dto/comment.hpp @@ -3,11 +3,11 @@ #include #include +#include #include #include #include "models/comment.hpp" -#include "profile.hpp" namespace real_medium::dto { @@ -18,7 +18,7 @@ struct Comment final { userver::storages::postgres::TimePointTz createdAt; userver::storages::postgres::TimePointTz updatedAt; std::string body; - dto::Profile author; + handlers::Profile author; }; userver::formats::json::Value Serialize( diff --git a/src/dto/filter.cpp b/src/dto/filter.cpp index 13e5395..871fd09 100644 --- a/src/dto/filter.cpp +++ b/src/dto/filter.cpp @@ -1,11 +1,12 @@ #include "filter.hpp" +#include #include "boost/lexical_cast.hpp" namespace real_medium::dto { template <> -FeedArticleFilterDTO Parse(const userver::server::http::HttpRequest& request) { - FeedArticleFilterDTO filter; +handlers::FeedArticleFilterDTO Parse(const userver::server::http::HttpRequest& request) { + handlers::FeedArticleFilterDTO filter; if (request.HasArg("limit")) { filter.limit = boost::lexical_cast(request.GetArg("limit")); filter.limit = std::max(0, filter.limit); @@ -18,8 +19,8 @@ FeedArticleFilterDTO Parse(const userver::server::http::HttpRequest& request) { } template <> -ArticleFilterDTO Parse(const userver::server::http::HttpRequest& request) { - ArticleFilterDTO filter; +handlers::ArticleFilterDTO Parse(const userver::server::http::HttpRequest& request) { + handlers::ArticleFilterDTO filter; if (request.HasArg("tag")) { filter.tag = request.GetArg("tag"); } diff --git a/src/dto/filter.hpp b/src/dto/filter.hpp index c65886f..6b5a148 100644 --- a/src/dto/filter.hpp +++ b/src/dto/filter.hpp @@ -9,19 +9,6 @@ #include namespace real_medium::dto { -struct ArticleFilterDTO { - std::optional tag; - std::optional author; - std::optional favorited; - std::int32_t limit = 20; - std::int32_t offset = 0; -}; - -struct FeedArticleFilterDTO { - std::int32_t limit = 20; - std::int32_t offset = 0; -}; - template T Parse(const userver::server::http::HttpRequest& request); } // namespace real_medium::dto diff --git a/src/dto/profile.cpp b/src/dto/profile.cpp deleted file mode 100644 index 14c5bfa..0000000 --- a/src/dto/profile.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include "profile.hpp" - -namespace real_medium::dto { - -userver::formats::json::Value Serialize( - const real_medium::dto::Profile& data, - userver::formats::serialize::To) { - userver::formats::json::ValueBuilder builder; - builder["username"] = data.username; - if (data.bio) - builder["bio"] = *data.bio; - else - builder["bio"] = userver::formats::common::Type::kNull; - if (data.image) - builder["image"] = *data.image; - else - builder["image"] = userver::formats::common::Type::kNull; - ; - builder["following"] = data.following; - return builder.ExtractValue(); -} - -} // namespace real_medium::dto diff --git a/src/dto/profile.hpp b/src/dto/profile.hpp deleted file mode 100644 index 3e3535d..0000000 --- a/src/dto/profile.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -namespace real_medium::dto { - -struct Profile { - std::string username; - std::optional bio; - std::optional image; - bool following{false}; -}; - -userver::formats::json::Value Serialize( - const Profile& dto, - userver::formats::serialize::To); - -} // namespace real_medium::dto diff --git a/src/handlers/articles/articles_get.cpp b/src/handlers/articles/articles_get.cpp index 222708e..1dd6828 100644 --- a/src/handlers/articles/articles_get.cpp +++ b/src/handlers/articles/articles_get.cpp @@ -1,5 +1,6 @@ #include "articles_get.hpp" #include +#include #include "db/sql.hpp" #include "dto/article.hpp" #include "dto/filter.hpp" @@ -22,10 +23,10 @@ userver::formats::json::Value Handler::HandleRequestJsonThrow( const userver::server::http::HttpRequest& request, const userver::formats::json::Value& request_json, userver::server::request::RequestContext& context) const { - dto::ArticleFilterDTO filter; + handlers::ArticleFilterDTO filter; try { - filter = dto::Parse(request); + filter = dto::Parse(request); } catch (std::bad_cast& ex) { auto& response = request.GetHttpResponse(); response.SetStatus(userver::server::http::HttpStatus::kUnprocessableEntity); diff --git a/src/handlers/articles/feed_articles.cpp b/src/handlers/articles/feed_articles.cpp index ce484c6..828b8f1 100644 --- a/src/handlers/articles/feed_articles.cpp +++ b/src/handlers/articles/feed_articles.cpp @@ -1,6 +1,7 @@ #include "feed_articles.hpp" #include #include +#include #include "db/sql.hpp" #include "dto/article.hpp" #include "dto/filter.hpp" @@ -23,10 +24,10 @@ userver::formats::json::Value Handler::HandleRequestJsonThrow( const userver::server::http::HttpRequest& request, const userver::formats::json::Value& /*request_json*/, userver::server::request::RequestContext& context) const { - dto::FeedArticleFilterDTO filter; + handlers::FeedArticleFilterDTO filter; try { - filter = dto::Parse(request); + filter = dto::Parse(request); } catch (std::bad_cast& ex) { auto& response = request.GetHttpResponse(); response.SetStatus(userver::server::http::HttpStatus::kUnprocessableEntity); diff --git a/src/handlers/comments/comment_post.cpp b/src/handlers/comments/comment_post.cpp index 950c8c2..fa03b78 100644 --- a/src/handlers/comments/comment_post.cpp +++ b/src/handlers/comments/comment_post.cpp @@ -61,7 +61,7 @@ userver::formats::json::Value Handler::HandleRequestJsonThrow( userver::server::http::HttpStatus::kNotImplemented); // 501, мб надо // заменить return utils::error::MakeError( - "none", "Unknow error. The comment was not added to the database."); + "none", "Unknown error. The comment was not added to the database."); } auto comment_res_data = diff --git a/src/handlers/comments/comments_get.cpp b/src/handlers/comments/comments_get.cpp index 1c989c6..a0d4014 100644 --- a/src/handlers/comments/comments_get.cpp +++ b/src/handlers/comments/comments_get.cpp @@ -3,7 +3,6 @@ #include #include "db/sql.hpp" #include "dto/comment.hpp" -#include "dto/profile.hpp" #include "utils/make_error.hpp" namespace real_medium::handlers::comments::get { diff --git a/src/handlers/profiles/profiles.cpp b/src/handlers/profiles/profiles.cpp index 93e836b..618e23c 100644 --- a/src/handlers/profiles/profiles.cpp +++ b/src/handlers/profiles/profiles.cpp @@ -40,7 +40,7 @@ json::Value Handler::HandleRequestJsonThrow(const HttpRequest& request, "There is no user with this nickname."); } - auto profile = res.AsSingleRow( + auto profile = res.AsSingleRow( userver::storages::postgres::kRowTag); userver::formats::json::ValueBuilder builder; diff --git a/src/handlers/profiles/profiles_follow.cpp b/src/handlers/profiles/profiles_follow.cpp index 2c5e07a..128a6bb 100644 --- a/src/handlers/profiles/profiles_follow.cpp +++ b/src/handlers/profiles/profiles_follow.cpp @@ -1,6 +1,7 @@ +#include + #include "profiles_follow.hpp" #include "db/sql.hpp" -#include "dto/profile.hpp" #include "models/profile.hpp" #include "utils/make_error.hpp" @@ -59,7 +60,7 @@ namespace real_medium::handlers::profiles::post { pg_cluster_->Execute(userver::storages::postgres::ClusterHostType::kSlave, sql::KFollowingUser.data(), username_id, user_id); - const auto profile = res_following.AsSingleRow( + const auto profile = res_following.AsSingleRow( userver::storages::postgres::kRowTag); if (!profile.following) { diff --git a/src/handlers/profiles/profiles_follow_delete.cpp b/src/handlers/profiles/profiles_follow_delete.cpp index cb81340..40dec85 100644 --- a/src/handlers/profiles/profiles_follow_delete.cpp +++ b/src/handlers/profiles/profiles_follow_delete.cpp @@ -1,6 +1,7 @@ +#include + #include "profiles_follow_delete.hpp" #include "db/sql.hpp" -#include "dto/profile.hpp" #include "models/profile.hpp" #include "userver/formats/yaml/value_builder.hpp" #include "userver/server/handlers/http_handler_base.hpp" @@ -58,7 +59,7 @@ userver::formats::json::Value Handler::HandleRequestJsonThrow( sql::KUnFollowingUser.data(), username_id, user_id); const auto profile = - res_unfollowing.AsSingleRow( + res_unfollowing.AsSingleRow( userver::storages::postgres::kRowTag); if (profile.following) { diff --git a/src/handlers/users/user_get.cpp b/src/handlers/users/user_get.cpp index 9a5e8e5..7fb8abb 100644 --- a/src/handlers/users/user_get.cpp +++ b/src/handlers/users/user_get.cpp @@ -1,4 +1,3 @@ - #include "user_get.hpp" #include "db/sql.hpp" #include "models/user.hpp" @@ -27,7 +26,7 @@ userver::formats::json::Value Handler::HandleRequestJsonThrow( if (result.IsEmpty()) { auto& response = request.GetHttpResponse(); response.SetStatus(userver::server::http::HttpStatus::kNotFound); - return utils::error::MakeError("user_id", "Ivanlid user_id. Not found."); + return utils::error::MakeError("user_id", "Invalid user_id. Not found."); } auto user = result.AsSingleRow( diff --git a/src/handlers/users/users.cpp b/src/handlers/users/users.cpp index 9e8c397..f13dc60 100644 --- a/src/handlers/users/users.cpp +++ b/src/handlers/users/users.cpp @@ -47,6 +47,7 @@ userver::formats::json::Value RegisterUser::HandleRequestJsonThrow( auto query_result = pg_cluster_->Execute( userver::storages::postgres::ClusterHostType::kMaster, sql::kInsertUser.data(), user_register.username, user_register.email, + user_register.bio, user_register.image, hash_password, salt); result_user = query_result.AsSingleRow( userver::storages::postgres::kRowTag); diff --git a/src/models/profile.hpp b/src/models/profile.hpp index 048552e..14caf62 100644 --- a/src/models/profile.hpp +++ b/src/models/profile.hpp @@ -12,8 +12,8 @@ namespace real_medium::models { struct Profile final { std::string username; - std::optional bio; - std::optional image; + std::string bio; + std::string image; bool following{false}; auto Introspect() { return std::tie(username, bio, image, following); } }; diff --git a/src/models/user.hpp b/src/models/user.hpp index 11eae86..7f87338 100644 --- a/src/models/user.hpp +++ b/src/models/user.hpp @@ -16,8 +16,8 @@ struct User final { UserId id; std::string username; std::string email; - std::optional bio; - std::optional image; + std::string bio; + std::string image; std::string password_hash; std::string salt; diff --git a/tests/articles/test_create_article.py b/tests/articles/test_create_article.py index 3f0c7b1..b3b1d71 100644 --- a/tests/articles/test_create_article.py +++ b/tests/articles/test_create_article.py @@ -17,7 +17,7 @@ async def test_create_article_unauthorized(service_client): async def test_create_article(service_client): - user = User(bio=None, image=None) + user = User() response = await register_user(service_client, user) assert response.status == HTTPStatus.OK diff --git a/tests/articles/test_delete_article.py b/tests/articles/test_delete_article.py index 9523b9c..737d448 100644 --- a/tests/articles/test_delete_article.py +++ b/tests/articles/test_delete_article.py @@ -18,7 +18,7 @@ async def test_delete_article_unauthorized(service_client): - user = User(bio=None, image=None) + user = User() response = await register_user(service_client, user) assert response.status == HTTPStatus.OK @@ -33,7 +33,7 @@ async def test_delete_article_unauthorized(service_client): async def test_delete_unknown_article(service_client): - user = User(bio=None, image=None) + user = User() response = await register_user(service_client, user) assert response.status == HTTPStatus.OK @@ -45,7 +45,7 @@ async def test_delete_unknown_article(service_client): async def test_delete_article(service_client): - user = User(bio=None, image=None) + user = User() response = await register_user(service_client, user) assert response.status == HTTPStatus.OK @@ -84,7 +84,7 @@ async def test_delete_article(service_client): async def test_invalid_access_delete_article(service_client): - user = User(bio=None, image=None) + user = User() response = await register_user(service_client, user) assert response.status == HTTPStatus.OK @@ -94,7 +94,7 @@ async def test_invalid_access_delete_article(service_client): ) assert response.status == HTTPStatus.OK - another_user = User(bio=None, image=None) + another_user = User() response = await register_user(service_client, another_user) assert response.status == HTTPStatus.OK diff --git a/tests/articles/test_favourite_article.py b/tests/articles/test_favourite_article.py index 0a47fbe..bdf19ab 100644 --- a/tests/articles/test_favourite_article.py +++ b/tests/articles/test_favourite_article.py @@ -12,7 +12,7 @@ async def test_favourite_article_unauthorized(service_client): - user = User(bio=None, image=None) + user = User() response = await register_user(service_client, user) assert response.status == HTTPStatus.OK @@ -27,7 +27,7 @@ async def test_favourite_article_unauthorized(service_client): async def test_favourite_unknown_article(service_client): - user = User(bio=None, image=None) + user = User() response = await register_user(service_client, user) assert response.status == HTTPStatus.OK @@ -40,7 +40,7 @@ async def test_favourite_unknown_article(service_client): async def test_favourite_article(service_client): - user = User(bio=None, image=None) + user = User() response = await register_user(service_client, user) assert response.status == HTTPStatus.OK @@ -50,7 +50,7 @@ async def test_favourite_article(service_client): response = await create_article(service_client, article, user_token) assert response.status == HTTPStatus.OK - another_user = User(bio=None, image=None) + another_user = User() response = await register_user(service_client, another_user) assert response.status == HTTPStatus.OK @@ -81,7 +81,7 @@ async def test_favourite_article(service_client): async def test_self_favorite_article(service_client): - user = User(bio=None, image=None) + user = User() response = await register_user(service_client, user) assert response.status == HTTPStatus.OK @@ -108,7 +108,7 @@ async def test_self_favorite_article(service_client): async def test_multiple_favorite_article(service_client): - user = User(bio=None, image=None) + user = User() response = await register_user(service_client, user) assert response.status == HTTPStatus.OK @@ -121,7 +121,7 @@ async def test_multiple_favorite_article(service_client): tokens = [] for _ in range(3): - user = User(bio=None, image=None) + user = User() response = await register_user(service_client, user) assert response.status == HTTPStatus.OK tokens.append(get_user_token(response)) diff --git a/tests/articles/test_feed_articles.py b/tests/articles/test_feed_articles.py index d372fd2..5d639ae 100644 --- a/tests/articles/test_feed_articles.py +++ b/tests/articles/test_feed_articles.py @@ -17,13 +17,13 @@ async def test_feed_articles_unauthorized(service_client): async def test_feed_articles(service_client): - user = User(bio=None, image=None) + user = User() response = await register_user(service_client, user) assert response.status == HTTPStatus.OK user_token = get_user_token(response) - another_user = User(bio=None, image=None) + another_user = User() response = await register_user(service_client, another_user) assert response.status == HTTPStatus.OK diff --git a/tests/articles/test_get_article.py b/tests/articles/test_get_article.py index 1d44390..a183995 100644 --- a/tests/articles/test_get_article.py +++ b/tests/articles/test_get_article.py @@ -11,7 +11,7 @@ async def test_get_article(service_client): - user = User(bio=None, image=None) + user = User() response = await register_user(service_client, user) assert response.status == HTTPStatus.OK @@ -29,7 +29,7 @@ async def test_get_article(service_client): async def test_get_unknown_article(service_client): - user = User(bio=None, image=None) + user = User() response = await register_user(service_client, user) assert response.status == HTTPStatus.OK @@ -43,7 +43,7 @@ async def test_get_unknown_article(service_client): async def test_get_article_unauthorized(service_client): - user = User(bio=None, image=None) + user = User() response = await register_user(service_client, user) assert response.status == HTTPStatus.OK diff --git a/tests/articles/test_list_articles.py b/tests/articles/test_list_articles.py index 1fa8e0b..560f268 100644 --- a/tests/articles/test_list_articles.py +++ b/tests/articles/test_list_articles.py @@ -19,7 +19,7 @@ async def test_list_articles_unauthorized(service_client): assert response.status == HTTPStatus.OK assert validate_articles(ArticleList(0), response) - author = User(bio=None, image=None) + author = User() response = await register_user(service_client, author) assert response.status == HTTPStatus.OK @@ -39,7 +39,7 @@ async def test_list_articles_unauthorized(service_client): init_articles=article_lst.articles[:-3:-1], ) - another_user = User(bio=None, image=None) + another_user = User() response = await register_user(service_client, another_user) assert response.status == HTTPStatus.OK @@ -67,7 +67,7 @@ async def test_list_articles_unauthorized(service_client): async def test_list_articles(service_client): - user = User(bio=None, image=None) + user = User() response = await register_user(service_client, user) assert response.status == HTTPStatus.OK @@ -79,7 +79,7 @@ async def test_list_articles(service_client): assert response.status == HTTPStatus.OK assert validate_articles(ArticleList(0), response) - author = User(bio=None, image=None) + author = User() response = await register_user(service_client, author) assert response.status == HTTPStatus.OK diff --git a/tests/articles/test_unfavourite_article.py b/tests/articles/test_unfavourite_article.py index 57b699a..8b7176b 100644 --- a/tests/articles/test_unfavourite_article.py +++ b/tests/articles/test_unfavourite_article.py @@ -13,7 +13,7 @@ async def test_unfavourite_article_unauthorized(service_client): - user = User(bio=None, image=None) + user = User() response = await register_user(service_client, user) assert response.status == HTTPStatus.OK @@ -28,7 +28,7 @@ async def test_unfavourite_article_unauthorized(service_client): async def test_unfavourite_unknown_article(service_client): - user = User(bio=None, image=None) + user = User() response = await register_user(service_client, user) assert response.status == HTTPStatus.OK @@ -41,7 +41,7 @@ async def test_unfavourite_unknown_article(service_client): async def test_unfavourite_article(service_client): - user = User(bio=None, image=None) + user = User() response = await register_user(service_client, user) assert response.status == HTTPStatus.OK @@ -51,7 +51,7 @@ async def test_unfavourite_article(service_client): response = await create_article(service_client, article, user_token) assert response.status == HTTPStatus.OK - another_user = User(bio=None, image=None) + another_user = User() response = await register_user(service_client, another_user) assert response.status == HTTPStatus.OK diff --git a/tests/articles/test_update_article.py b/tests/articles/test_update_article.py index 47f55b5..9d885dd 100644 --- a/tests/articles/test_update_article.py +++ b/tests/articles/test_update_article.py @@ -11,7 +11,7 @@ async def test_update_article_unauthorized(service_client): - user = User(bio=None, image=None) + user = User() response = await register_user(service_client, user) assert response.status == HTTPStatus.OK @@ -28,7 +28,7 @@ async def test_update_article_unauthorized(service_client): async def test_update_unknown_article(service_client): - user = User(bio=None, image=None) + user = User() response = await register_user(service_client, user) assert response.status == HTTPStatus.OK @@ -40,7 +40,7 @@ async def test_update_unknown_article(service_client): async def test_update_article(service_client): - user = User(bio=None, image=None) + user = User() response = await register_user(service_client, user) assert response.status == HTTPStatus.OK @@ -58,7 +58,7 @@ async def test_update_article(service_client): async def test_invalid_access_update_article(service_client): - user = User(bio=None, image=None) + user = User() response = await register_user(service_client, user) assert response.status == HTTPStatus.OK @@ -68,7 +68,7 @@ async def test_invalid_access_update_article(service_client): ) assert response.status == HTTPStatus.OK - another_user = User(bio=None, image=None) + another_user = User() response = await register_user(service_client, another_user) assert response.status == HTTPStatus.OK diff --git a/tests/comments/test_add_comment.py b/tests/comments/test_add_comment.py index 99f1005..5f98b9e 100644 --- a/tests/comments/test_add_comment.py +++ b/tests/comments/test_add_comment.py @@ -12,7 +12,7 @@ async def test_add_self_comment(service_client): - user = User(bio=None, image=None) + user = User() response = await register_user(service_client, user) assert response.status == HTTPStatus.OK @@ -29,12 +29,12 @@ async def test_add_self_comment(service_client): async def test_add_not_self_comment(service_client): - user = User(bio=None, image=None) + user = User() response = await register_user(service_client, user) assert response.status == HTTPStatus.OK user_token = get_user_token(response) - another_user = User(bio=None, image=None) + another_user = User() response = await register_user(service_client, another_user) assert response.status == HTTPStatus.OK another_user_token = get_user_token(response) @@ -53,7 +53,7 @@ async def test_add_not_self_comment(service_client): async def test_add_comment_unknown_article(service_client): - user = User(bio=None, image=None) + user = User() response = await register_user(service_client, user) assert response.status == HTTPStatus.OK @@ -66,7 +66,7 @@ async def test_add_comment_unknown_article(service_client): async def test_add_comment_unauthorized(service_client): - user = User(bio=None, image=None) + user = User() response = await register_user(service_client, user) assert response.status == HTTPStatus.OK diff --git a/tests/comments/test_delete_comment.py b/tests/comments/test_delete_comment.py index 344904d..677cb6e 100644 --- a/tests/comments/test_delete_comment.py +++ b/tests/comments/test_delete_comment.py @@ -15,7 +15,7 @@ async def test_delete_self_comment(service_client): - user = User(bio=None, image=None) + user = User() response = await register_user(service_client, user) assert response.status == HTTPStatus.OK @@ -40,12 +40,12 @@ async def test_delete_self_comment(service_client): async def test_delete_not_self_comment(service_client): - user = User(bio=None, image=None) + user = User() response = await register_user(service_client, user) assert response.status == HTTPStatus.OK user_token = get_user_token(response) - another_user = User(bio=None, image=None) + another_user = User() response = await register_user(service_client, another_user) assert response.status == HTTPStatus.OK another_user_token = get_user_token(response) @@ -75,7 +75,7 @@ async def test_delete_not_self_comment(service_client): async def test_delete_comment_unknown_article(service_client): - user = User(bio=None, image=None) + user = User() response = await register_user(service_client, user) assert response.status == HTTPStatus.OK @@ -95,7 +95,7 @@ async def test_delete_comment_unknown_article(service_client): async def test_delete_unknown_comment(service_client): - user = User(bio=None, image=None) + user = User() response = await register_user(service_client, user) assert response.status == HTTPStatus.OK @@ -110,7 +110,7 @@ async def test_delete_unknown_comment(service_client): async def test_delete_comment_unauthorized(service_client): - user = User(bio=None, image=None) + user = User() response = await register_user(service_client, user) assert response.status == HTTPStatus.OK diff --git a/tests/comments/test_get_comments.py b/tests/comments/test_get_comments.py index eb98cc4..63161c4 100644 --- a/tests/comments/test_get_comments.py +++ b/tests/comments/test_get_comments.py @@ -14,12 +14,12 @@ async def test_get_comments_authorized(service_client): - user = User(bio=None, image=None) + user = User() response = await register_user(service_client, user) assert response.status == HTTPStatus.OK user_token = get_user_token(response) - another_user = User(bio=None, image=None) + another_user = User() response = await register_user(service_client, another_user) assert response.status == HTTPStatus.OK another_user_token = get_user_token(response) @@ -49,12 +49,12 @@ async def test_get_comments_authorized(service_client): async def test_get_comments_unknown_article(service_client): - user = User(bio=None, image=None) + user = User() response = await register_user(service_client, user) assert response.status == HTTPStatus.OK user_token = get_user_token(response) - another_user = User(bio=None, image=None) + another_user = User() response = await register_user(service_client, another_user) assert response.status == HTTPStatus.OK another_user_token = get_user_token(response) @@ -80,13 +80,13 @@ async def test_get_comments_unknown_article(service_client): async def test_get_comments_unauthorized(service_client): - user = User(bio=None, image=None) + user = User() response = await register_user(service_client, user) assert response.status == HTTPStatus.OK user_token = get_user_token(response) profile = Profile(user) - another_user = User(bio=None, image=None) + another_user = User() response = await register_user(service_client, another_user) assert response.status == HTTPStatus.OK another_user_token = get_user_token(response) diff --git a/tests/genTest.py b/tests/genTest.py index 6cdcaea..00d56d9 100644 --- a/tests/genTest.py +++ b/tests/genTest.py @@ -14,7 +14,7 @@ COUNT_OF_USERS = 30000 COUNT_OF_ARTICLES = 30000 COUNT_OF_COMMENTS = 15000 -MAX_FOLLOWERS = 200 # Максимум Ффоловерок у каждого пользователя +MAX_FOLLOWERS = 200 # Максимум фоллловеров у каждого пользователя MAX_FAVORITES = 200 # Максимум лайков у каждой статьи по отдельности NAME_SCHEMA = 'real_medium' diff --git a/tests/helpers/endpoints.py b/tests/helpers/endpoints.py index 7574271..722693d 100644 --- a/tests/helpers/endpoints.py +++ b/tests/helpers/endpoints.py @@ -6,7 +6,7 @@ async def register_user(service_client, user): return await service_client.post( Routes.REGISTRATION, - json=model_dump(user, include=RequiredFields.REGISTRATION.value), + json=model_dump(user), ) diff --git a/tests/helpers/models.py b/tests/helpers/models.py index 2a38785..a7349d4 100644 --- a/tests/helpers/models.py +++ b/tests/helpers/models.py @@ -7,6 +7,7 @@ from utils import fake from utils import generate_title +from utils import generate_words class User(BaseModel): @@ -40,7 +41,7 @@ class Article(BaseModel): title: str = Field(default_factory=generate_title) description: str = Field(default_factory=fake.sentence) body: str = Field(default_factory=fake.paragraph) - tags: list = Field(default_factory=fake.words) + tags: list = Field(default_factory=generate_words) favorited: bool = False favoritesCount: int = 0 author: Optional[Profile] = None diff --git a/tests/helpers/utils.py b/tests/helpers/utils.py index e72c929..09b603e 100644 --- a/tests/helpers/utils.py +++ b/tests/helpers/utils.py @@ -49,3 +49,8 @@ def get_user_token(response): def generate_title(): return ' '.join(fake.words(nb=5)) + + +def generate_words(): + words = [word for word in fake.words(nb=10) if len(word) > 2] + return words diff --git a/tests/profiles/test_follow_user.py b/tests/profiles/test_follow_user.py index 11be9a6..a53b358 100644 --- a/tests/profiles/test_follow_user.py +++ b/tests/profiles/test_follow_user.py @@ -10,14 +10,14 @@ async def test_follow_user(service_client): - user = User(bio=None, image=None) + user = User() response = await register_user(service_client, user) assert response.status == HTTPStatus.OK user_token = get_user_token(response) - followed_user = User(bio=None, image=None) + followed_user = User() response = await register_user(service_client, followed_user) assert response.status == HTTPStatus.OK @@ -33,7 +33,7 @@ async def test_follow_user(service_client): async def test_follow_urself(service_client): - user = User(bio=None, image=None) + user = User() response = await register_user(service_client, user) assert response.status == HTTPStatus.OK @@ -44,7 +44,7 @@ async def test_follow_urself(service_client): async def test_follow_user_unauthorized(service_client): - user = User(bio=None, image=None) + user = User() response = await register_user(service_client, user) assert response.status == HTTPStatus.OK @@ -53,7 +53,7 @@ async def test_follow_user_unauthorized(service_client): async def test_follow_unknown_user(service_client): - user = User(bio=None, image=None) + user = User() response = await register_user(service_client, user) assert response.status == HTTPStatus.OK diff --git a/tests/profiles/test_get_profile.py b/tests/profiles/test_get_profile.py index 8efa92a..5ed6127 100644 --- a/tests/profiles/test_get_profile.py +++ b/tests/profiles/test_get_profile.py @@ -9,7 +9,7 @@ async def test_get_profile_auth(service_client): - user = User(bio=None, image=None) + user = User() response = await register_user(service_client, user) assert response.status == HTTPStatus.OK @@ -24,7 +24,7 @@ async def test_get_profile_auth(service_client): async def test_get_profile_unauthorized(service_client): - user = User(bio=None, image=None) + user = User() response = await register_user(service_client, user) assert response.status == HTTPStatus.OK diff --git a/tests/profiles/test_unfollow_user.py b/tests/profiles/test_unfollow_user.py index 75e3591..3508a86 100644 --- a/tests/profiles/test_unfollow_user.py +++ b/tests/profiles/test_unfollow_user.py @@ -17,7 +17,7 @@ async def test_unfollow_user_unauthorized(service_client): async def test_unfollow_unknown_user(service_client): - user = User(bio=None, image=None) + user = User() response = await register_user(service_client, user) assert response.status == HTTPStatus.OK @@ -29,14 +29,14 @@ async def test_unfollow_unknown_user(service_client): async def test_unfollow_user(service_client): - user = User(bio=None, image=None) + user = User() response = await register_user(service_client, user) assert response.status == HTTPStatus.OK user_token = get_user_token(response) - followed_user = User(bio=None, image=None) + followed_user = User() response = await register_user(service_client, followed_user) assert response.status == HTTPStatus.OK diff --git a/tests/tags/test_get_tags.py b/tests/tags/test_get_tags.py index 5b9ab7d..98276ff 100644 --- a/tests/tags/test_get_tags.py +++ b/tests/tags/test_get_tags.py @@ -11,7 +11,7 @@ async def test_get_tags(service_client): - user = User(bio=None, image=None) + user = User() response = await register_user(service_client, user) assert response.status == HTTPStatus.OK @@ -23,7 +23,6 @@ async def test_get_tags(service_client): for article in articleList.articles: response = await create_article(service_client, article, user_token) assert response.status == HTTPStatus.OK - print(article.tags) tags |= set(article.tags) response = await get_tags(service_client) diff --git a/tests/users/test_get_user.py b/tests/users/test_get_user.py index 18cc678..51c94ce 100644 --- a/tests/users/test_get_user.py +++ b/tests/users/test_get_user.py @@ -8,7 +8,7 @@ async def test_get_user(service_client): - user = User(bio=None, image=None) + user = User() response = await register_user(service_client, user) assert response.status == HTTPStatus.OK diff --git a/tests/users/test_login.py b/tests/users/test_login.py index 8869d41..fa85cb7 100644 --- a/tests/users/test_login.py +++ b/tests/users/test_login.py @@ -7,7 +7,7 @@ async def test_login(service_client): - user = User(bio=None, image=None) + user = User() response = await register_user(service_client, user) assert response.status == HTTPStatus.OK @@ -17,6 +17,6 @@ async def test_login(service_client): async def test_login_unknown(service_client): - user = User(bio=None, image=None) + user = User() response = await login_user(service_client, user) assert response.status == HTTPStatus.NOT_FOUND diff --git a/tests/users/test_register.py b/tests/users/test_register.py index cf7005f..2ef612b 100644 --- a/tests/users/test_register.py +++ b/tests/users/test_register.py @@ -6,7 +6,7 @@ async def test_register(service_client): - user = User(bio=None, image=None) + user = User() response = await register_user(service_client, user) assert response.status == HTTPStatus.OK assert validate_user(user, response)