diff --git a/CMakeLists.txt b/CMakeLists.txt index 41c84faf71ea4efd1e4810d27fc2290620e2ea03..451ba6926aa223c032d03b658800bce517b0dcf6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,13 +13,13 @@ if(BUILD_DEV) enable_testing() message("Building dev version") # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage -O0 -fprofile-arcs -ftest-coverage") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall -Wextra -pedantic -Wformat=2 -Wfloat-equal -Wconversion \ - -Wlogical-op -Wshift-overflow=2 -Wduplicated-cond -Wcast-qual -Wcast-align -lpq -lpqxx") +# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall -Wextra -pedantic -Wformat=2 -Wfloat-equal -Wconversion \ +# -Wlogical-op -Wshift-overflow=2 -Wduplicated-cond -Wcast-qual -Wcast-align -lpq -lpqxx") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -coverage -lgcov") if(SANITIZE_BUILD) message("Sanitizers ON") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address,undefined -fno-sanitize-recover=all -fsanitize-undefined-trap-on-error") +# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address,undefined -fno-sanitize-recover=all -fsanitize-undefined-trap-on-error") endif(SANITIZE_BUILD) endif(BUILD_DEV) diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index 2e5c3dc9fcef8d100ad122beedaf7d1ddaf37e57..86cd702d68de87350211066b1e65f0eb3b44272a 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -3,7 +3,7 @@ project(SourcedOut CXX) # find_package(antlr4-runtime REQUIRED) find_package(Boost 1.8.1 REQUIRED) # find_package(libpqxx REQUIRED) -find_library(PQXX_LIB pqxx) +#find_library(PQXX_LIB pqxx) find_package(GTest REQUIRED) find_package(nlohmann_json REQUIRED) message(STATUS ${nlohmann_json_LIBRARIES}) diff --git a/server/internal/CMakeLists.txt b/server/internal/CMakeLists.txt index f23cb6bf4ee5ceddca8379d76e7412c294e919dc..a6a49c7adb8b4ca929ec886d2555c8137d8b12a9 100644 --- a/server/internal/CMakeLists.txt +++ b/server/internal/CMakeLists.txt @@ -3,6 +3,7 @@ add_subdirectory(entities) add_subdirectory(dbManager) add_subdirectory(repository) add_subdirectory(service) +add_subdirectory(httpServer) set(libEntities_LIB ${libEntities_LIB} PARENT_SCOPE) set(libEntities_INCLUDE_DIRS ${libEntities_INCLUDE_DIRS} PARENT_SCOPE) @@ -16,4 +17,8 @@ set(SERVICE_INCLUDE_DIRS ${SERVICE_lib_INCLUDE_DIRS} PARENT_SCOPE) set(libDbManager_LIB ${libDbManager_LIB} PARENT_SCOPE) set(libDbManager_INCLUDE_DIRS ${libDbManager_INCLUDE_DIRS} PARENT_SCOPE) +set(HTTPSERVER_lib_LIB ${HTTPSERVER_lib_LIB} PARENT_SCOPE) +set(HTTPSERVER_lib_INCLUDE_DIRS ${HTTPSERVER_lib_INCLUDE_DIRS} PARENT_SCOPE) + message("DbManager = ${libDbManager_LIB}") +message("HTTPSERVER = " ${HTTPSERVER_lib_LIB}) diff --git a/server/internal/httpServer/CMakeLists.txt b/server/internal/httpServer/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..871e221a0c6a43ccdd91444bb38c366c751bb9cf --- /dev/null +++ b/server/internal/httpServer/CMakeLists.txt @@ -0,0 +1,24 @@ +project("HttpServerLib") + +set(CMAKE_CXX_STANDARD 20) + +file(GLOB SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) +file(GLOB INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/virtual) +file(GLOB INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h ${CMAKE_CURRENT_SOURCE_DIR}/virtual/*.h) + +include_directories(${INCLUDE_DIRS} ${Boost_INCLUDE_DIR} ${libEntities_INCLUDE_DIRS} ${SERVICE_lib_INCLUDE_DIRS}) +add_library(${PROJECT_NAME} ${SOURCES} ${INCLUDES}) + +message("SERVICE_lib_LIB = ${SERVICE_lib_LIB}") +message("SERVICE_lib_INCLUDE_DIRS = ${SERVICE_lib_INCLUDE_DIRS}") + +target_link_libraries(${PROJECT_NAME} ${SERVICE_lib_LIB} ${libEntities_LIB} ${Boost_LIBRARIES}) + +set(HTTPSERVER_lib_LIB ${PROJECT_NAME}) +set(HTTPSERVER_lib_LIB ${HTTPSERVER_lib_LIB} PARENT_SCOPE) + +set(HTTPSERVER_lib_INCLUDE_DIRS ${INCLUDE_DIRS}) +set(HTTPSERVER_lib_INCLUDE_DIRS ${HTTPSERVER_lib_INCLUDE_DIRS} PARENT_SCOPE) + +enable_testing() +add_subdirectory(tests) \ No newline at end of file diff --git a/server/internal/httpServer/include/Header.h b/server/internal/httpServer/include/Header.h new file mode 100644 index 0000000000000000000000000000000000000000..a3e50dd4cc33388e9c93861333a5cd411e218757 --- /dev/null +++ b/server/internal/httpServer/include/Header.h @@ -0,0 +1,11 @@ +#ifndef APP_HTTPSERVER_HTTPSERVER_HEADER_H_ +#define APP_HTTPSERVER_HTTPSERVER_HEADER_H_ + +#include + +struct Header { + std::string name; + std::string value; +}; + +#endif // APP_HTTPSERVER_HTTPSERVER_HEADER_H_ diff --git a/server/internal/httpServer/include/HttpConnection.h b/server/internal/httpServer/include/HttpConnection.h new file mode 100644 index 0000000000000000000000000000000000000000..cee5f56d4bb9da7c36c9b4d01932fc03780110ef --- /dev/null +++ b/server/internal/httpServer/include/HttpConnection.h @@ -0,0 +1,33 @@ +#ifndef APP_HTTPSERVER_HTTPSERVER_HTTPCONNECTION_H_ +#define APP_HTTPSERVER_HTTPSERVER_HTTPCONNECTION_H_ + + +#include +#include + +#include "Response.h" +#include "Request.h" +#include "Router.h" +#include "Parser.h" + +class HttpConnection : public std::enable_shared_from_this, + private boost::noncopyable { + public: + explicit HttpConnection(boost::asio::io_service& io_service); + boost::asio::ip::tcp::socket& getSocket(); + void start(); + protected: + void handleRead(const boost::system::error_code& e, + std::size_t bytes_transferred); + void handleWrite(const boost::system::error_code& e); + + boost::asio::io_service::strand strand; + boost::asio::ip::tcp::socket socket; + std::shared_ptr router; + std::array buffer{}; + Request request; + Parser parser; + Response response; +}; + +#endif // APP_HTTPSERVER_HTTPSERVER_HTTPCONNECTION_H_ diff --git a/server/internal/httpServer/include/HttpServer.h b/server/internal/httpServer/include/HttpServer.h new file mode 100644 index 0000000000000000000000000000000000000000..083d224d766b340a68bb21bca18ae5701596084a --- /dev/null +++ b/server/internal/httpServer/include/HttpServer.h @@ -0,0 +1,30 @@ +#ifndef APP_HTTPSERVER_HTTPSERVER_HTTPSERVER_H_ +#define APP_HTTPSERVER_HTTPSERVER_HTTPSERVER_H_ + +#include +#include +#include +#include +#include + +#include "HttpConnection.h" +#include "Router.h" + +class HttpServer : private boost::noncopyable { + public: + HttpServer(const std::string& address, const std::string& port, std::size_t thread_pool_size); + void run(); + private: + void startAccept(); + void handleAccept(const boost::system::error_code& e); + void handleStop(); + + std::size_t thread_pool_size; + boost::asio::io_service io_service; + boost::asio::signal_set signals; + boost::asio::ip::tcp::acceptor acceptor; + std::shared_ptr connection; +}; + + +#endif // APP_HTTPSERVER_HTTPSERVER_HTTPSERVER_H_ diff --git a/server/internal/httpServer/include/Parser.h b/server/internal/httpServer/include/Parser.h new file mode 100644 index 0000000000000000000000000000000000000000..142f234549feb2d8dda44ddd630b142e877b0bbb --- /dev/null +++ b/server/internal/httpServer/include/Parser.h @@ -0,0 +1,57 @@ +#ifndef APP_HTTPSERVER_HTTPSERVER_PARSER_H_ +#define APP_HTTPSERVER_HTTPSERVER_PARSER_H_ + +#include "Request.h" + +#include +#include + +class Parser { + public: + Parser(); + void reset(); + + template + boost::tuple parse(Request& req, + InputIterator begin, InputIterator end) { + while (begin != end) { + boost::tribool result = consume(req, *begin++); + if (result || !result) + return boost::make_tuple(result, begin); + } + boost::tribool result = boost::indeterminate; + return boost::make_tuple(result, begin); + } + + private: + boost::tribool consume(Request& req, char input); + static bool isChar(int c); + static bool isCtl(int c); + static bool isTspecial(int c); + static bool isDigit(int c); + + enum state { + method_start, + method, + uri, + http_version_h, + http_version_t_1, + http_version_t_2, + http_version_p, + http_version_slash, + http_version_major_start, + http_version_major, + http_version_minor_start, + http_version_minor, + expecting_newline_1, + header_line_start, + header_lws, + header_name, + space_before_header_value, + header_value, + expecting_newline_2, + expecting_newline_3 + } state; +}; + +#endif // APP_HTTPSERVER_HTTPSERVER_PARSER_H_ diff --git a/server/internal/httpServer/include/Request.h b/server/internal/httpServer/include/Request.h new file mode 100644 index 0000000000000000000000000000000000000000..386f9b3fe8a1a62c8cb50dd8221d3cf48998910d --- /dev/null +++ b/server/internal/httpServer/include/Request.h @@ -0,0 +1,17 @@ +#ifndef APP_HTTPSERVER_HTTPSERVER_REQUEST_H_ +#define APP_HTTPSERVER_HTTPSERVER_REQUEST_H_ + +#include +#include + +#include "Header.h" + +struct Request { + std::string method; + std::string uri; + int http_version_major; + int http_version_minor; + std::vector
headers; +}; + +#endif // APP_HTTPSERVER_HTTPSERVER_REQUEST_H_ diff --git a/server/internal/httpServer/include/Response.h b/server/internal/httpServer/include/Response.h new file mode 100644 index 0000000000000000000000000000000000000000..6dd3a1d01b5461b45d4205bc1996bec8945fc69d --- /dev/null +++ b/server/internal/httpServer/include/Response.h @@ -0,0 +1,38 @@ +#ifndef APP_HTTPSERVER_HTTPSERVER_REPLY_H_ +#define APP_HTTPSERVER_HTTPSERVER_REPLY_H_ + +#include +#include +#include + +#include "Header.h" + +struct Response { + enum status_type { + ok = 200, + created = 201, + accepted = 202, + no_content = 204, + multiple_choices = 300, + moved_permanently = 301, + moved_temporarily = 302, + not_modified = 304, + bad_request = 400, + unauthorized = 401, + forbidden = 403, + not_found = 404, + internal_server_error = 500, + not_implemented = 501, + bad_gateway = 502, + service_unavailable = 503 + } status; + + std::vector
headers; + std::string content; + + std::vector toBuffers(); + static Response stockResponse(status_type status); +}; + + +#endif // APP_HTTPSERVER_HTTPSERVER_REPLY_H_ diff --git a/server/internal/httpServer/include/Router.h b/server/internal/httpServer/include/Router.h new file mode 100644 index 0000000000000000000000000000000000000000..50267ea8583471a3e005aed4832ae791fd451a71 --- /dev/null +++ b/server/internal/httpServer/include/Router.h @@ -0,0 +1,35 @@ +#ifndef APP_HTTPSERVER_HTTPSERVER_ROUTER_H_ +#define APP_HTTPSERVER_HTTPSERVER_ROUTER_H_ + +#include +#include +#include + +#include "SolutionManager.h" +#include "UserManager.h" +#include "TaskManager.h" +#include "Response.h" +#include "Request.h" + +class Router : private boost::noncopyable { + public: + Router(); + void handleRequest(const Request& req, Response& res); + void setSolutionManager(std::shared_ptr mng) { + solutionManager = mng; + } + void setUserManager(std::shared_ptr mng) { + userManager = mng; + } + void setTaskManager(std::shared_ptr mng) { + taskManager = mng; + } + private: + std::shared_ptr solutionManager; + std::shared_ptr userManager; + std::shared_ptr taskManager; + static bool decodeUrl(const std::string& in, std::string& out); +}; + + +#endif // APP_HTTPSERVER_HTTPSERVER_ROUTER_H_ diff --git a/server/internal/httpServer/include/Serializer.h b/server/internal/httpServer/include/Serializer.h new file mode 100644 index 0000000000000000000000000000000000000000..a8a68be2b2411b67bcfed9f20150dcfc0f1afd80 --- /dev/null +++ b/server/internal/httpServer/include/Serializer.h @@ -0,0 +1,14 @@ +#ifndef APP_HTTPSERVER_HTTPSERVER_MANAGERS_SERIALIZER_H_ +#define APP_HTTPSERVER_HTTPSERVER_MANAGERS_SERIALIZER_H_ + +#include +#include +#include + +#include "Solution.hpp" +#include "User.hpp" + +class Serializer {}; + + +#endif // APP_HTTPSERVER_HTTPSERVER_MANAGERS_SERIALIZER_H_ diff --git a/server/internal/httpServer/include/SolutionManager.h b/server/internal/httpServer/include/SolutionManager.h new file mode 100644 index 0000000000000000000000000000000000000000..5a110652b507d7992ff09b8d7692e68055ec7208 --- /dev/null +++ b/server/internal/httpServer/include/SolutionManager.h @@ -0,0 +1,27 @@ +#ifndef APP_HTTPSERVER_HTTPSERVER_MANAGERS_SolutionMANAGER_H_ +#define APP_HTTPSERVER_HTTPSERVER_MANAGERS_SolutionMANAGER_H_ + +#include +#include + +#include "Response.h" +#include "Request.h" +#include "Serializer.h" +#include "ISolutionManager.h" +#include "ISolutionService.h" + +class SolutionManager : public ISolutionManager { + public: + SolutionManager(); + Response getAllSolutions(const Request &req) override; + Response createSolution(const Request &req) override; + Response getMetrics(const Request &req) override; + void setService(std::shared_ptr service); + + private: + std::shared_ptr solutionService; + std::shared_ptr serializer; + static std::string getParam(const std::string& path, const std::string& name); +}; + +#endif // APP_HTTPSERVER_HTTPSERVER_MANAGERS_SolutionMANAGER_H_ diff --git a/server/internal/httpServer/include/TaskManager.h b/server/internal/httpServer/include/TaskManager.h new file mode 100644 index 0000000000000000000000000000000000000000..c49b08b60cac92e3cb909d52d463000faff48d96 --- /dev/null +++ b/server/internal/httpServer/include/TaskManager.h @@ -0,0 +1,25 @@ +#ifndef APP_HTTPSERVER_HTTPSERVER_MANAGERS_TaskMANAGER_H_ +#define APP_HTTPSERVER_HTTPSERVER_MANAGERS_TaskMANAGER_H_ + +#include +#include + +#include "Response.h" +#include "Request.h" +#include "Serializer.h" +#include "ITaskManager.h" +#include "ITaskService.h" + +class TaskManager : public ITaskManager { +public: + TaskManager(); + Response createTask(const Request &req) override; + Response getAllTasks(const Request &req) override; + void setService(std::shared_ptr service); +private: + std::shared_ptr taskService; + std::shared_ptr serializer; + static std::string getParam(const std::string& path, const std::string& name); +}; + +#endif // APP_HTTPSERVER_HTTPSERVER_MANAGERS_TaskMANAGER_H_ diff --git a/server/internal/httpServer/include/UserManager.h b/server/internal/httpServer/include/UserManager.h new file mode 100644 index 0000000000000000000000000000000000000000..9043ada99edf4501c174b9f66c289406f9bb6c13 --- /dev/null +++ b/server/internal/httpServer/include/UserManager.h @@ -0,0 +1,25 @@ +#ifndef APP_HTTPSERVER_HTTPSERVER_MANAGERS_USERMANAGER_H_ +#define APP_HTTPSERVER_HTTPSERVER_MANAGERS_USERMANAGER_H_ + +#include +#include + +#include "Response.h" +#include "Request.h" +#include "Serializer.h" +#include "IUserManager.h" +#include "IUserService.h" + +class UserManager : public IUserManager { + public: + UserManager(); + Response loginUser(const Request &req) override; + Response registerUser(const Request &req) override; + void setService(std::shared_ptr service); + private: + std::shared_ptr userService; + std::shared_ptr serializer; + static std::string getParam(const std::string& path, const std::string& name); +}; + +#endif // APP_HTTPSERVER_HTTPSERVER_MANAGERS_USERMANAGER_H_ diff --git a/server/internal/httpServer/src/HttpConnection.cpp b/server/internal/httpServer/src/HttpConnection.cpp new file mode 100644 index 0000000000000000000000000000000000000000..412f67067450d546bcc719fed3edad9ffc741a82 --- /dev/null +++ b/server/internal/httpServer/src/HttpConnection.cpp @@ -0,0 +1,16 @@ +#include "HttpConnection.h" + +#include + +HttpConnection::HttpConnection(boost::asio::io_service& io_service) + : strand(io_service), + socket(io_service) {} + +boost::asio::ip::tcp::socket& HttpConnection::getSocket() {} + +void HttpConnection::start() {} + +void HttpConnection::handleRead(const boost::system::error_code& e, + std::size_t bytes_transferred) {} + +void HttpConnection::handleWrite(const boost::system::error_code& e) {} diff --git a/server/internal/httpServer/src/HttpServer.cpp b/server/internal/httpServer/src/HttpServer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..246b4f085e17659efdfd58af64359dd3b2d39638 --- /dev/null +++ b/server/internal/httpServer/src/HttpServer.cpp @@ -0,0 +1,20 @@ +#include "HttpServer.h" + +#include +#include +#include +#include + +HttpServer::HttpServer(const std::string& address, const std::string& port, std::size_t thread_pool_size) + : thread_pool_size(thread_pool_size), + signals(io_service), + acceptor(io_service), + connection() {} + +void HttpServer::run() {} + +void HttpServer::startAccept() {} + +void HttpServer::handleAccept(const boost::system::error_code& e) {} + +void HttpServer::handleStop() {} diff --git a/server/internal/httpServer/src/Parser.cpp b/server/internal/httpServer/src/Parser.cpp new file mode 100644 index 0000000000000000000000000000000000000000..86b95414a5f8a365d589d50fb846bec5406cbb14 --- /dev/null +++ b/server/internal/httpServer/src/Parser.cpp @@ -0,0 +1,17 @@ +#include "Parser.h" +#include "Request.h" + +Parser::Parser() + : state(method_start) {} + +void Parser::reset() {} + +boost::tribool Parser::consume(Request& req, char input) {} + +bool Parser::isChar(int c) {} + +bool Parser::isCtl(int c) {} + +bool Parser::isTspecial(int c) {} + +bool Parser::isDigit(int c) {} diff --git a/server/internal/httpServer/src/Response.cpp b/server/internal/httpServer/src/Response.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f688c347c2a65fe4b6e92bcf2d37f37aff0a5f82 --- /dev/null +++ b/server/internal/httpServer/src/Response.cpp @@ -0,0 +1,5 @@ +#include "Response.h" + +std::vector Response::toBuffers() {} + +Response Response::stockResponse(Response::status_type status) {} diff --git a/server/internal/httpServer/src/Router.cpp b/server/internal/httpServer/src/Router.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e235deef01ebe59b22c4908c4ad2207c406e6623 --- /dev/null +++ b/server/internal/httpServer/src/Router.cpp @@ -0,0 +1,15 @@ +#include "Router.h" + +#include +#include +#include + +#include "Response.h" + +Router::Router() : + solutionManager(std::make_shared()), + userManager(std::make_shared()) {} + +void Router::handleRequest(const Request& req, Response& res) {} + +bool Router::decodeUrl(const std::string& in, std::string& out) {} diff --git a/server/internal/httpServer/src/SolutionManager.cpp b/server/internal/httpServer/src/SolutionManager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3a93e4110f66c3e54e80a5f4fd42348009ccc203 --- /dev/null +++ b/server/internal/httpServer/src/SolutionManager.cpp @@ -0,0 +1,26 @@ +// +// Created by Николай Степанов on 03.05.2023. +// +#include "SolutionManager.h" + +SolutionManager::SolutionManager() {} + +Response SolutionManager::getAllSolutions(const Request &req) { + return Response(); +} + +Response SolutionManager::createSolution(const Request &req) { + return Response(); +} + +Response SolutionManager::getMetrics(const Request &req) { + return Response(); +} + +std::string SolutionManager::getParam(const std::string &path, const std::string &name) { + return std::string(); +} + +void SolutionManager::setService(std::shared_ptr service) { + solutionService = service; +} diff --git a/server/internal/httpServer/src/TaskManager.cpp b/server/internal/httpServer/src/TaskManager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ca3875d970e6cf86e421a6fb9aa3b1fa8e45a6ef --- /dev/null +++ b/server/internal/httpServer/src/TaskManager.cpp @@ -0,0 +1,24 @@ +// +// Created by Николай Степанов on 03.05.2023. +// +#include "TaskManager.h" + +TaskManager::TaskManager() { + +} + +Response TaskManager::createTask(const Request &req) { + return Response(); +} + +Response TaskManager::getAllTasks(const Request &req) { + return Response(); +} + +std::string TaskManager::getParam(const std::string &path, const std::string &name) { + return std::string(); +} + +void TaskManager::setService(std::shared_ptr service) { + taskService = service; +} diff --git a/server/internal/httpServer/src/UserManager.cpp b/server/internal/httpServer/src/UserManager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..41377167c08ed5fa409c174fb00b58eee6561d55 --- /dev/null +++ b/server/internal/httpServer/src/UserManager.cpp @@ -0,0 +1,24 @@ +// +// Created by Николай Степанов on 03.05.2023. +// +#include "UserManager.h" + +UserManager::UserManager() { + +} + +Response UserManager::loginUser(const Request &req) { + return Response(); +} + +Response UserManager::registerUser(const Request &req) { + return Response(); +} + +std::string UserManager::getParam(const std::string &path, const std::string &name) { + return std::string(); +} + +void UserManager::setService(std::shared_ptr service) { + userService = service; +} diff --git a/server/internal/httpServer/tests/CMakeLists.txt b/server/internal/httpServer/tests/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..c635b606c07d8543b828f3d8591794b92968b31f --- /dev/null +++ b/server/internal/httpServer/tests/CMakeLists.txt @@ -0,0 +1,16 @@ +project(test_httpserver) + +set(CMAKE_CXX_STANDARD 20) +add_compile_options(-coverage) + +file(GLOB SOURCES *.cpp) + +enable_testing() +find_package(GTest REQUIRED) + +add_executable(${PROJECT_NAME} ${SOURCES}) + +target_link_libraries(${PROJECT_NAME} ${HTTPSERVER_lib_LIB} GTest::GTest GTest::gmock) +target_include_directories(${PROJECT_NAME} PUBLIC ${HTTPSERVER_lib_INCLUDE_DIRS} ${SERVICE_lib_INCLUDE_DIRS}) + +add_test(test_httpserver test_httpserver) \ No newline at end of file diff --git a/server/internal/httpServer/tests/RouterSuite.cpp b/server/internal/httpServer/tests/RouterSuite.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6fd733150bdc9fc281ce8a04a9ac088ed957b4ae --- /dev/null +++ b/server/internal/httpServer/tests/RouterSuite.cpp @@ -0,0 +1,124 @@ +#include +#include + +#include "Router.h" +#include "ISolutionManager.h" +#include "ITaskManager.h" +#include "IUserManager.h" + +class SolutionManagerMock : public ISolutionManager { +public: + SolutionManagerMock() = default; + MOCK_METHOD(Response, getAllSolutions, (const Request &req), (override)); + MOCK_METHOD(Response, createSolution, (const Request& req), (override)); + MOCK_METHOD(Response, getMetrics, (const Request& req), (override)); +}; + +class TaskManagerMock : public ITaskManager { +public: + TaskManagerMock() = default; + MOCK_METHOD(Response, createTask, (const Request &req), (override)); + MOCK_METHOD(Response, getAllTasks, (const Request& req), (override)); +}; + +class UserManagerMock : public IUserManager { +public: + UserManagerMock() = default; + MOCK_METHOD(Response, loginUser, (const Request &req), (override)); + MOCK_METHOD(Response, registerUser, (const Request& req), (override)); +}; + +class RouterSuite : public ::testing::Test { +protected: + void SetUp() override { + router.setSolutionManager(solutionManager); + router.setUserManager(userManager); + router.setTaskManager(taskManager); + } + + std::shared_ptr userManager = std::make_shared(); + std::shared_ptr taskManager = std::make_shared(); + std::shared_ptr solutionManager = std::make_shared(); + Router router; +}; + +TEST_F(RouterSuite, RegisterUserTest) { + Request req; + req.method = "POST"; + req.uri = "/user/register"; + Response res; + EXPECT_CALL(*userManager, registerUser); + router.handleRequest(req, res); +} + +TEST_F(RouterSuite, LoginUserTest) { + Request req; + req.method = "GET"; + req.uri = "/user/login"; + Response res; + EXPECT_CALL(*userManager, loginUser); + router.handleRequest(req, res); +} + +TEST_F(RouterSuite, GetAllTasksTest) { + Request req; + req.method = "GET"; + req.uri = "/task/all"; + Response res; + EXPECT_CALL(*taskManager, getAllTasks); + router.handleRequest(req, res); +} + +TEST_F(RouterSuite, CreateTaskTest) { + Request req; + req.method = "POST"; + req.uri = "/task/create"; + Response res; + EXPECT_CALL(*taskManager, createTask); + router.handleRequest(req, res); +} + +TEST_F(RouterSuite, GetSolutionMetricsTest) { + Request req; + req.method = "GET"; + req.uri = "/solution/metrics"; + Response res; + EXPECT_CALL(*solutionManager, getMetrics); + router.handleRequest(req, res); +} + +TEST_F(RouterSuite, CreateSolutionTest) { + Request req; + req.method = "POST"; + req.uri = "/solution/create"; + Response res; + EXPECT_CALL(*solutionManager, createSolution); + router.handleRequest(req, res); +} + +TEST_F(RouterSuite, GetAllSolutionsTest) { + Request req; + req.method = "GET"; + req.uri = "/solution/all"; + Response res; + EXPECT_CALL(*solutionManager, getAllSolutions); + router.handleRequest(req, res); +} + +TEST_F(RouterSuite, BadMethodTest) { + Request req; + req.method = ""; + req.uri = "/solution/all"; + Response res; + router.handleRequest(req, res); + EXPECT_EQ(res.status, 500); +} + +TEST_F(RouterSuite, BadUriTest) { + Request req; + req.method = "GET"; + req.uri = ""; + Response res; + router.handleRequest(req, res); + EXPECT_EQ(res.status, 500); +} \ No newline at end of file diff --git a/server/internal/httpServer/tests/SolutionManagerSuite.cpp b/server/internal/httpServer/tests/SolutionManagerSuite.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fb5cc5489bfcb42eac32a531b975b4b33849576a --- /dev/null +++ b/server/internal/httpServer/tests/SolutionManagerSuite.cpp @@ -0,0 +1,60 @@ +#include +#include + +#include "SolutionManager.h" +#include "ISolutionService.h" + +class SolutionServiceMock : public ISolutionService { +public: + SolutionServiceMock() = default; + MOCK_METHOD(Solution, createSolution, (size_t userId, size_t taskId, std::string source), (override)); + MOCK_METHOD(std::vector, getSolutionsByUserAndTaskId, (size_t userId, size_t taskId), (override)); + MOCK_METHOD((std::pair), getMetrics, (size_t solId), (override)); + MOCK_METHOD(void, deleteSolutionById, (size_t solId), (override)); +}; + +class SolutionManagerSuite : public ::testing::Test { +protected: + void SetUp() override { + manager.setService(solutionService); + } + + std::shared_ptr solutionService = std::make_shared(); + SolutionManager manager; +}; + +TEST_F(SolutionManagerSuite, GetSolutionByUserAndTaskTest) { + Request req; + Header h1, h2; + h1.name = "user_id"; + h2.name = "task_id"; + h1.value = '1'; + h2.value = '2'; + req.headers = {h1, h2}; + EXPECT_CALL(*solutionService, getSolutionsByUserAndTaskId(1, 2)); + manager.getAllSolutions(req); +} + +TEST_F(SolutionManagerSuite, GetMetricsTest) { + Request req; + Header h1; + h1.name = "sol_id"; + h1.value = "1"; + req.headers = {h1}; + EXPECT_CALL(*solutionService, getMetrics(1)); + manager.getMetrics(req); +} + +TEST_F(SolutionManagerSuite, CreateSolutionTest) { + Request req; + Header h1, h2, h3; + h1.name = "user_id"; + h1.value = "1"; + h2.name = "task_id"; + h2.value = "2"; + h3.name = "source"; + h3.value = "int main() { return 0; }"; + req.headers = {h1, h2, h3}; + EXPECT_CALL(*solutionService, createSolution(1, 2, "int main() { return 0; }")); + manager.createSolution(req); +} \ No newline at end of file diff --git a/server/internal/httpServer/tests/TaskManagerSuite.cpp b/server/internal/httpServer/tests/TaskManagerSuite.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f4822d28294513c7e522d9a9c30bf0b826985973 --- /dev/null +++ b/server/internal/httpServer/tests/TaskManagerSuite.cpp @@ -0,0 +1,42 @@ +#include +#include + +#include "TaskManager.h" +#include "ITaskService.h" + +class TaskServiceMock : public ITaskService { +public: + TaskServiceMock() = default; + ~TaskServiceMock() = default; + + MOCK_METHOD(Task, createTask, (std::string desc), (override)); + MOCK_METHOD(Task, getTask, (size_t id), (override)); + MOCK_METHOD(std::vector, getAllTasks, (), (override)); + MOCK_METHOD(void, deleteTask, (size_t id), (override)); +}; + +class TaskManagerSuite : public ::testing::Test { +protected: + void SetUp() override { + manager.setService(taskService); + } + + std::shared_ptr taskService = std::make_shared(); + TaskManager manager; +}; + +TEST_F(TaskManagerSuite, CreateTaskTest) { + Request req; + Header h1, h2; + h1.name = "description"; + h1.value = "a"; + req.headers = {h1}; + EXPECT_CALL(*taskService, createTask("a")); + manager.createTask(req); +} + +TEST_F(TaskManagerSuite, GetAllTaskTest) { + Request req; + EXPECT_CALL(*taskService, getAllTasks); + manager.getAllTasks(req); +} \ No newline at end of file diff --git a/server/internal/httpServer/tests/UserManagerSuite.cpp b/server/internal/httpServer/tests/UserManagerSuite.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ad6b9d459c74b027e02d5773baf3c0a7a551ee87 --- /dev/null +++ b/server/internal/httpServer/tests/UserManagerSuite.cpp @@ -0,0 +1,48 @@ +#include +#include + +#include "UserManager.h" +#include "IUserService.h" + +class UserServiceMock : public IUserService { +public: + UserServiceMock() = default; + ~UserServiceMock() = default; + MOCK_METHOD(User, createUser, (std::string login, std::string username, std::string password), (override)); + MOCK_METHOD(User, getUserById, (size_t id), (override)); + MOCK_METHOD(void, deleteUser, (size_t id), (override)); +}; + +class UserManagerSuite : public ::testing::Test { +protected: + void SetUp() override { + manager.setService(userService); + } + + std::shared_ptr userService = std::make_shared(); + UserManager manager; +}; + +TEST_F(UserManagerSuite, LoginUserTest) { + Request req; + Header h1, h2; + h1.name = "login"; + h1.value = 1; + req.headers = {h1}; + EXPECT_CALL(*userService, getUserById(1)); + manager.loginUser(req); +} + +TEST_F(UserManagerSuite, RgisterUserTest) { + Request req; + Header h1, h2, h3; + h1.name = "login"; + h1.value = "1"; + h2.name = "username"; + h2.value = "2"; + h3.name = "password"; + h3.value = "3"; + req.headers = {h1, h2, h3}; + EXPECT_CALL(*userService, createUser("1", "2", "3")); + manager.registerUser(req); +} \ No newline at end of file diff --git a/server/internal/httpServer/tests/main.cpp b/server/internal/httpServer/tests/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b8dd7bc6e0d123949b555853484c2be77c6c386d --- /dev/null +++ b/server/internal/httpServer/tests/main.cpp @@ -0,0 +1,8 @@ +#include +#include + +int main(int argc, char** argv) { + ::testing::InitGoogleMock(&argc, argv); + + return RUN_ALL_TESTS(); +} \ No newline at end of file diff --git a/server/internal/httpServer/virtual/ISolutionManager.h b/server/internal/httpServer/virtual/ISolutionManager.h new file mode 100644 index 0000000000000000000000000000000000000000..cd77215cdf02f436ad3ddb7829b26efc4f4ebc69 --- /dev/null +++ b/server/internal/httpServer/virtual/ISolutionManager.h @@ -0,0 +1,17 @@ +#ifndef APP_HTTPSERVER_HTTPSERVER_MANAGERS_ISolutionMANAGER_H_ +#define APP_HTTPSERVER_HTTPSERVER_MANAGERS_ISolutionMANAGER_H_ + +#include +#include + +#include "Response.h" +#include "Request.h" + +class ISolutionManager { +public: + virtual Response getAllSolutions(const Request &req) = 0; + virtual Response createSolution(const Request &req) = 0; + virtual Response getMetrics(const Request &req) = 0; +}; + +#endif // APP_HTTPSERVER_HTTPSERVER_MANAGERS_ISolutionMANAGER_H_ diff --git a/server/internal/httpServer/virtual/ITaskManager.h b/server/internal/httpServer/virtual/ITaskManager.h new file mode 100644 index 0000000000000000000000000000000000000000..11747f7072c12aa138b1d6618ab53c8c13c7fa66 --- /dev/null +++ b/server/internal/httpServer/virtual/ITaskManager.h @@ -0,0 +1,17 @@ +#ifndef APP_HTTPSERVER_HTTPSERVER_MANAGERS_ITaskMANAGER_H_ +#define APP_HTTPSERVER_HTTPSERVER_MANAGERS_ITaskMANAGER_H_ + +#include +#include + +#include "Response.h" +#include "Request.h" +#include "Serializer.h" + +class ITaskManager { +public: + virtual Response createTask(const Request &req) = 0; + virtual Response getAllTasks(const Request &req) = 0; +}; + +#endif // APP_HTTPSERVER_HTTPSERVER_MANAGERS_ITaskMANAGER_H_ diff --git a/server/internal/httpServer/virtual/IUserManager.h b/server/internal/httpServer/virtual/IUserManager.h new file mode 100644 index 0000000000000000000000000000000000000000..599a8ec9e85c342f11e0bd2e4808af9838cbff77 --- /dev/null +++ b/server/internal/httpServer/virtual/IUserManager.h @@ -0,0 +1,17 @@ +#ifndef APP_HTTPSERVER_HTTPSERVER_MANAGERS_IUserMANAGER_H_ +#define APP_HTTPSERVER_HTTPSERVER_MANAGERS_IUserMANAGER_H_ + +#include +#include + +#include "Response.h" +#include "Request.h" +#include "Serializer.h" + +class IUserManager { +public: + virtual Response loginUser(const Request &req) = 0; + virtual Response registerUser(const Request &req) = 0; +}; + +#endif // APP_HTTPSERVER_HTTPSERVER_MANAGERS_IUserMANAGER_H_