Move license test signers to testsupport

This commit is contained in:
rcourtman 2026-04-28 19:12:21 +01:00
parent 146cb5e69e
commit c197f6a7a5
11 changed files with 121 additions and 37 deletions

View file

@ -2117,6 +2117,22 @@
"pkg/licensing/service_activate_test.go"
]
},
{
"id": "license-test-support",
"label": "license test-support helper proof",
"match_prefixes": [
"pkg/licensing/testsupport/"
],
"match_files": [],
"allow_same_subsystem_tests": false,
"test_prefixes": [],
"exact_files": [
"internal/api/contract_test.go",
"internal/api/license_handlers_test.go",
"internal/api/licensing_handlers_auto_migrate_test.go",
"internal/license/testing_helpers_test.go"
]
},
{
"id": "license-server-transport",
"label": "license server transport proof",

View file

@ -45,6 +45,7 @@ import (
"github.com/rcourtman/pulse-go-rewrite/pkg/cloudauth"
"github.com/rcourtman/pulse-go-rewrite/pkg/extensions"
pkglicensing "github.com/rcourtman/pulse-go-rewrite/pkg/licensing"
licensetestsupport "github.com/rcourtman/pulse-go-rewrite/pkg/licensing/testsupport"
"github.com/rcourtman/pulse-go-rewrite/pkg/metrics"
"github.com/rcourtman/pulse-go-rewrite/pkg/reporting"
"github.com/rs/zerolog"
@ -5517,7 +5518,7 @@ func TestContract_LegacyMigrationGrandfatherFloorFallbackJSONSnapshot(t *testing
t.Setenv("PULSE_LICENSE_DEV_MODE", "false")
const expectedClientVersion = "6.0.0-rc.1"
grantJWT, grantPublicKey, err := pkglicensing.GenerateGrantJWTForTesting(pkglicensing.GrantClaims{
grantJWT, grantPublicKey, err := licensetestsupport.GenerateGrantJWTForTesting(pkglicensing.GrantClaims{
LicenseID: "lic_contract_floor",
Tier: "pro",
PlanKey: "legacy_migration_fallback",
@ -5579,7 +5580,7 @@ func TestContract_LegacyMigrationGrandfatherFloorFallbackJSONSnapshot(t *testing
if err != nil {
t.Fatalf("new persistence: %v", err)
}
legacyJWT, err := pkglicensing.GenerateLicenseForTesting("contract-floor@example.com", pkglicensing.TierPro, 24*time.Hour)
legacyJWT, err := licensetestsupport.GenerateLicenseForTesting("contract-floor@example.com", pkglicensing.TierPro, 24*time.Hour)
if err != nil {
t.Fatalf("generate test license: %v", err)
}
@ -6437,7 +6438,7 @@ func TestContract_DemoModeCommercialSurfacePolicy(t *testing.T) {
handlers := createTestHandler(t)
handlers.SetConfig(&config.Config{DemoMode: true})
licenseKey, err := pkglicensing.GenerateLicenseForTesting("contract-demo@example.com", pkglicensing.TierPro, 24*time.Hour)
licenseKey, err := licensetestsupport.GenerateLicenseForTesting("contract-demo@example.com", pkglicensing.TierPro, 24*time.Hour)
if err != nil {
t.Fatalf("GenerateLicenseForTesting: %v", err)
}

View file

@ -14,6 +14,7 @@ import (
"github.com/rcourtman/pulse-go-rewrite/internal/license"
"github.com/rcourtman/pulse-go-rewrite/internal/license/entitlements"
pkglicensing "github.com/rcourtman/pulse-go-rewrite/pkg/licensing"
licensetestsupport "github.com/rcourtman/pulse-go-rewrite/pkg/licensing/testsupport"
)
func containsCapability(values []string, key string) bool {
@ -230,7 +231,7 @@ func TestBuildCommercialPosturePayloadWithUsage_CurrentValues(t *testing.T) {
func TestHandleCommercialPosture_ActiveLicense(t *testing.T) {
t.Setenv("PULSE_LICENSE_DEV_MODE", "true")
handler := createTestHandler(t)
licenseKey, err := pkglicensing.GenerateLicenseForTesting(
licenseKey, err := licensetestsupport.GenerateLicenseForTesting(
"owner@example.com",
pkglicensing.TierPro,
24*time.Hour,

View file

@ -11,6 +11,7 @@ import (
"github.com/rcourtman/pulse-go-rewrite/internal/config"
"github.com/rcourtman/pulse-go-rewrite/internal/license"
pkglicensing "github.com/rcourtman/pulse-go-rewrite/pkg/licensing"
licensetestsupport "github.com/rcourtman/pulse-go-rewrite/pkg/licensing/testsupport"
)
// createTestHandlerWithDir creates a LicenseHandlers and returns the base data
@ -36,7 +37,7 @@ func TestExpiredLicenseBlocksProFeature(t *testing.T) {
handler := createTestHandler(t)
// Activate a Pro license with a 24h expiry.
licenseKey, err := pkglicensing.GenerateLicenseForTesting("expiry@example.com", license.TierPro, 24*time.Hour)
licenseKey, err := licensetestsupport.GenerateLicenseForTesting("expiry@example.com", license.TierPro, 24*time.Hour)
if err != nil {
t.Fatalf("generate test license: %v", err)
}
@ -93,7 +94,7 @@ func TestGracePeriodAllowsProFeature(t *testing.T) {
handler := createTestHandler(t)
licenseKey, err := pkglicensing.GenerateLicenseForTesting("grace@example.com", license.TierPro, 24*time.Hour)
licenseKey, err := licensetestsupport.GenerateLicenseForTesting("grace@example.com", license.TierPro, 24*time.Hour)
if err != nil {
t.Fatalf("generate test license: %v", err)
}
@ -134,7 +135,7 @@ func TestExpiredLicenseFeaturesEndpoint(t *testing.T) {
handler := createTestHandler(t)
licenseKey, err := pkglicensing.GenerateLicenseForTesting("features@example.com", license.TierPro, 24*time.Hour)
licenseKey, err := licensetestsupport.GenerateLicenseForTesting("features@example.com", license.TierPro, 24*time.Hour)
if err != nil {
t.Fatalf("generate test license: %v", err)
}
@ -278,7 +279,7 @@ func TestLicenseGatedEmptyResponseOnExpiry(t *testing.T) {
handler := createTestHandler(t)
licenseKey, err := pkglicensing.GenerateLicenseForTesting("gated@example.com", license.TierPro, 24*time.Hour)
licenseKey, err := licensetestsupport.GenerateLicenseForTesting("gated@example.com", license.TierPro, 24*time.Hour)
if err != nil {
t.Fatalf("generate test license: %v", err)
}

View file

@ -16,6 +16,7 @@ import (
"github.com/rcourtman/pulse-go-rewrite/internal/license"
"github.com/rcourtman/pulse-go-rewrite/internal/license/entitlements"
pkglicensing "github.com/rcourtman/pulse-go-rewrite/pkg/licensing"
licensetestsupport "github.com/rcourtman/pulse-go-rewrite/pkg/licensing/testsupport"
)
func createTestHandler(t *testing.T) *LicenseHandlers {
@ -64,7 +65,7 @@ func purchaseReturnJTIFromToken(t *testing.T, handler *LicenseHandlers, token st
func issueCheckoutActivationGrant(t *testing.T) string {
t.Helper()
grantJWT, grantPublicKey, err := pkglicensing.GenerateGrantJWTForTesting(pkglicensing.GrantClaims{
grantJWT, grantPublicKey, err := licensetestsupport.GenerateGrantJWTForTesting(pkglicensing.GrantClaims{
LicenseID: "lic_checkout_success",
Tier: "pro_plus",
State: "active",
@ -156,7 +157,7 @@ func TestHandleLicenseFeatures_WithActiveLicense(t *testing.T) {
t.Setenv("PULSE_LICENSE_DEV_MODE", "true")
handler := createTestHandler(t)
licenseKey, err := pkglicensing.GenerateLicenseForTesting("test@example.com", license.TierPro, 24*time.Hour)
licenseKey, err := licensetestsupport.GenerateLicenseForTesting("test@example.com", license.TierPro, 24*time.Hour)
if err != nil {
t.Fatalf("failed to generate test license: %v", err)
}
@ -245,7 +246,7 @@ func TestHandleLicenseStatus_WithActiveLicense(t *testing.T) {
t.Setenv("PULSE_LICENSE_DEV_MODE", "true")
handler := createTestHandler(t)
licenseKey, err := pkglicensing.GenerateLicenseForTesting("test@example.com", license.TierPro, 24*time.Hour)
licenseKey, err := licensetestsupport.GenerateLicenseForTesting("test@example.com", license.TierPro, 24*time.Hour)
if err != nil {
t.Fatalf("failed to generate test license: %v", err)
}
@ -403,7 +404,7 @@ func TestHandleActivateLicense_ExchangesLegacyJWTInStrictV6(t *testing.T) {
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
grantJWT, grantPublicKey, err := pkglicensing.GenerateGrantJWTForTesting(pkglicensing.GrantClaims{
grantJWT, grantPublicKey, err := licensetestsupport.GenerateGrantJWTForTesting(pkglicensing.GrantClaims{
LicenseID: "lic_exchanged",
Tier: "pro",
PlanKey: tc.planKey,
@ -450,7 +451,7 @@ func TestHandleActivateLicense_ExchangesLegacyJWTInStrictV6(t *testing.T) {
t.Setenv("PULSE_LICENSE_SERVER_URL", server.URL)
handler := createTestHandler(t)
licenseKey, err := pkglicensing.GenerateLicenseForTesting("legacy-jwt@example.com", license.TierPro, 24*time.Hour)
licenseKey, err := licensetestsupport.GenerateLicenseForTesting("legacy-jwt@example.com", license.TierPro, 24*time.Hour)
if err != nil {
t.Fatalf("failed to generate test license: %v", err)
}
@ -502,7 +503,7 @@ func TestHandleActivateLicense_ExchangesLegacyJWTInStrictV6(t *testing.T) {
func TestHandleActivateLicense_ClearsCommercialMigrationStateOnNativeActivation(t *testing.T) {
t.Setenv("PULSE_LICENSE_DEV_MODE", "false")
grantJWT, grantPublicKey, err := pkglicensing.GenerateGrantJWTForTesting(pkglicensing.GrantClaims{
grantJWT, grantPublicKey, err := licensetestsupport.GenerateGrantJWTForTesting(pkglicensing.GrantClaims{
LicenseID: "lic_v6_native",
Tier: "pro",
State: "active",
@ -588,7 +589,7 @@ func TestHandleActivateLicense_ClearsCommercialMigrationStateOnNativeActivation(
func TestHandleActivateLicense_ActivationKeyClearsStaleLegacyPersistence(t *testing.T) {
t.Setenv("PULSE_LICENSE_DEV_MODE", "false")
grantJWT, grantPublicKey, err := pkglicensing.GenerateGrantJWTForTesting(pkglicensing.GrantClaims{
grantJWT, grantPublicKey, err := licensetestsupport.GenerateGrantJWTForTesting(pkglicensing.GrantClaims{
LicenseID: "lic_v6_native",
Tier: "pro",
State: "active",
@ -644,7 +645,7 @@ func TestHandleActivateLicense_ActivationKeyClearsStaleLegacyPersistence(t *test
t.Fatalf("new license persistence: %v", err)
}
legacyKey, err := pkglicensing.GenerateLicenseForTesting("legacy-stale@example.com", license.TierPro, 24*time.Hour)
legacyKey, err := licensetestsupport.GenerateLicenseForTesting("legacy-stale@example.com", license.TierPro, 24*time.Hour)
if err != nil {
t.Fatalf("generate stale legacy license: %v", err)
}
@ -697,7 +698,7 @@ func TestHandleActivateLicense_ValidKey(t *testing.T) {
t.Setenv("PULSE_LICENSE_DEV_MODE", "true")
handler := createTestHandler(t)
licenseKey, err := pkglicensing.GenerateLicenseForTesting("pro@example.com", license.TierPro, 24*time.Hour)
licenseKey, err := licensetestsupport.GenerateLicenseForTesting("pro@example.com", license.TierPro, 24*time.Hour)
if err != nil {
t.Fatalf("failed to generate test license: %v", err)
}
@ -1456,7 +1457,7 @@ func TestHandleClearLicense_WithActiveLicense(t *testing.T) {
t.Setenv("PULSE_LICENSE_DEV_MODE", "true")
handler := createTestHandler(t)
licenseKey, err := pkglicensing.GenerateLicenseForTesting("test@example.com", license.TierPro, 24*time.Hour)
licenseKey, err := licensetestsupport.GenerateLicenseForTesting("test@example.com", license.TierPro, 24*time.Hour)
if err != nil {
t.Fatalf("failed to generate test license: %v", err)
}
@ -1592,7 +1593,7 @@ func TestRequireLicenseFeature_WithLicense(t *testing.T) {
t.Setenv("PULSE_LICENSE_DEV_MODE", "true")
handler := createTestHandler(t)
licenseKey, err := pkglicensing.GenerateLicenseForTesting("test@example.com", license.TierPro, 24*time.Hour)
licenseKey, err := licensetestsupport.GenerateLicenseForTesting("test@example.com", license.TierPro, 24*time.Hour)
if err != nil {
t.Fatalf("failed to generate test license: %v", err)
}
@ -1741,7 +1742,7 @@ func TestLicenseGatedEmptyResponse_WithLicense(t *testing.T) {
t.Setenv("PULSE_LICENSE_DEV_MODE", "true")
handler := createTestHandler(t)
licenseKey, err := pkglicensing.GenerateLicenseForTesting("test@example.com", license.TierPro, 24*time.Hour)
licenseKey, err := licensetestsupport.GenerateLicenseForTesting("test@example.com", license.TierPro, 24*time.Hour)
if err != nil {
t.Fatalf("failed to generate test license: %v", err)
}

View file

@ -7,6 +7,7 @@ import (
"time"
pkglicensing "github.com/rcourtman/pulse-go-rewrite/pkg/licensing"
licensetestsupport "github.com/rcourtman/pulse-go-rewrite/pkg/licensing/testsupport"
)
type staticLicenseProvider struct {
@ -27,7 +28,7 @@ func setMaxMonitoredSystemsLicenseForTests(t *testing.T, maxMonitoredSystems int
t.Setenv("PULSE_LICENSE_DEV_MODE", "true")
service := pkglicensing.NewService()
licenseKey, err := pkglicensing.GenerateLicenseForTesting("limits@example.com", pkglicensing.TierEnterprise, 24*time.Hour)
licenseKey, err := licensetestsupport.GenerateLicenseForTesting("limits@example.com", pkglicensing.TierEnterprise, 24*time.Hour)
if err != nil {
t.Fatalf("failed to generate test license: %v", err)
}

View file

@ -12,6 +12,7 @@ import (
"github.com/rcourtman/pulse-go-rewrite/internal/models"
pkglicensing "github.com/rcourtman/pulse-go-rewrite/pkg/licensing"
licensetestsupport "github.com/rcourtman/pulse-go-rewrite/pkg/licensing/testsupport"
)
func setMaxUsersLimitForTests(t *testing.T, limits map[string]int64) {
@ -20,7 +21,7 @@ func setMaxUsersLimitForTests(t *testing.T, limits map[string]int64) {
t.Setenv("PULSE_LICENSE_DEV_MODE", "true")
service := pkglicensing.NewService()
licenseKey, err := pkglicensing.GenerateLicenseForTesting("users-limit@example.com", pkglicensing.TierPro, 24*time.Hour)
licenseKey, err := licensetestsupport.GenerateLicenseForTesting("users-limit@example.com", pkglicensing.TierPro, 24*time.Hour)
if err != nil {
t.Fatalf("failed to generate test license: %v", err)
}

View file

@ -14,6 +14,7 @@ import (
"github.com/rcourtman/pulse-go-rewrite/internal/monitoring"
"github.com/rcourtman/pulse-go-rewrite/internal/unifiedresources"
pkglicensing "github.com/rcourtman/pulse-go-rewrite/pkg/licensing"
licensetestsupport "github.com/rcourtman/pulse-go-rewrite/pkg/licensing/testsupport"
)
type grandfatherFloorSupplementalProvider struct {
@ -46,7 +47,7 @@ func (p *grandfatherFloorSupplementalProvider) settle(count int) {
func TestGetTenantComponents_AutoExchangesPersistedLegacyJWT(t *testing.T) {
t.Setenv("PULSE_LICENSE_DEV_MODE", "false")
grantJWT, grantPublicKey, err := pkglicensing.GenerateGrantJWTForTesting(pkglicensing.GrantClaims{
grantJWT, grantPublicKey, err := licensetestsupport.GenerateGrantJWTForTesting(pkglicensing.GrantClaims{
LicenseID: "lic_migrated",
Tier: "pro",
State: "active",
@ -108,7 +109,7 @@ func TestGetTenantComponents_AutoExchangesPersistedLegacyJWT(t *testing.T) {
}
// Create and persist a legacy test JWT.
legacyJWT, err := pkglicensing.GenerateLicenseForTesting("user@example.com", pkglicensing.TierPro, 365*24*time.Hour)
legacyJWT, err := licensetestsupport.GenerateLicenseForTesting("user@example.com", pkglicensing.TierPro, 365*24*time.Hour)
if err != nil {
t.Fatalf("generate test license: %v", err)
}
@ -182,7 +183,7 @@ func TestGetTenantComponents_SkipsExchange_WhenActivationStateExists(t *testing.
}
// Save a legacy JWT (shouldn't be used since activation state exists).
legacyJWT, err := pkglicensing.GenerateLicenseForTesting("user@example.com", pkglicensing.TierPro, 365*24*time.Hour)
legacyJWT, err := licensetestsupport.GenerateLicenseForTesting("user@example.com", pkglicensing.TierPro, 365*24*time.Hour)
if err != nil {
t.Fatalf("generate test license: %v", err)
}
@ -263,7 +264,7 @@ func TestGetTenantComponents_PersistsCommercialMigrationState_WhenAutoExchangeFa
t.Fatalf("init default persistence: %v", err)
}
legacyJWT, err := pkglicensing.GenerateLicenseForTesting("user@example.com", pkglicensing.TierPro, 365*24*time.Hour)
legacyJWT, err := licensetestsupport.GenerateLicenseForTesting("user@example.com", pkglicensing.TierPro, 365*24*time.Hour)
if err != nil {
t.Fatalf("generate test license: %v", err)
}
@ -325,7 +326,7 @@ func TestGetTenantComponents_PersistsCommercialMigrationState_WhenAutoExchangeFa
func TestGetTenantComponents_AutoExchangeGrandfathersObservedMonitoredSystems(t *testing.T) {
t.Setenv("PULSE_LICENSE_DEV_MODE", "false")
grantJWT, grantPublicKey, err := pkglicensing.GenerateGrantJWTForTesting(pkglicensing.GrantClaims{
grantJWT, grantPublicKey, err := licensetestsupport.GenerateGrantJWTForTesting(pkglicensing.GrantClaims{
LicenseID: "lic_floor_auto",
Tier: "pro",
PlanKey: "legacy_migration_fallback",
@ -377,7 +378,7 @@ func TestGetTenantComponents_AutoExchangeGrandfathersObservedMonitoredSystems(t
t.Fatalf("init default persistence: %v", err)
}
legacyJWT, err := pkglicensing.GenerateLicenseForTesting("floor-auto@example.com", pkglicensing.TierPro, 24*time.Hour)
legacyJWT, err := licensetestsupport.GenerateLicenseForTesting("floor-auto@example.com", pkglicensing.TierPro, 24*time.Hour)
if err != nil {
t.Fatalf("generate test license: %v", err)
}
@ -424,7 +425,7 @@ func TestGetTenantComponents_AutoExchangeGrandfathersObservedMonitoredSystems(t
func TestGetTenantComponents_BackfillsGrandfatherFloorAfterRestoreWhenMonitorArrivesLate(t *testing.T) {
t.Setenv("PULSE_LICENSE_DEV_MODE", "false")
grantJWT, grantPublicKey, err := pkglicensing.GenerateGrantJWTForTesting(pkglicensing.GrantClaims{
grantJWT, grantPublicKey, err := licensetestsupport.GenerateGrantJWTForTesting(pkglicensing.GrantClaims{
LicenseID: "lic_floor_restore",
Tier: "pro",
PlanKey: "legacy_migration_fallback",
@ -521,7 +522,7 @@ func TestGetTenantComponents_BackfillsGrandfatherFloorAfterRestoreWhenMonitorArr
func TestBillingReads_DoNotRestartLegacyGrandfatherReconcileLoop(t *testing.T) {
t.Setenv("PULSE_LICENSE_DEV_MODE", "false")
grantJWT, grantPublicKey, err := pkglicensing.GenerateGrantJWTForTesting(pkglicensing.GrantClaims{
grantJWT, grantPublicKey, err := licensetestsupport.GenerateGrantJWTForTesting(pkglicensing.GrantClaims{
LicenseID: "lic_floor_read_only",
Tier: "pro",
PlanKey: "legacy_migration_fallback",
@ -619,7 +620,7 @@ func TestBillingReads_DoNotRestartLegacyGrandfatherReconcileLoop(t *testing.T) {
func TestActivateLicenseKey_GrandfathersObservedMonitoredSystemsForLegacyMigration(t *testing.T) {
t.Setenv("PULSE_LICENSE_DEV_MODE", "false")
grantJWT, grantPublicKey, err := pkglicensing.GenerateGrantJWTForTesting(pkglicensing.GrantClaims{
grantJWT, grantPublicKey, err := licensetestsupport.GenerateGrantJWTForTesting(pkglicensing.GrantClaims{
LicenseID: "lic_floor_manual",
Tier: "pro",
PlanKey: "legacy_migration_fallback",
@ -669,7 +670,7 @@ func TestActivateLicenseKey_GrandfathersObservedMonitoredSystemsForLegacyMigrati
t.Cleanup(handlers.StopAllBackgroundLoops)
ctx := context.WithValue(context.Background(), OrgIDContextKey, "default")
legacyJWT, err := pkglicensing.GenerateLicenseForTesting("floor-manual@example.com", pkglicensing.TierPro, 24*time.Hour)
legacyJWT, err := licensetestsupport.GenerateLicenseForTesting("floor-manual@example.com", pkglicensing.TierPro, 24*time.Hour)
if err != nil {
t.Fatalf("generate test license: %v", err)
}
@ -694,7 +695,7 @@ func TestActivateLicenseKey_GrandfathersObservedMonitoredSystemsForLegacyMigrati
func TestGetTenantComponents_DelaysGrandfatherFloorUntilSupplementalInventorySettles(t *testing.T) {
t.Setenv("PULSE_LICENSE_DEV_MODE", "false")
grantJWT, grantPublicKey, err := pkglicensing.GenerateGrantJWTForTesting(pkglicensing.GrantClaims{
grantJWT, grantPublicKey, err := licensetestsupport.GenerateGrantJWTForTesting(pkglicensing.GrantClaims{
LicenseID: "lic_floor_supplemental",
Tier: "pro",
PlanKey: "legacy_migration_fallback",
@ -746,7 +747,7 @@ func TestGetTenantComponents_DelaysGrandfatherFloorUntilSupplementalInventorySet
t.Fatalf("init default persistence: %v", err)
}
legacyJWT, err := pkglicensing.GenerateLicenseForTesting("floor-supplemental@example.com", pkglicensing.TierPro, 24*time.Hour)
legacyJWT, err := licensetestsupport.GenerateLicenseForTesting("floor-supplemental@example.com", pkglicensing.TierPro, 24*time.Hour)
if err != nil {
t.Fatalf("generate test license: %v", err)
}

View file

@ -15,6 +15,7 @@ import (
"github.com/rcourtman/pulse-go-rewrite/internal/license/entitlements"
pkglicensing "github.com/rcourtman/pulse-go-rewrite/pkg/licensing"
licensetestsupport "github.com/rcourtman/pulse-go-rewrite/pkg/licensing/testsupport"
)
// init sets dev mode for tests so license validation works without a real public key
@ -610,7 +611,7 @@ func TestServiceActivateReturnsSnapshot(t *testing.T) {
if err != nil {
t.Fatalf("failed to generate test license: %v", err)
}
grantJWT, pub, err := pkglicensing.GenerateGrantJWTForTesting(pkglicensing.GrantClaims{
grantJWT, pub, err := licensetestsupport.GenerateGrantJWTForTesting(pkglicensing.GrantClaims{
LicenseID: "snapshot_test",
Email: "snapshot@example.com",
Tier: string(TierPro),

View file

@ -3,9 +3,9 @@ package license
import (
"time"
pkglicensing "github.com/rcourtman/pulse-go-rewrite/pkg/licensing"
licensetestsupport "github.com/rcourtman/pulse-go-rewrite/pkg/licensing/testsupport"
)
func GenerateLicenseForTesting(email string, tier Tier, expiresIn time.Duration) (string, error) {
return pkglicensing.GenerateLicenseForTesting(email, tier, expiresIn)
return licensetestsupport.GenerateLicenseForTesting(email, tier, expiresIn)
}

View file

@ -0,0 +1,60 @@
// Package testsupport contains license fixtures for cross-package tests.
//
// Production code must not import this package. It intentionally lives outside
// pkg/licensing so release-tag tests can build without exposing test signers on
// the production licensing package API.
package testsupport
import (
"crypto/ed25519"
"crypto/rand"
"encoding/base64"
"encoding/json"
"fmt"
"time"
"github.com/rcourtman/pulse-go-rewrite/pkg/licensing"
)
// GenerateLicenseForTesting creates a legacy JWT-shaped test license.
func GenerateLicenseForTesting(email string, tier licensing.Tier, expiresIn time.Duration) (string, error) {
claims := licensing.Claims{
LicenseID: fmt.Sprintf("test_%d", time.Now().UnixNano()),
Email: email,
Tier: tier,
IssuedAt: time.Now().Unix(),
}
if expiresIn > 0 {
claims.ExpiresAt = time.Now().Add(expiresIn).Unix()
}
header := base64.RawURLEncoding.EncodeToString([]byte(`{"alg":"EdDSA","typ":"JWT"}`))
payloadBytes, err := json.Marshal(claims)
if err != nil {
return "", fmt.Errorf("marshal test license claims: %w", err)
}
payload := base64.RawURLEncoding.EncodeToString(payloadBytes)
signature := base64.RawURLEncoding.EncodeToString([]byte("test-signature-not-valid"))
return header + "." + payload + "." + signature, nil
}
// GenerateGrantJWTForTesting creates a signed grant JWT and returns the
// matching public key so tests can install it before verification.
func GenerateGrantJWTForTesting(claims licensing.GrantClaims) (string, ed25519.PublicKey, error) {
publicKey, privateKey, err := ed25519.GenerateKey(rand.Reader)
if err != nil {
return "", nil, fmt.Errorf("generate grant test key pair: %w", err)
}
header := base64.RawURLEncoding.EncodeToString([]byte(`{"alg":"EdDSA"}`))
payloadBytes, err := json.Marshal(claims)
if err != nil {
return "", nil, fmt.Errorf("marshal grant test claims: %w", err)
}
payload := base64.RawURLEncoding.EncodeToString(payloadBytes)
signedData := []byte(header + "." + payload)
signature := ed25519.Sign(privateKey, signedData)
return header + "." + payload + "." + base64.RawURLEncoding.EncodeToString(signature), publicKey, nil
}