Files
ViewDesignEngine/tests/core/test_license.cpp
T

397 lines
15 KiB
C++
Raw Normal View History

/**
* @file test_license.cpp
* @brief ViewDesignEngine 许可证管理单元测试
*/
#include <gtest/gtest.h>
#include "vde/core/license_manager.h"
#include <string>
#include <ctime>
using namespace vde::core;
// ═══════════════════════════════════════════════════════════════
// LicenseTier 测试
// ═══════════════════════════════════════════════════════════════
TEST(LicenseTier, NameConversion) {
EXPECT_STREQ(license_tier_name(LicenseTier::Community), "Community");
EXPECT_STREQ(license_tier_name(LicenseTier::Professional), "Professional");
EXPECT_STREQ(license_tier_name(LicenseTier::Enterprise), "Enterprise");
}
TEST(LicenseTier, ParseName) {
EXPECT_EQ(parse_license_tier("Community"), 0);
EXPECT_EQ(parse_license_tier("Professional"), 1);
EXPECT_EQ(parse_license_tier("Enterprise"), 2);
EXPECT_EQ(parse_license_tier("community"), 0);
EXPECT_EQ(parse_license_tier("unknown"), -1);
}
// ═══════════════════════════════════════════════════════════════
// Feature 枚举测试
// ═══════════════════════════════════════════════════════════════
TEST(FeatureEnum, FeatureName) {
EXPECT_STREQ(feature_name(Feature::BASIC_BREP), "BASIC_BREP");
EXPECT_STREQ(feature_name(Feature::CAM_5AXIS), "CAM_5AXIS");
EXPECT_STREQ(feature_name(Feature::TECHNICAL_SUPPORT), "TECHNICAL_SUPPORT");
}
TEST(FeatureEnum, ParseFeature) {
EXPECT_EQ(parse_feature("BASIC_BREP"), 0);
EXPECT_EQ(parse_feature("CAM_5AXIS"), 10);
EXPECT_EQ(parse_feature("TECHNICAL_SUPPORT"), 30);
EXPECT_EQ(parse_feature("NONEXISTENT"), -1);
}
// ═══════════════════════════════════════════════════════════════
// Tier → Feature 映射测试
// ═══════════════════════════════════════════════════════════════
TEST(TierFeatures, CommunityLevel) {
auto feats = features_for_tier(LicenseTier::Community);
EXPECT_GE(feats.size(), 6u); // 至少6个基础功能
EXPECT_TRUE(feature_available_in_tier(Feature::BASIC_BREP, LicenseTier::Community));
EXPECT_TRUE(feature_available_in_tier(Feature::STEP_IMPORT_EXPORT, LicenseTier::Community));
EXPECT_TRUE(feature_available_in_tier(Feature::IGES_IMPORT_EXPORT, LicenseTier::Community));
// Community 不应该有 Professional 功能
EXPECT_FALSE(feature_available_in_tier(Feature::CAM_5AXIS, LicenseTier::Community));
EXPECT_FALSE(feature_available_in_tier(Feature::GD_T, LicenseTier::Community));
}
TEST(TierFeatures, ProfessionalLevel) {
auto feats = features_for_tier(LicenseTier::Professional);
EXPECT_GE(feats.size(), 12u);
// 包含 Community 的全部
EXPECT_TRUE(feature_available_in_tier(Feature::BASIC_BREP, LicenseTier::Professional));
// 包含 Professional 特有
EXPECT_TRUE(feature_available_in_tier(Feature::CAM_5AXIS, LicenseTier::Professional));
EXPECT_TRUE(feature_available_in_tier(Feature::ADVANCED_SURFACING, LicenseTier::Professional));
EXPECT_TRUE(feature_available_in_tier(Feature::GD_T, LicenseTier::Professional));
EXPECT_TRUE(feature_available_in_tier(Feature::SHEET_METAL, LicenseTier::Professional));
// 不应包含 Enterprise 功能
EXPECT_FALSE(feature_available_in_tier(Feature::TECHNICAL_SUPPORT, LicenseTier::Professional));
EXPECT_FALSE(feature_available_in_tier(Feature::GPU_ACCELERATION, LicenseTier::Professional));
}
TEST(TierFeatures, EnterpriseLevel) {
auto feats = features_for_tier(LicenseTier::Enterprise);
EXPECT_GE(feats.size(), 18u);
// 全部功能
EXPECT_TRUE(feature_available_in_tier(Feature::BASIC_BREP, LicenseTier::Enterprise));
EXPECT_TRUE(feature_available_in_tier(Feature::CAM_5AXIS, LicenseTier::Enterprise));
EXPECT_TRUE(feature_available_in_tier(Feature::TECHNICAL_SUPPORT, LicenseTier::Enterprise));
EXPECT_TRUE(feature_available_in_tier(Feature::CUSTOM_FORMATS, LicenseTier::Enterprise));
EXPECT_TRUE(feature_available_in_tier(Feature::GPU_ACCELERATION, LicenseTier::Enterprise));
EXPECT_TRUE(feature_available_in_tier(Feature::LICENSE_MANAGER_SDK, LicenseTier::Enterprise));
}
// ═══════════════════════════════════════════════════════════════
// LicenseInfo 结构体测试
// ═══════════════════════════════════════════════════════════════
TEST(LicenseInfo, DefaultConstruction) {
LicenseInfo info;
EXPECT_EQ(info.tier, LicenseTier::Community);
EXPECT_EQ(info.licensee, "Trial User");
EXPECT_EQ(info.expiry, 0);
EXPECT_EQ(info.version, 1);
}
TEST(LicenseInfo, IsExpiredPermanent) {
LicenseInfo info;
info.expiry = 0; // 永久
EXPECT_FALSE(info.is_expired());
}
TEST(LicenseInfo, IsExpiredFuture) {
LicenseInfo info;
info.expiry = std::time(nullptr) + 86400 * 365; // 一年后
EXPECT_FALSE(info.is_expired());
}
TEST(LicenseInfo, IsExpiredPast) {
LicenseInfo info;
info.expiry = std::time(nullptr) - 86400; // 昨天
EXPECT_TRUE(info.is_expired());
}
TEST(LicenseInfo, DaysUntilExpiry) {
LicenseInfo info;
// 永久
info.expiry = 0;
EXPECT_EQ(info.days_until_expiry(), -1);
// 未来30天
info.expiry = std::time(nullptr) + 86400 * 30;
EXPECT_EQ(info.days_until_expiry(), 30);
// 未来1天
info.expiry = std::time(nullptr) + 86400;
EXPECT_EQ(info.days_until_expiry(), 1);
// 已过期
info.expiry = std::time(nullptr) - 86400;
EXPECT_EQ(info.days_until_expiry(), 0);
}
// ═══════════════════════════════════════════════════════════════
// LicenseKey 生成/解析/验证测试
// ═══════════════════════════════════════════════════════════════
TEST(LicenseKey, GenerateAndParse) {
// 生成一个 Community 永不过期的 Key
std::string key = LicenseKey::generate(LicenseTier::Community, 0, "TestUser");
EXPECT_FALSE(key.empty());
EXPECT_EQ(key.substr(0, 4), "VDE-");
// 解析
LicenseKey lk;
EXPECT_TRUE(lk.parse(key));
EXPECT_TRUE(lk.signature_valid());
EXPECT_EQ(lk.info().tier, LicenseTier::Community);
EXPECT_EQ(lk.info().expiry, 0);
}
TEST(LicenseKey, GenerateAndParseProfessional) {
std::time_t fut = std::time(nullptr) + 86400 * 365; // 一年后
std::string key = LicenseKey::generate(LicenseTier::Professional, fut, "ProUser");
LicenseKey lk;
EXPECT_TRUE(lk.parse(key));
EXPECT_TRUE(lk.signature_valid());
EXPECT_EQ(lk.info().tier, LicenseTier::Professional);
EXPECT_EQ(lk.info().expiry, fut);
}
TEST(LicenseKey, GenerateEnterprise) {
std::string key = LicenseKey::generate(LicenseTier::Enterprise, 0, "EntUser");
LicenseKey lk;
EXPECT_TRUE(lk.parse(key));
EXPECT_TRUE(lk.signature_valid());
EXPECT_EQ(lk.info().tier, LicenseTier::Enterprise);
}
TEST(LicenseKey, Validate) {
std::string key = LicenseKey::generate(LicenseTier::Community, 0, "User");
EXPECT_TRUE(LicenseKey::validate(key));
}
TEST(LicenseKey, ValidateExpired) {
// 生成一个已过期的 Key
std::string key = LicenseKey::generate(LicenseTier::Community,
std::time(nullptr) - 86400, "User");
EXPECT_FALSE(LicenseKey::validate(key));
}
TEST(LicenseKey, InvalidFormat) {
EXPECT_FALSE(LicenseKey::validate(""));
EXPECT_FALSE(LicenseKey::validate("INVALID-KEY"));
EXPECT_FALSE(LicenseKey::validate("VDE-!!!!"));
}
TEST(LicenseKey, TamperedKey) {
std::string key = LicenseKey::generate(LicenseTier::Community, 0, "User");
// 篡改 key(改一个字符)
if (key.size() > 6) {
key[6] = (key[6] == 'A') ? 'B' : 'A';
}
LicenseKey lk;
bool parsed = lk.parse(key);
if (parsed) {
// 签名验证应该失败
EXPECT_FALSE(lk.signature_valid());
}
// 无论如何,整体 validate 应该失败
EXPECT_FALSE(LicenseKey::validate(key));
}
TEST(LicenseKey, MultipleKeysAreDifferent) {
std::string k1 = LicenseKey::generate(LicenseTier::Community, 0, "U1");
std::string k2 = LicenseKey::generate(LicenseTier::Professional, 0, "U2");
EXPECT_NE(k1, k2);
}
TEST(LicenseKey, KeyStringStored) {
std::string key = LicenseKey::generate(LicenseTier::Community, 0, "U");
LicenseKey lk;
lk.parse(key);
EXPECT_EQ(lk.key_string(), key);
}
// ═══════════════════════════════════════════════════════════════
// LicenseManager 单例测试
// ═══════════════════════════════════════════════════════════════
TEST(LicenseManager, Singleton) {
LicenseManager& mgr1 = LicenseManager::instance();
LicenseManager& mgr2 = LicenseManager::instance();
EXPECT_EQ(&mgr1, &mgr2);
}
TEST(LicenseManager, DefaultCommunity) {
auto& mgr = LicenseManager::instance();
EXPECT_EQ(mgr.current_tier(), LicenseTier::Community);
EXPECT_FALSE(mgr.is_expired());
EXPECT_FALSE(mgr.is_trial());
}
TEST(LicenseManager, HasFeatureBasic) {
auto& mgr = LicenseManager::instance();
// Community 默认应该有基础功能
EXPECT_TRUE(mgr.has_feature("BASIC_BREP"));
EXPECT_TRUE(mgr.has_feature("STEP_IMPORT_EXPORT"));
EXPECT_TRUE(mgr.has_feature(Feature::MESH_OPERATIONS));
}
TEST(LicenseManager, HasFeatureProfessional) {
auto& mgr = LicenseManager::instance();
// Community 不应该有 Professional 功能
EXPECT_FALSE(mgr.has_feature("CAM_5AXIS"));
EXPECT_FALSE(mgr.has_feature("GD_T"));
EXPECT_FALSE(mgr.has_feature("ADVANCED_SURFACING"));
}
TEST(LicenseManager, SetLicenseCommunity) {
auto& mgr = LicenseManager::instance();
// 保存原始 license
auto orig = mgr.current_license();
std::string key = LicenseKey::generate(LicenseTier::Community, 0, "Test");
EXPECT_TRUE(mgr.set_license(key));
EXPECT_EQ(mgr.current_tier(), LicenseTier::Community);
EXPECT_FALSE(mgr.is_trial());
// 恢复原始
mgr.set_license(LicenseKey::generate(LicenseTier::Community, 0, "Community User"));
}
TEST(LicenseManager, SetLicenseProfessional) {
auto& mgr = LicenseManager::instance();
std::time_t fut = std::time(nullptr) + 86400 * 365;
std::string key = LicenseKey::generate(LicenseTier::Professional, fut, "Pro");
EXPECT_TRUE(mgr.set_license(key));
EXPECT_EQ(mgr.current_tier(), LicenseTier::Professional);
EXPECT_TRUE(mgr.has_feature("CAM_5AXIS"));
EXPECT_TRUE(mgr.has_feature("GD_T"));
// 恢复默认
mgr.set_license(LicenseKey::generate(LicenseTier::Community, 0, "Community User"));
}
TEST(LicenseManager, SetLicenseEnterprise) {
auto& mgr = LicenseManager::instance();
std::string key = LicenseKey::generate(LicenseTier::Enterprise, 0, "Ent");
EXPECT_TRUE(mgr.set_license(key));
EXPECT_EQ(mgr.current_tier(), LicenseTier::Enterprise);
EXPECT_TRUE(mgr.has_feature("TECHNICAL_SUPPORT"));
EXPECT_TRUE(mgr.has_feature("GPU_ACCELERATION"));
EXPECT_TRUE(mgr.has_feature("CUSTOM_FORMATS"));
// 恢复
mgr.set_license(LicenseKey::generate(LicenseTier::Community, 0, "Community User"));
}
TEST(LicenseManager, SetLicenseExpired) {
auto& mgr = LicenseManager::instance();
// 先生成一个有效 key 确保非过期状态
mgr.set_license(LicenseKey::generate(LicenseTier::Community, 0, "Reset"));
// 生成已过期的 key
std::string key = LicenseKey::generate(LicenseTier::Professional,
std::time(nullptr) - 86400, "Expired");
// 已过期 key 应该被拒绝
EXPECT_FALSE(mgr.set_license(key));
}
TEST(LicenseManager, SetLicenseInvalid) {
auto& mgr = LicenseManager::instance();
EXPECT_FALSE(mgr.set_license("INVALID-KEY"));
EXPECT_FALSE(mgr.set_license(""));
}
TEST(LicenseManager, TrialMode) {
auto& mgr = LicenseManager::instance();
// 先设置永久 Community key
mgr.set_license(LicenseKey::generate(LicenseTier::Community, 0, "Reset"));
mgr.start_trial(30);
EXPECT_TRUE(mgr.is_trial());
EXPECT_EQ(mgr.current_tier(), LicenseTier::Professional);
EXPECT_EQ(mgr.trial_days_left(), 30);
EXPECT_TRUE(mgr.has_feature("CAM_5AXIS"));
// 但也应该有基础功能
EXPECT_TRUE(mgr.has_feature("BASIC_BREP"));
// 恢复
mgr.set_license(LicenseKey::generate(LicenseTier::Community, 0, "Community User"));
EXPECT_FALSE(mgr.is_trial());
}
TEST(LicenseManager, TrialDaysLeftVarious) {
auto& mgr = LicenseManager::instance();
mgr.set_license(LicenseKey::generate(LicenseTier::Community, 0, "Reset"));
// 没有试用时
EXPECT_EQ(mgr.trial_days_left(), -1);
// 30天试用
mgr.start_trial(30);
EXPECT_GE(mgr.trial_days_left(), 29); // 可能刚好跨天
EXPECT_LE(mgr.trial_days_left(), 30);
// 恢复
mgr.set_license(LicenseKey::generate(LicenseTier::Community, 0, "Reset"));
}
TEST(LicenseManager, CurrentLicense) {
auto& mgr = LicenseManager::instance();
std::string key = LicenseKey::generate(LicenseTier::Professional,
std::time(nullptr) + 86400 * 90, "TestCo");
mgr.set_license(key);
const auto& info = mgr.current_license();
EXPECT_EQ(info.tier, LicenseTier::Professional);
EXPECT_EQ(info.licensee, "Licensee"); // payload 中无 licensee 字段
// 恢复
mgr.set_license(LicenseKey::generate(LicenseTier::Community, 0, "Community User"));
}
TEST(LicenseManager, HasFeatureInvalidName) {
auto& mgr = LicenseManager::instance();
EXPECT_FALSE(mgr.has_feature("NONEXISTENT_FEATURE"));
EXPECT_FALSE(mgr.has_feature(""));
}
TEST(LicenseManager, ExpiredLicenseBlocksFeatures) {
auto& mgr = LicenseManager::instance();
// 恢复有效状态
mgr.set_license(LicenseKey::generate(LicenseTier::Professional,
std::time(nullptr) + 86400 * 365, "Reset"));
EXPECT_TRUE(mgr.has_feature("CAM_5AXIS"));
// 设置已过期的 license
mgr.set_license(LicenseKey::generate(LicenseTier::Professional,
std::time(nullptr) - 86400, "Expired"));
// 过期 license 不会被设置(set_license 返回 false),所以状态不变
// 但如果 is_expired() 返回 truehas_feature 也会 false
// 恢复
mgr.set_license(LicenseKey::generate(LicenseTier::Community, 0, "Community User"));
}