package model import ( "database/sql" "testing" "time" ) func TestIsExpired_Perpetual(t *testing.T) { l := &License{ ExpiresAt: sql.NullTime{Valid: false}, } if l.IsExpired() { t.Error("PERPETUAL licenca ne sme biti istekla") } } func TestIsExpired_Active(t *testing.T) { l := &License{ ExpiresAt: sql.NullTime{ Time: time.Now().Add(24 * time.Hour), Valid: true, }, } if l.IsExpired() { t.Error("licenca koja istice sutra ne sme biti istekla") } } func TestIsExpired_Expired(t *testing.T) { l := &License{ ExpiresAt: sql.NullTime{ Time: time.Now().Add(-24 * time.Hour), Valid: true, }, } if !l.IsExpired() { t.Error("licenca koja je istekla juce mora biti istekla") } } func TestIsInGrace_NotExpired(t *testing.T) { l := &License{ ExpiresAt: sql.NullTime{ Time: time.Now().Add(24 * time.Hour), Valid: true, }, GraceDays: 30, } if l.IsInGrace() { t.Error("licenca koja nije istekla ne sme biti u grace periodu") } } func TestIsInGrace_InGrace(t *testing.T) { l := &License{ ExpiresAt: sql.NullTime{ Time: time.Now().Add(-5 * 24 * time.Hour), // istekla pre 5 dana Valid: true, }, GraceDays: 30, } if !l.IsInGrace() { t.Error("licenca istekla pre 5 dana sa 30 dana grace-a mora biti u grace-u") } } func TestIsInGrace_GraceExpired(t *testing.T) { l := &License{ ExpiresAt: sql.NullTime{ Time: time.Now().Add(-35 * 24 * time.Hour), // istekla pre 35 dana Valid: true, }, GraceDays: 30, } if l.IsInGrace() { t.Error("licenca kojoj je grace prosao ne sme biti u grace-u") } } func TestIsInGrace_Perpetual(t *testing.T) { l := &License{ ExpiresAt: sql.NullTime{Valid: false}, GraceDays: 30, } if l.IsInGrace() { t.Error("PERPETUAL licenca ne sme biti u grace periodu") } } func TestIsGraceExpired(t *testing.T) { l := &License{ ExpiresAt: sql.NullTime{ Time: time.Now().Add(-40 * 24 * time.Hour), Valid: true, }, GraceDays: 30, } if !l.IsGraceExpired() { t.Error("grace period je prosao, mora biti expired") } } func TestIsGraceExpired_Perpetual(t *testing.T) { l := &License{ ExpiresAt: sql.NullTime{Valid: false}, GraceDays: 30, } if l.IsGraceExpired() { t.Error("PERPETUAL licenca ne moze imati istekao grace") } } func TestMaskedKey(t *testing.T) { tests := []struct { key string prefix string expected string }{ {"LT-K7M2-9P4N-R3W8-J6T1", "LT-", "LT-K7M2-****-****-J6T1"}, {"ESIR-A3B5-C8D2-E7F4-G9H6", "ESIR-", "ESIR-A3B5-****-****-G9H6"}, {"ARV-X2Y3-Z4A5-B6C7-D8E9", "ARV-", "ARV-X2Y3-****-****-D8E9"}, } for _, tt := range tests { l := &License{LicenseKey: tt.key, ProductPrefix: tt.prefix} got := l.MaskedKey() if got != tt.expected { t.Errorf("MaskedKey(%q) = %q, ocekivano %q", tt.key, got, tt.expected) } } } func TestStatusText(t *testing.T) { tests := []struct { name string license License expected string }{ { name: "revoked", license: License{Revoked: true, Active: true}, expected: "Opozvana", }, { name: "inactive", license: License{Active: false}, expected: "Neaktivna", }, { name: "active", license: License{ Active: true, ExpiresAt: sql.NullTime{Time: time.Now().Add(24 * time.Hour), Valid: true}, }, expected: "Aktivna", }, { name: "trial", license: License{ Active: true, LicenseType: "TRIAL", ExpiresAt: sql.NullTime{Time: time.Now().Add(24 * time.Hour), Valid: true}, }, expected: "Trial", }, { name: "in_grace", license: License{ Active: true, ExpiresAt: sql.NullTime{Time: time.Now().Add(-5 * 24 * time.Hour), Valid: true}, GraceDays: 30, }, expected: "Grace period", }, { name: "grace_expired", license: License{ Active: true, ExpiresAt: sql.NullTime{Time: time.Now().Add(-40 * 24 * time.Hour), Valid: true}, GraceDays: 30, }, expected: "Istekla (grace)", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := tt.license.StatusText() if got != tt.expected { t.Errorf("StatusText() = %q, ocekivano %q", got, tt.expected) } }) } } func TestStatusClass(t *testing.T) { l := &License{Active: true, ExpiresAt: sql.NullTime{Time: time.Now().Add(24 * time.Hour), Valid: true}} if l.StatusClass() != "status-active" { t.Errorf("StatusClass() = %q, ocekivano 'status-active'", l.StatusClass()) } l2 := &License{Revoked: true, Active: true} if l2.StatusClass() != "status-revoked" { t.Errorf("StatusClass() = %q, ocekivano 'status-revoked'", l2.StatusClass()) } } func TestExpiresAtFormatted(t *testing.T) { l := &License{ExpiresAt: sql.NullTime{Valid: false}} if l.ExpiresAtFormatted() != "Neograniceno" { t.Errorf("ocekivano 'Neograniceno', dobijeno %q", l.ExpiresAtFormatted()) } date := time.Date(2026, 4, 1, 0, 0, 0, 0, time.UTC) l2 := &License{ExpiresAt: sql.NullTime{Time: date, Valid: true}} expected := "01.04.2026" if l2.ExpiresAtFormatted() != expected { t.Errorf("ocekivano %q, dobijeno %q", expected, l2.ExpiresAtFormatted()) } }