mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-05-07 00:37:36 +00:00
384 lines
8.8 KiB
Go
384 lines
8.8 KiB
Go
package licensing
|
|
|
|
import (
|
|
"testing"
|
|
)
|
|
|
|
type mockSource struct {
|
|
capabilities []string
|
|
limits map[string]int64
|
|
metersEnabled []string
|
|
planVersion string
|
|
subState SubscriptionState
|
|
trialStarted *int64
|
|
trialEnds *int64
|
|
}
|
|
|
|
func (m mockSource) Capabilities() []string { return m.capabilities }
|
|
func (m mockSource) Limits() map[string]int64 { return m.limits }
|
|
func (m mockSource) MetersEnabled() []string { return m.metersEnabled }
|
|
func (m mockSource) PlanVersion() string { return m.planVersion }
|
|
func (m mockSource) SubscriptionState() SubscriptionState { return m.subState }
|
|
func (m mockSource) TrialStartedAt() *int64 { return m.trialStarted }
|
|
func (m mockSource) TrialEndsAt() *int64 { return m.trialEnds }
|
|
func (m mockSource) OverflowGrantedAt() *int64 { return nil }
|
|
|
|
func TestEvaluator_HasCapability(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
source mockSource
|
|
key string
|
|
want bool
|
|
}{
|
|
{
|
|
name: "nil_evaluator_returns_false",
|
|
source: mockSource{},
|
|
key: "feature",
|
|
want: false,
|
|
},
|
|
{
|
|
name: "nil_source_returns_false",
|
|
source: mockSource{},
|
|
key: "feature",
|
|
want: false,
|
|
},
|
|
{
|
|
name: "finds_capability",
|
|
source: mockSource{capabilities: []string{"feature_a", "feature_b"}},
|
|
key: "feature_a",
|
|
want: true,
|
|
},
|
|
{
|
|
name: "missing_capability_returns_false",
|
|
source: mockSource{capabilities: []string{"feature_a"}},
|
|
key: "feature_b",
|
|
want: false,
|
|
},
|
|
{
|
|
name: "empty_capabilities_returns_false",
|
|
source: mockSource{capabilities: []string{}},
|
|
key: "feature_a",
|
|
want: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
tt := tt
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
e := NewEvaluator(tt.source)
|
|
got := e.HasCapability(tt.key)
|
|
if got != tt.want {
|
|
t.Errorf("HasCapability(%q) = %v, want %v", tt.key, got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestEvaluator_GetLimit(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
source mockSource
|
|
key string
|
|
wantValue int64
|
|
wantExists bool
|
|
}{
|
|
{
|
|
name: "nil_evaluator_returns_false",
|
|
source: mockSource{},
|
|
key: "max_monitored_systems",
|
|
wantValue: 0,
|
|
wantExists: false,
|
|
},
|
|
{
|
|
name: "finds_limit",
|
|
source: mockSource{limits: map[string]int64{"max_monitored_systems": 100}},
|
|
key: "max_monitored_systems",
|
|
wantValue: 100,
|
|
wantExists: true,
|
|
},
|
|
{
|
|
name: "missing_limit_returns_false",
|
|
source: mockSource{limits: map[string]int64{"max_monitored_systems": 100}},
|
|
key: "max_guests",
|
|
wantValue: 0,
|
|
wantExists: false,
|
|
},
|
|
{
|
|
name: "zero_limit_exists",
|
|
source: mockSource{limits: map[string]int64{"max_monitored_systems": 0}},
|
|
key: "max_monitored_systems",
|
|
wantValue: 0,
|
|
wantExists: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
tt := tt
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
e := NewEvaluator(tt.source)
|
|
gotVal, gotExists := e.GetLimit(tt.key)
|
|
if gotVal != tt.wantValue {
|
|
t.Errorf("GetLimit(%q).value = %v, want %v", tt.key, gotVal, tt.wantValue)
|
|
}
|
|
if gotExists != tt.wantExists {
|
|
t.Errorf("GetLimit(%q).exists = %v, want %v", tt.key, gotExists, tt.wantExists)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestEvaluator_CheckLimit(t *testing.T) {
|
|
source := mockSource{limits: map[string]int64{"max_monitored_systems": 100}}
|
|
e := NewEvaluator(source)
|
|
|
|
tests := []struct {
|
|
name string
|
|
key string
|
|
observed int64
|
|
want LimitCheckResult
|
|
}{
|
|
{
|
|
name: "well_under_limit",
|
|
key: "max_monitored_systems",
|
|
observed: 50,
|
|
want: LimitAllowed,
|
|
},
|
|
{
|
|
name: "at_90_percent",
|
|
key: "max_monitored_systems",
|
|
observed: 90,
|
|
want: LimitSoftBlock,
|
|
},
|
|
{
|
|
name: "at_limit",
|
|
key: "max_monitored_systems",
|
|
observed: 100,
|
|
want: LimitHardBlock,
|
|
},
|
|
{
|
|
name: "over_limit",
|
|
key: "max_monitored_systems",
|
|
observed: 150,
|
|
want: LimitHardBlock,
|
|
},
|
|
{
|
|
name: "undefined_limit_allows",
|
|
key: "max_guests",
|
|
observed: 1000,
|
|
want: LimitAllowed,
|
|
},
|
|
{
|
|
name: "zero_limit_allows",
|
|
key: "max_monitored_systems",
|
|
observed: 0,
|
|
want: LimitAllowed,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
tt := tt
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := e.CheckLimit(tt.key, tt.observed)
|
|
if got != tt.want {
|
|
t.Errorf("CheckLimit(%q, %d) = %v, want %v", tt.key, tt.observed, got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestEvaluator_MeterEnabled(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
source mockSource
|
|
key string
|
|
want bool
|
|
}{
|
|
{
|
|
name: "nil_source_returns_false",
|
|
source: mockSource{},
|
|
key: "meter_a",
|
|
want: false,
|
|
},
|
|
{
|
|
name: "finds_enabled_meter",
|
|
source: mockSource{metersEnabled: []string{"meter_a", "meter_b"}},
|
|
key: "meter_a",
|
|
want: true,
|
|
},
|
|
{
|
|
name: "missing_meter_returns_false",
|
|
source: mockSource{metersEnabled: []string{"meter_a"}},
|
|
key: "meter_b",
|
|
want: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
tt := tt
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
e := NewEvaluator(tt.source)
|
|
got := e.MeterEnabled(tt.key)
|
|
if got != tt.want {
|
|
t.Errorf("MeterEnabled(%q) = %v, want %v", tt.key, got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestEvaluator_PlanVersion(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
source mockSource
|
|
want string
|
|
}{
|
|
{
|
|
name: "nil_source_returns_empty",
|
|
source: mockSource{},
|
|
want: "",
|
|
},
|
|
{
|
|
name: "returns_plan_version",
|
|
source: mockSource{planVersion: "v2"},
|
|
want: "v2",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
tt := tt
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
e := NewEvaluator(tt.source)
|
|
got := e.PlanVersion()
|
|
if got != tt.want {
|
|
t.Errorf("PlanVersion() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestEvaluator_SubscriptionState(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
source mockSource
|
|
want SubscriptionState
|
|
}{
|
|
{
|
|
name: "empty_source_returns_empty",
|
|
source: mockSource{subState: ""},
|
|
want: "",
|
|
},
|
|
{
|
|
name: "returns_subscription_state",
|
|
source: mockSource{subState: SubStateGrace},
|
|
want: SubStateGrace,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
tt := tt
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
e := NewEvaluator(tt.source)
|
|
got := e.SubscriptionState()
|
|
if got != tt.want {
|
|
t.Errorf("SubscriptionState() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestEvaluator_NilSource_ReturnsDefaults(t *testing.T) {
|
|
var e *Evaluator
|
|
if got := e.HasCapability("feature"); got != false {
|
|
t.Errorf("HasCapability() on nil = %v, want false", got)
|
|
}
|
|
if got, _ := e.GetLimit("max_monitored_systems"); got != 0 {
|
|
t.Errorf("GetLimit() on nil = %v, want 0", got)
|
|
}
|
|
if got := e.CheckLimit("max_monitored_systems", 50); got != LimitAllowed {
|
|
t.Errorf("CheckLimit() on nil = %v, want LimitAllowed", got)
|
|
}
|
|
if got := e.MeterEnabled("meter"); got != false {
|
|
t.Errorf("MeterEnabled() on nil = %v, want false", got)
|
|
}
|
|
if got := e.PlanVersion(); got != "" {
|
|
t.Errorf("PlanVersion() on nil = %v, want empty", got)
|
|
}
|
|
if got := e.SubscriptionState(); got != SubStateActive {
|
|
t.Errorf("SubscriptionState() on nil = %v, want SubStateActive", got)
|
|
}
|
|
if got := e.TrialStartedAt(); got != nil {
|
|
t.Errorf("TrialStartedAt() on nil = %v, want nil", got)
|
|
}
|
|
if got := e.TrialEndsAt(); got != nil {
|
|
t.Errorf("TrialEndsAt() on nil = %v, want nil", got)
|
|
}
|
|
}
|
|
|
|
func TestEvaluator_TrialStartedAt(t *testing.T) {
|
|
ts := int64(1700000000)
|
|
tests := []struct {
|
|
name string
|
|
source mockSource
|
|
want *int64
|
|
}{
|
|
{
|
|
name: "nil_source_returns_nil",
|
|
source: mockSource{},
|
|
want: nil,
|
|
},
|
|
{
|
|
name: "returns_trial_started",
|
|
source: mockSource{trialStarted: &ts},
|
|
want: &ts,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
tt := tt
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
e := NewEvaluator(tt.source)
|
|
got := e.TrialStartedAt()
|
|
if (got == nil) != (tt.want == nil) {
|
|
t.Errorf("TrialStartedAt() = %v, want %v", got, tt.want)
|
|
return
|
|
}
|
|
if got != nil && *got != *tt.want {
|
|
t.Errorf("TrialStartedAt() = %v, want %v", *got, *tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestEvaluator_TrialEndsAt(t *testing.T) {
|
|
ts := int64(1700000000)
|
|
tests := []struct {
|
|
name string
|
|
source mockSource
|
|
want *int64
|
|
}{
|
|
{
|
|
name: "nil_source_returns_nil",
|
|
source: mockSource{},
|
|
want: nil,
|
|
},
|
|
{
|
|
name: "returns_trial_ends",
|
|
source: mockSource{trialEnds: &ts},
|
|
want: &ts,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
tt := tt
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
e := NewEvaluator(tt.source)
|
|
got := e.TrialEndsAt()
|
|
if (got == nil) != (tt.want == nil) {
|
|
t.Errorf("TrialEndsAt() = %v, want %v", got, tt.want)
|
|
return
|
|
}
|
|
if got != nil && *got != *tt.want {
|
|
t.Errorf("TrialEndsAt() = %v, want %v", *got, *tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|