Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions server/databases/core-pgsql/data/testCreateSubsrcibe.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
INSERT INTO users(id,name,login,password) VALUES('6cca3ced-9615-4e2c-bae4-580c86d78710','Lox','Login','Password');
INSERT INTO users(id,name,login,password) VALUES('46775165-7542-49d9-a3b2-a7878980a2bc','Lox123','Login123','Password123');

INSERT INTO follows(folowee_id,folower_id) VALUES('6cca3ced-9615-4e2c-bae4-580c86d78710','46775165-7542-49d9-a3b2-a7878980a2bc');
2 changes: 2 additions & 0 deletions server/services/posts-uservice/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ add_library(${PROJECT_NAME}_objs OBJECT
src/api/v1/users/subscribers/subscribers.cpp
src/api/v1/users/subscriptions/subscriptions.hpp
src/api/v1/users/subscriptions/subscriptions.cpp
src/api/v1/users/subscribe/subscribe.hpp
src/api/v1/users/subscribe/subscribe.cpp
src/models/s3_url.hpp
src/models/s3_url.cpp
src/models/post.hpp
Expand Down
4 changes: 4 additions & 0 deletions server/services/posts-uservice/configs/static_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ components_manager:
method: GET
task_processor: main-task-processor

handler-create-subscribe:
path: /api/v1/users/{userId}/subscribe
method: POST
task_processor: main-task-processor

postgres-db-1:
dbconnection: $dbconnection
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#include "subscribe.hpp"

#include <fmt/format.h>
#include <boost/uuid/uuid.hpp>
#include <userver/components/component_context.hpp>

#include <userver/formats/serialize/common_containers.hpp>
#include <userver/server/handlers/http_handler_base.hpp>

#include "models/user.hpp"
#include "userver/storages/secdist/exceptions.hpp"
#include "utils/errors.hpp"
#include "utils/fields.hpp"

#include <userver/storages/postgres/cluster.hpp>
#include <userver/storages/postgres/cluster_types.hpp>
#include <userver/storages/postgres/component.hpp>
#include <userver/storages/postgres/io/row_types.hpp>
#include <userver/storages/postgres/postgres_fwd.hpp>

namespace posts_uservice {
bool Is_user_exists(const boost::uuids::uuid& user_id,const userver::storages::postgres::ClusterPtr& pg_cluster_) {
auto user_exists = pg_cluster_->Execute(userver::storages::postgres::ClusterHostType::kMaster,
"SELECT name FROM users WHERE id = $1", user_id);
return !user_exists.IsEmpty();
}
Comment on lines +22 to +26
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Что это за стиль названия функции? Все функции до этого момента мы вроде в CamelCase называли


namespace {

class Subscribe final : public userver::server::handlers::HttpHandlerBase {
public:
static constexpr std::string_view kName = "handler-create-subscribe";

Subscribe(const userver::components::ComponentConfig& config,
const userver::components::ComponentContext& context)
: HttpHandlerBase(config, context),
pg_cluster_(context.FindComponent<userver::components::Postgres>("postgres-db-1").GetCluster()) {}

using HttpHandlerBase::HttpHandlerBase;

std::string HandleRequestThrow(const userver::server::http::HttpRequest& request,
userver::server::request::RequestContext&) const override {
// can be useful for hide subscriptions for someone
const std::string& user_authorized_id_argument = request.GetHeader("System-Design-User-Id");
const std::string& user_id_argument = request.GetPathArg("userId");

const auto user_authorized_id = utils::ParseUUIDArgument(user_authorized_id_argument);
const auto user_id = utils::ParseUUIDArgument(user_id_argument);

if(user_authorized_id == user_id) {
throw errors::ValidationException("user","Can not subcribe to yourself");
}
Comment on lines +50 to +52
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Проблема не с валидацией, это логическая ошибка, тут другое должно быть

if(!Is_user_exists(user_authorized_id,pg_cluster_)) {
throw errors::NotFoundException("user", "User with this id not found");
}
if(!Is_user_exists(user_id,pg_cluster_)) {
throw errors::NotFoundException("user", "User with this id not found");
}
Comment on lines +53 to +58
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pg_cluster_ лучше первым аргументом


auto res = pg_cluster_->Execute(userver::storages::postgres::ClusterHostType::kMaster,
"SELECT folowee_id,folower_id FROM follows WHERE folowee_id = $1 AND folower_id = $2",
user_id,user_authorized_id);

if(!res.IsEmpty()) {
return "Already subscribed";
}

res = pg_cluster_->Execute(userver::storages::postgres::ClusterHostType::kMaster,
"INSERT INTO follows(folowee_id,folower_id) VALUES($1,$2)",
user_id,user_authorized_id);

return "Subcribed";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Не уверен, что можно просто текст возвращать. В пост запросе сделать пост нужно было что-то осмысленное возвращать (json), думаю, что тут тоже.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Кажется здесь лучше вообще ничего не возращать, код 200 о всем говорит

}

private:
userver::storages::postgres::ClusterPtr pg_cluster_;
};

} // namespace

void AppendSubscribe(userver::components::ComponentList& component_list) {
component_list.Append<Subscribe>();
}

} // namespace posts_uservice
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#pragma once

#include <string>
#include <string_view>

#include <userver/components/component_list.hpp>

namespace posts_uservice {

void AppendSubscribe(userver::components::ComponentList& component_list);

} // namespace posts_uservice
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class GetSubscribers final : public userver::server::handlers::HttpHandlerBase {
const std::string& user_authorized_id_argument = request.GetHeader("System-Design-User-Id");
const std::string& user_id_argument = request.GetPathArg("userId");

const auto user_authorized_id = utils::ParseUUIDArgument(user_id_argument);
const auto user_authorized_id = utils::ParseUUIDArgument(user_authorized_id_argument);
const auto user_id = utils::ParseUUIDArgument(user_id_argument);

auto user_exists = pg_cluster_->Execute(userver::storages::postgres::ClusterHostType::kMaster,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class GetSubscriptions final : public userver::server::handlers::HttpHandlerBase
const std::string& user_authorized_id_argument = request.GetHeader("System-Design-User-Id");
const std::string& user_id_argument = request.GetPathArg("userId");

const auto user_authorized_id = utils::ParseUUIDArgument(user_id_argument);
const auto user_authorized_id = utils::ParseUUIDArgument(user_authorized_id_argument);
const auto user_id = utils::ParseUUIDArgument(user_id_argument);

auto user_exists = pg_cluster_->Execute(userver::storages::postgres::ClusterHostType::kMaster,
Expand Down
3 changes: 3 additions & 0 deletions server/services/posts-uservice/src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <api/v1/users/subscribe/subscribe.hpp>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Эту строчку убираем, повтор 17 строчки

#include <userver/clients/dns/component.hpp>
#include <userver/clients/http/component.hpp>
#include <userver/components/minimal_server_component_list.hpp>
Expand All @@ -13,6 +14,7 @@
#include "api/v1/users/posts/last_posts.hpp"
#include "api/v1/users/subscribers/subscribers.hpp"
#include "api/v1/users/subscriptions/subscriptions.hpp"
#include "api/v1/users/subscribe/subscribe.hpp"

int main(int argc, char* argv[]) {
auto component_list = userver::components::MinimalServerComponentList()
Expand All @@ -29,6 +31,7 @@ int main(int argc, char* argv[]) {
posts_uservice::AppendGetFeed(component_list);
posts_uservice::AppendGetSubscribers(component_list);
posts_uservice::AppendGetSubscriptions(component_list);
posts_uservice::AppendSubscribe(component_list);

return userver::utils::DaemonMain(argc, argv, component_list);
}
52 changes: 52 additions & 0 deletions server/services/posts-uservice/tests/test_create_subcribe.py
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Нет проверки подписки на несуществующего пользователя (корректный uuid, которого нет в бд юзерс)

Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Start via `make test-debug` or `make test-release`

import pytest

from testsuite.databases import pgsql

from utils.error_strings import *

# No test for absent id
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

либо делай, либо убирай комментарий


FIRST_GUY = '6cca3ced-9615-4e2c-bae4-580c86d78710'
SECOND_GUY = '46775165-7542-49d9-a3b2-a7878980a2bc'

@pytest.mark.pgsql('db', files=['testCreateSubsrcibe.sql'])
async def test_create_subcribe_with_incorrect_id(service_client):
response = await service_client.post(
f'/api/v1/users/kek/subscribe',
headers={'System-Design-User-Id': '123'},
)
assert response.status == 400
assert VALIDATION_ERROR_START in response.text

@pytest.mark.pgsql('db', files=['testCreateSubsrcibe.sql'])
async def test_create_subcribe_with_myself(service_client):
response = await service_client.post(
f'/api/v1/users/{FIRST_GUY}/subscribe',
headers={'System-Design-User-Id': FIRST_GUY}
)
assert response.status == 400
assert VALIDATION_ERROR_START in response.text

@pytest.mark.pgsql('db', files=['testCreateSubsrcibe.sql'])
async def test_create_subcribe_twice(service_client):
response = await service_client.post(
f'/api/v1/users/{FIRST_GUY}/subscribe',
headers={'System-Design-User-Id': SECOND_GUY}
)
assert response.status == 200
assert response.text == "Already subscribed"
@pytest.mark.pgsql('db', files=['testCreateSubsrcibe.sql'])
async def test_create_subcribe_good(service_client):
response = await service_client.post(
f'/api/v1/users/{SECOND_GUY}/subscribe',
headers={'System-Design-User-Id': FIRST_GUY}
)
assert response.status == 200
assert response.text == "Subcribed"