Files
Adminive/backend/service/tests/drogon_adapter_test.cpp
T
2026-08-08 19:16:58 +08:00

169 lines
6.6 KiB
C++

#include "adminive/adapters/drogon.hpp"
#include "adminive/adapters/nlohmann_json.hpp"
#include "adminive_test.hpp"
#include <functional>
#include <string>
#include <utility>
#include <vector>
namespace drogon_test {
struct Config {
std::string name{"default"};
};
struct Status {
std::string user;
};
}
namespace adminive {
template <>
struct Type_Descriptor<drogon_test::Config> {
static auto get() {
using T = drogon_test::Config;
return object<T>("config", "Config", ADMINIVE_FIELD(T, name).editable().creatable());
}
};
template <>
struct Type_View_Descriptor<drogon_test::Config> {
static Table_View table() {
using T = drogon_test::Config;
return table_view<T>(column<&T::name>("Name").sort().search());
}
};
template <>
struct Type_Descriptor<drogon_test::Status> {
static auto get() {
using T = drogon_test::Status;
return object<T>("status", "Status", ADMINIVE_FIELD(T, user).label("User"));
}
};
}
int main() {
using Json = nlohmann::json;
drogon_test::Config config;
drogon::HttpAppFramework app;
std::vector<std::function<void()>> tasks;
std::string committed_user;
adminive::Resource_Transaction<drogon_test::Config> transaction;
transaction.commit = [&committed_user](const drogon_test::Config&, const adminive::Request_Context& context) {
committed_user = context.user;
};
adminive::Drogon_Bind_Options options;
options.executor = [&tasks](std::function<void()> task) {
tasks.push_back(std::move(task));
};
options.filters = {"LoginFilter", "AdminFilter"};
options.context_factory = [](const drogon::HttpRequestPtr& request) {
adminive::Request_Context context;
context.user = request->user;
return context;
};
{
adminive::Drogon_Resource<drogon_test::Config, Json> resource(config, "/config", std::move(transaction));
resource.bind(app, options);
adminive::Drogon_Status_Resource<drogon_test::Status, Json> status("/status", [](const adminive::Request_Context& context) {
if(context.user == "error") {
throw std::runtime_error("status failed");
}
return drogon_test::Status{context.user};
});
status.bind(app, options);
}
ADMINIVE_CHECK(app.filters("/config/data", drogon::Post).size() == 2);
ADMINIVE_CHECK(app.filters("/status/data", drogon::Get).size() == 2);
auto request = std::make_shared<drogon::HttpRequest>();
drogon::HttpResponsePtr response;
app.handle("/config/view", drogon::Get, request, [&response](const drogon::HttpResponsePtr& value) {
response = value;
});
ADMINIVE_CHECK(response->status == drogon::k200OK);
ADMINIVE_CHECK(Json::parse(response->body).at("data").at("kind") == "form");
request->body = R"({"name":"updated"})";
request->user = "wyc";
response.reset();
app.handle("/config/data", drogon::Post, request, [&response](const drogon::HttpResponsePtr& value) {
response = value;
});
ADMINIVE_CHECK(!response);
ADMINIVE_CHECK(tasks.size() == 1);
tasks.front()();
tasks.erase(tasks.begin());
ADMINIVE_CHECK(response);
ADMINIVE_CHECK(response->status == drogon::k200OK);
ADMINIVE_CHECK(config.name == "updated");
ADMINIVE_CHECK(committed_user == "wyc");
response.reset();
app.handle("/status/data", drogon::Get, request, [&response](const drogon::HttpResponsePtr& value) {
response = value;
});
ADMINIVE_CHECK(!response);
ADMINIVE_CHECK(tasks.size() == 1);
tasks.front()();
tasks.erase(tasks.begin());
ADMINIVE_CHECK(response->status == drogon::k200OK);
ADMINIVE_CHECK(Json::parse(response->body).at("data").at("user").at("value") == "wyc");
request->user = "error";
response.reset();
app.handle("/status/data", drogon::Get, request, [&response](const drogon::HttpResponsePtr& value) {
response = value;
});
tasks.front()();
tasks.erase(tasks.begin());
ADMINIVE_CHECK(response->status == drogon::k500InternalServerError);
response.reset();
app.handle("/status/descriptor", drogon::Get, request, [&response](const drogon::HttpResponsePtr& value) {
response = value;
});
ADMINIVE_CHECK(response->status == drogon::k200OK);
adminive::Drogon_Collection_Resource<drogon_test::Config, Json> collection("/configs", {drogon_test::Config{"first"}});
collection.bind(app, options);
response.reset();
app.handle("/configs/view", drogon::Get, request, [&response](const drogon::HttpResponsePtr& value) {
response = value;
});
ADMINIVE_CHECK(response->status == drogon::k200OK);
ADMINIVE_CHECK(Json::parse(response->body).at("data").at("kind") == "table");
ADMINIVE_CHECK(Json::parse(response->body).at("data").at("columns").at(0).at("searchable") == true);
request->parameters = {{"page", "1"}, {"perPage", "10"}, {"name", "fir"}};
response.reset();
app.handle("/configs", drogon::Get, request, [&response](const drogon::HttpResponsePtr& value) {
response = value;
});
ADMINIVE_CHECK(response->status == drogon::k200OK);
ADMINIVE_CHECK(Json::parse(response->body).at("data").at("total") == 1);
response.reset();
app.handle("/configs/1", drogon::Get, request, [&response](const drogon::HttpResponsePtr& value) {
response = value;
});
ADMINIVE_CHECK(response->status == drogon::k200OK);
ADMINIVE_CHECK(Json::parse(response->body).at("data").at("name") == "first");
request->body = R"({"name":"second"})";
response.reset();
app.handle("/configs", drogon::Post, request, [&response](const drogon::HttpResponsePtr& value) {
response = value;
});
ADMINIVE_CHECK(!response);
ADMINIVE_CHECK(tasks.size() == 1);
tasks.front()();
tasks.erase(tasks.begin());
ADMINIVE_CHECK(response->status == drogon::k200OK);
ADMINIVE_CHECK(collection.size() == 2);
request->body = R"({"name":"changed"})";
response.reset();
app.handle("/configs/2", drogon::Patch, request, [&response](const drogon::HttpResponsePtr& value) {
response = value;
});
tasks.front()();
tasks.erase(tasks.begin());
ADMINIVE_CHECK(response->status == drogon::k200OK);
ADMINIVE_CHECK(Json::parse(response->body).at("data").at("name") == "changed");
response.reset();
app.handle("/configs/1", drogon::Delete, request, [&response](const drogon::HttpResponsePtr& value) {
response = value;
});
tasks.front()();
tasks.erase(tasks.begin());
ADMINIVE_CHECK(response->status == drogon::k200OK);
ADMINIVE_CHECK(collection.size() == 1);
ADMINIVE_CHECK(app.filters("/configs/{1:id}", drogon::Patch).size() == 2);
return 0;
}