Initial commit of Descrybe v2 without local scratch artifacts.

Drop one-shot tmp/axe scripts and agent i18n scratch so the Gitea tree is deployable.
This commit is contained in:
2026-08-09 22:47:43 +02:00
commit 8580c996c3
1285 changed files with 325780 additions and 0 deletions
@@ -0,0 +1,188 @@
package billing
import "testing"
func TestIsCustomPackage(t *testing.T) {
cases := []struct {
name string
isCustom bool
want bool
}{
{"Free", false, false},
{"Starter", false, false},
{"Growth", false, false},
{"Business", false, false},
{"Enterprise", true, true},
{"Enterprise", false, false}, // public ladder without is_custom flag
{"A1", false, false}, // legacy name without is_custom → limited matrix
{"A1", true, true}, // dump-faithful A1 PAYG is_custom → custom profile (Stores/AI still gated)
{"Legacy", true, false}, // exact Legacy package never enable-all
{"Merkur trial", false, true},
{" growth ", false, false},
{"", false, true}, // empty name is not a public plan name
}
for _, tc := range cases {
got := IsCustomPackage(tc.name, tc.isCustom)
if got != tc.want {
t.Fatalf("IsCustomPackage(%q, %v)=%v want %v", tc.name, tc.isCustom, got, tc.want)
}
}
}
func TestAllRegistryFeatures(t *testing.T) {
on := AllRegistryFeatures(true)
off := AllRegistryFeatures(false)
if len(on) != len(FeatureCatalogKeys) || len(off) != len(FeatureCatalogKeys) {
t.Fatalf("len on=%d off=%d catalog=%d", len(on), len(off), len(FeatureCatalogKeys))
}
for _, k := range FeatureCatalogKeys {
if !on[k] {
t.Fatalf("expected %s enabled", k)
}
if off[k] {
t.Fatalf("expected %s disabled", k)
}
}
}
func TestPrepareCustomPackageCreateFeatures(t *testing.T) {
t.Run("custom create without features enables all", func(t *testing.T) {
p := Plan{Name: "ClientCo Deal", IsCustom: true}
prepareCustomPackageCreateFeatures(&p, true, false)
if p.Features == nil || len(p.Features) != len(FeatureCatalogKeys) {
t.Fatalf("expected full enable-all features, got %#v", p.Features)
}
for _, k := range FeatureCatalogKeys {
if !p.Features[k] {
t.Fatalf("key %s not enabled", k)
}
}
})
t.Run("non-public name forces is_custom", func(t *testing.T) {
p := Plan{Name: "Merkur", IsCustom: false}
prepareCustomPackageCreateFeatures(&p, true, false)
if !p.IsCustom {
t.Fatal("expected is_custom forced true for client deal")
}
if len(p.Features) != len(FeatureCatalogKeys) {
t.Fatalf("expected enable-all after force custom, got %d keys", len(p.Features))
}
})
t.Run("public free create leaves features nil", func(t *testing.T) {
p := Plan{Name: "Free", IsCustom: false}
prepareCustomPackageCreateFeatures(&p, true, false)
if p.Features != nil {
t.Fatalf("standard Free must not materialize features: %#v", p.Features)
}
})
t.Run("explicit features respected", func(t *testing.T) {
p := Plan{Name: "A1", IsCustom: true, Features: map[string]bool{"catalog.products": false}}
prepareCustomPackageCreateFeatures(&p, true, true)
if p.Features["catalog.products"] != false || len(p.Features) != 1 {
t.Fatalf("explicit features overwritten: %#v", p.Features)
}
})
t.Run("update does not rewrite", func(t *testing.T) {
p := Plan{Name: "A1", IsCustom: true, ID: 9}
prepareCustomPackageCreateFeatures(&p, false, false)
if p.Features != nil {
t.Fatalf("update must not inject features: %#v", p.Features)
}
})
t.Run("enterprise is_custom create enables all", func(t *testing.T) {
p := Plan{Name: "Enterprise", IsCustom: true}
prepareCustomPackageCreateFeatures(&p, true, false)
if len(p.Features) != len(FeatureCatalogKeys) {
t.Fatalf("enterprise custom create should enable all, got %d", len(p.Features))
}
})
t.Run("A1 custom create uses PAYG matrix without Stores/Marketing/Integrations", func(t *testing.T) {
p := Plan{Name: "A1", IsCustom: true}
prepareCustomPackageCreateFeatures(&p, true, false)
if p.IsLegacy {
t.Fatal("A1 PAYG create must clear is_legacy")
}
if !p.IsCustom {
t.Fatal("A1 remains a client deal (is_custom)")
}
if !p.Features["processing.monitor"] {
t.Fatal("A1 PAYG must enable processing.monitor")
}
if !p.Features["capability.eprel"] {
t.Fatal("A1 PAYG must enable capability.eprel")
}
if p.Features["stores.hub"] || p.Features["marketing.campaigns"] || p.Features["integrations.ai"] || p.Features["integrations.email"] {
t.Fatal("A1 PAYG must deny stores, marketing, and integrations")
}
if len(p.Features) != len(FeatureCatalogKeys) {
t.Fatalf("expected full tailored matrix, got %d keys", len(p.Features))
}
})
t.Run("Legacy create seeds legacy sparse", func(t *testing.T) {
p := Plan{Name: "Legacy", IsCustom: false, IsLegacy: true}
prepareCustomPackageCreateFeatures(&p, true, false)
if !p.IsLegacy {
t.Fatal("Legacy create must set is_legacy")
}
if p.Features["processing.monitor"] {
t.Fatal("Legacy must not enable processing.monitor")
}
})
}
func TestDefaultPlanFeaturesCustomUsesIsCustomPackage(t *testing.T) {
// Non-legacy client deal without is_custom flag still all-ON via name.
m := DefaultPlanFeatures("ClientCo Deal", false)
for _, k := range FeatureCatalogKeys {
if !m[k] {
t.Fatalf("client deal default missing %s", k)
}
}
// A1 without is_custom stays legacy — limited matrix.
a1 := DefaultPlanFeatures("A1", false)
if a1["processing.monitor"] {
t.Fatal("legacy A1 (is_custom=false) must keep processing.monitor off")
}
a1Payg := DefaultPlanFeatures("A1", true)
if !a1Payg["processing.monitor"] || !a1Payg["capability.eprel"] {
t.Fatal("A1 PAYG is_custom must enable core PAYG features")
}
if a1Payg["stores.hub"] || a1Payg["stores.shopify"] || a1Payg["marketing.campaigns"] || a1Payg["integrations.ai"] || a1Payg["integrations.ai.byok"] || a1Payg["integrations.email"] {
t.Fatal("A1 PAYG must keep Stores, Marketing, and Integrations off")
}
free := DefaultPlanFeatures("Free", false)
if free["capability.ai_processing"] {
t.Fatal("Free should keep AI processing off by default")
}
}
func TestPlanAllowsFeatureCustomByName(t *testing.T) {
if !PlanAllowsFeature("Merkur trial", false, nil, "capability.byok") {
t.Fatal("non-public package should allow all keys when overrides empty")
}
if PlanAllowsFeature("Free", false, nil, "capability.byok") {
t.Fatal("Free should deny byok by default")
}
}
func TestResolveEffectiveFeaturesSectionGate(t *testing.T) {
gates := emptyGatesView()
gates.Sections["marketing"] = false
features, sections, disabled := ResolveEffectiveFeatures("Merkur", true, nil, gates)
if sections["marketing"] {
t.Fatal("marketing section should be off")
}
if features["marketing.campaigns"] {
t.Fatal("marketing.campaigns should be effective-false when section off")
}
found := false
for _, d := range disabled {
if d == "marketing.campaigns" {
found = true
break
}
}
if !found {
t.Fatal("marketing.campaigns should appear in disabled list")
}
}