test_settings.cpp 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. #include <gtest/gtest.h>
  2. #include "settings.hpp"
  3. #include "apikey.hpp"
  4. #include <cctype>
  5. using namespace svapi;
  6. TEST(Settings, DefaultsAndRoundTrip) {
  7. Settings s = Settings::fromJson(nlohmann::json::object());
  8. EXPECT_EQ(s.openaiApiBase, "https://api.openai.com");
  9. EXPECT_EQ(s.defaultEmbeddingModel, "text-embedding-3-small");
  10. EXPECT_EQ(s.sessionTtlMinutes, 720u);
  11. EXPECT_TRUE(s.webuiEnabled);
  12. EXPECT_EQ(s.defaultProject, "default");
  13. EXPECT_EQ(Settings::fromJson(s.toJson()).toJson(), s.toJson());
  14. }
  15. TEST(Settings, EmbeddingTimeoutDefaults) {
  16. Settings s = Settings::fromJson(nlohmann::json::object());
  17. EXPECT_EQ(s.embeddingConnectTimeoutSec, 10u);
  18. EXPECT_EQ(s.embeddingReadTimeoutSec, 60u);
  19. }
  20. TEST(Settings, EmbeddingTimeoutRoundTrip) {
  21. nlohmann::json j{{"embedding_connect_timeout_sec", 30}, {"embedding_read_timeout_sec", 120}};
  22. Settings s = Settings::fromJson(j);
  23. EXPECT_EQ(s.embeddingConnectTimeoutSec, 30u);
  24. EXPECT_EQ(s.embeddingReadTimeoutSec, 120u);
  25. // round-trip: toJson → fromJson preserves values
  26. Settings s2 = Settings::fromJson(s.toJson());
  27. EXPECT_EQ(s2.embeddingConnectTimeoutSec, 30u);
  28. EXPECT_EQ(s2.embeddingReadTimeoutSec, 120u);
  29. }
  30. TEST(Settings, CaptchaDefaults) {
  31. Settings s = Settings::fromJson(nlohmann::json::object());
  32. EXPECT_EQ(s.captchaProvider, "");
  33. EXPECT_EQ(s.captchaSecret, "");
  34. EXPECT_EQ(s.captchaVerifyUrl, "");
  35. }
  36. TEST(Settings, CaptchaProviderAndUrlRoundTrip) {
  37. nlohmann::json j{{"captcha_provider", "turnstile"},
  38. {"captcha_verify_url", "https://challenges.cloudflare.com/turnstile/v0/siteverify"}};
  39. Settings s = Settings::fromJson(j);
  40. EXPECT_EQ(s.captchaProvider, "turnstile");
  41. EXPECT_EQ(s.captchaVerifyUrl, "https://challenges.cloudflare.com/turnstile/v0/siteverify");
  42. Settings s2 = Settings::fromJson(s.toJson());
  43. EXPECT_EQ(s2.captchaProvider, "turnstile");
  44. EXPECT_EQ(s2.captchaVerifyUrl, "https://challenges.cloudflare.com/turnstile/v0/siteverify");
  45. }
  46. TEST(Settings, CaptchaSecretRoundTrip) {
  47. nlohmann::json j{{"captcha_secret", "mysecret"}};
  48. Settings s = Settings::fromJson(j);
  49. EXPECT_EQ(s.captchaSecret, "mysecret");
  50. Settings s2 = Settings::fromJson(s.toJson());
  51. EXPECT_EQ(s2.captchaSecret, "mysecret");
  52. }
  53. TEST(ApiKey, JsonRoundTripAndPublicMasks) {
  54. ApiKey k = ApiKey::fromJson(nlohmann::json::parse(
  55. R"({"key":"abcdef0123456789","label":"n8n","projects":["p1","p2"],"admin":false,"created_at":7})"));
  56. EXPECT_EQ(k.key, "abcdef0123456789");
  57. EXPECT_EQ(k.projects.size(), 2u);
  58. EXPECT_FALSE(k.admin);
  59. EXPECT_EQ(k.createdAt, 7u);
  60. EXPECT_EQ(ApiKey::fromJson(k.toJson()).toJson(), k.toJson());
  61. auto pub = k.toPublicJson();
  62. EXPECT_FALSE(pub.contains("key")); // secret not exposed
  63. EXPECT_EQ(pub["label"], "n8n");
  64. EXPECT_EQ(pub["projects"].size(), 2u);
  65. EXPECT_TRUE(pub.contains("key_prefix")); // short hint only
  66. }
  67. TEST(ApiKey, CanAccess) {
  68. ApiKey adminK; adminK.admin = true;
  69. EXPECT_TRUE(adminK.canAccess("anything"));
  70. ApiKey star; star.projects = {"*"};
  71. EXPECT_TRUE(star.canAccess("anything"));
  72. ApiKey scoped; scoped.projects = {"p1", "p2"};
  73. EXPECT_TRUE(scoped.canAccess("p1"));
  74. EXPECT_FALSE(scoped.canAccess("p3"));
  75. }
  76. TEST(ApiKey, GenerateIsHexAndUnique) {
  77. std::string a = generateApiKey(), b = generateApiKey();
  78. EXPECT_GE(a.size(), 32u);
  79. EXPECT_NE(a, b);
  80. for (char c : a) EXPECT_TRUE(std::isxdigit(static_cast<unsigned char>(c)));
  81. }