package license import ( "crypto/ed25519" "crypto/rand" "testing" "time" ) func mkLicense(plan Plan, expires time.Time, feats ...string) *License { return &License{ ID: "test-id", Tenant: "ООО Тест", Product: "bj-server", Plan: plan, IssuedAt: time.Now().UTC().Add(-time.Hour), ExpiresAt: expires, Features: feats, } } func TestSignVerifyAndEncode(t *testing.T) { pub, priv, _ := ed25519.GenerateKey(rand.Reader) l := mkLicense(PlanPro, time.Now().Add(365*24*time.Hour), "updates") tok, err := Sign(l, priv, "main") if err != nil { t.Fatal(err) } // round-trip через компактную строку dec, err := DecodeToken(tok.Encode()) if err != nil { t.Fatal(err) } got, err := Verify(dec, pub) if err != nil { t.Fatalf("Verify: %v", err) } if got.Tenant != l.Tenant || got.Plan != PlanPro || !got.AllowsUpdates() { t.Fatalf("mismatch: %+v", got) } } func TestExpired(t *testing.T) { l := mkLicense(PlanPro, time.Now().Add(-time.Hour), "updates") if err := l.Valid(time.Now().UTC()); err == nil { t.Fatal("истёкшая лицензия прошла Valid") } } func TestFeaturesAndEnterprise(t *testing.T) { pro := mkLicense(PlanPro, time.Now().Add(time.Hour), "updates") if !pro.HasFeature("updates") || pro.HasFeature("web-cabinet") { t.Fatal("pro features неверны") } ent := mkLicense(PlanEnterprise, time.Now().Add(time.Hour)) if !ent.HasFeature("anything") || !ent.AllowsUpdates() { t.Fatal("enterprise должен включать всё") } } func TestVerifyRejectsWrongKey(t *testing.T) { _, priv, _ := ed25519.GenerateKey(rand.Reader) other, _, _ := ed25519.GenerateKey(rand.Reader) l := mkLicense(PlanPro, time.Now().Add(time.Hour)) tok, _ := Sign(l, priv, "main") if _, err := Verify(tok, other); err == nil { t.Fatal("Verify принял подпись чужим ключом") } }