forked from baron/baron-sso
userfront&backend test coverage 추가
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
package domain
|
||||
|
||||
import "testing"
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestHydraClient_HeadlessLoginFlags(t *testing.T) {
|
||||
t.Run("metadata-backed headless login client is supported", func(t *testing.T) {
|
||||
@@ -76,3 +79,104 @@ func TestHydraClient_HeadlessLoginFlags(t *testing.T) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestHydraClientHeadlessMetadataAccessors(t *testing.T) {
|
||||
t.Run("metadata values override inline values", func(t *testing.T) {
|
||||
metadataJWKS := map[string]any{"keys": []any{"metadata-key"}}
|
||||
client := HydraClient{
|
||||
TokenEndpointAuthMethod: "client_secret_post",
|
||||
JWKSUri: "https://inline.example.com/jwks.json",
|
||||
JWKS: map[string]any{"keys": []any{"inline-key"}},
|
||||
Metadata: map[string]any{
|
||||
MetadataHeadlessTokenEndpointAuthMethod: " private_key_jwt ",
|
||||
MetadataHeadlessJWKSURI: " https://metadata.example.com/jwks.json ",
|
||||
MetadataHeadlessJWKS: metadataJWKS,
|
||||
},
|
||||
}
|
||||
|
||||
if got := client.HeadlessTokenEndpointAuthMethod(); got != "private_key_jwt" {
|
||||
t.Fatalf("unexpected auth method: %q", got)
|
||||
}
|
||||
if got := client.HeadlessJWKSURI(); got != "https://metadata.example.com/jwks.json" {
|
||||
t.Fatalf("unexpected jwks uri: %q", got)
|
||||
}
|
||||
if got := client.HeadlessJWKS(); !reflect.DeepEqual(got, metadataJWKS) {
|
||||
t.Fatalf("unexpected jwks value: %#v", got)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("blank or missing metadata values fall back to inline values", func(t *testing.T) {
|
||||
inlineJWKS := map[string]any{"keys": []any{"inline-key"}}
|
||||
client := HydraClient{
|
||||
TokenEndpointAuthMethod: " private_key_jwt ",
|
||||
JWKSUri: " https://inline.example.com/jwks.json ",
|
||||
JWKS: inlineJWKS,
|
||||
Metadata: map[string]any{
|
||||
MetadataHeadlessTokenEndpointAuthMethod: " ",
|
||||
MetadataHeadlessJWKSURI: " ",
|
||||
MetadataHeadlessJWKS: nil,
|
||||
},
|
||||
}
|
||||
|
||||
if got := client.HeadlessTokenEndpointAuthMethod(); got != "private_key_jwt" {
|
||||
t.Fatalf("unexpected auth method: %q", got)
|
||||
}
|
||||
if got := client.HeadlessJWKSURI(); got != "https://inline.example.com/jwks.json" {
|
||||
t.Fatalf("unexpected jwks uri: %q", got)
|
||||
}
|
||||
if got := client.HeadlessJWKS(); !reflect.DeepEqual(got, inlineJWKS) {
|
||||
t.Fatalf("unexpected jwks value: %#v", got)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestHydraClientBackchannelLogoutAccessors(t *testing.T) {
|
||||
t.Run("metadata values override inline values", func(t *testing.T) {
|
||||
inlineRequired := false
|
||||
client := HydraClient{
|
||||
BackChannelLogoutURI: "https://inline.example.com/logout",
|
||||
BackChannelLogoutSessionRequired: &inlineRequired,
|
||||
Metadata: map[string]any{
|
||||
MetadataBackChannelLogoutURI: " https://metadata.example.com/logout ",
|
||||
MetadataBackChannelLogoutSessionRequired: true,
|
||||
},
|
||||
}
|
||||
|
||||
if got := client.BackchannelLogoutURI(); got != "https://metadata.example.com/logout" {
|
||||
t.Fatalf("unexpected logout uri: %q", got)
|
||||
}
|
||||
if !client.BackchannelLogoutSessionRequiredValue() {
|
||||
t.Fatalf("expected metadata session_required value")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("blank or missing metadata values fall back to inline values", func(t *testing.T) {
|
||||
inlineRequired := true
|
||||
client := HydraClient{
|
||||
BackChannelLogoutURI: " https://inline.example.com/logout ",
|
||||
BackChannelLogoutSessionRequired: &inlineRequired,
|
||||
Metadata: map[string]any{
|
||||
MetadataBackChannelLogoutURI: " ",
|
||||
MetadataBackChannelLogoutSessionRequired: "true",
|
||||
},
|
||||
}
|
||||
|
||||
if got := client.BackchannelLogoutURI(); got != "https://inline.example.com/logout" {
|
||||
t.Fatalf("unexpected logout uri: %q", got)
|
||||
}
|
||||
if !client.BackchannelLogoutSessionRequiredValue() {
|
||||
t.Fatalf("expected inline session_required value")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("missing session required defaults to false", func(t *testing.T) {
|
||||
client := HydraClient{}
|
||||
|
||||
if got := client.BackchannelLogoutURI(); got != "" {
|
||||
t.Fatalf("unexpected logout uri: %q", got)
|
||||
}
|
||||
if client.BackchannelLogoutSessionRequiredValue() {
|
||||
t.Fatalf("expected default session_required false")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
93
backend/internal/domain/json_map_test.go
Normal file
93
backend/internal/domain/json_map_test.go
Normal file
@@ -0,0 +1,93 @@
|
||||
package domain
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestJSONMapValue(t *testing.T) {
|
||||
t.Run("nil map returns nil database value", func(t *testing.T) {
|
||||
var payload JSONMap
|
||||
|
||||
value, err := payload.Value()
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if value != nil {
|
||||
t.Fatalf("expected nil value, got %v", value)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("map marshals to JSON string", func(t *testing.T) {
|
||||
payload := JSONMap{"enabled": true, "name": "baron"}
|
||||
|
||||
value, err := payload.Value()
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
raw, ok := value.(string)
|
||||
if !ok {
|
||||
t.Fatalf("expected string value, got %T", value)
|
||||
}
|
||||
|
||||
var decoded map[string]any
|
||||
if err := json.Unmarshal([]byte(raw), &decoded); err != nil {
|
||||
t.Fatalf("value should be valid json: %v", err)
|
||||
}
|
||||
if decoded["enabled"] != true || decoded["name"] != "baron" {
|
||||
t.Fatalf("unexpected decoded value: %#v", decoded)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestJSONMapScan(t *testing.T) {
|
||||
t.Run("nil value becomes empty map", func(t *testing.T) {
|
||||
var payload JSONMap
|
||||
|
||||
if err := payload.Scan(nil); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if payload == nil || len(payload) != 0 {
|
||||
t.Fatalf("expected empty map, got %#v", payload)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("byte slice value decodes JSON", func(t *testing.T) {
|
||||
var payload JSONMap
|
||||
|
||||
if err := payload.Scan([]byte(`{"count":2,"name":"baron"}`)); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if payload["count"] != float64(2) || payload["name"] != "baron" {
|
||||
t.Fatalf("unexpected payload: %#v", payload)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("string value decodes JSON", func(t *testing.T) {
|
||||
var payload JSONMap
|
||||
|
||||
if err := payload.Scan(`{"active":true}`); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if payload["active"] != true {
|
||||
t.Fatalf("unexpected payload: %#v", payload)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("unsupported value type returns error", func(t *testing.T) {
|
||||
var payload JSONMap
|
||||
|
||||
if err := payload.Scan(42); err == nil {
|
||||
t.Fatalf("expected unsupported type error")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("invalid JSON returns error", func(t *testing.T) {
|
||||
var payload JSONMap
|
||||
|
||||
if err := payload.Scan(`{invalid`); err == nil {
|
||||
t.Fatalf("expected invalid JSON error")
|
||||
}
|
||||
})
|
||||
}
|
||||
357
backend/internal/domain/model_hooks_test.go
Normal file
357
backend/internal/domain/model_hooks_test.go
Normal file
@@ -0,0 +1,357 @@
|
||||
package domain
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
func requireGeneratedUUID(t *testing.T, value string) {
|
||||
t.Helper()
|
||||
|
||||
if value == "" {
|
||||
t.Fatalf("expected generated uuid")
|
||||
}
|
||||
if _, err := uuid.Parse(value); err != nil {
|
||||
t.Fatalf("expected valid uuid, got %q: %v", value, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBeforeCreateGeneratesMissingIDs(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
run func(t *testing.T)
|
||||
}{
|
||||
{
|
||||
name: "api key",
|
||||
run: func(t *testing.T) {
|
||||
model := ApiKey{}
|
||||
if err := model.BeforeCreate(nil); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
requireGeneratedUUID(t, model.ID)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "client consent",
|
||||
run: func(t *testing.T) {
|
||||
model := ClientConsent{}
|
||||
if err := model.BeforeCreate(nil); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
requireGeneratedUUID(t, model.ID)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "identity provider config",
|
||||
run: func(t *testing.T) {
|
||||
model := IdentityProviderConfig{}
|
||||
if err := model.BeforeCreate(nil); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
requireGeneratedUUID(t, model.ID)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "keto outbox",
|
||||
run: func(t *testing.T) {
|
||||
model := KetoOutbox{}
|
||||
if err := model.BeforeCreate(nil); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
requireGeneratedUUID(t, model.ID)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "tenant",
|
||||
run: func(t *testing.T) {
|
||||
model := Tenant{}
|
||||
if err := model.BeforeCreate(nil); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
requireGeneratedUUID(t, model.ID)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "tenant domain",
|
||||
run: func(t *testing.T) {
|
||||
model := TenantDomain{}
|
||||
if err := model.BeforeCreate(nil); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
requireGeneratedUUID(t, model.ID)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "user",
|
||||
run: func(t *testing.T) {
|
||||
model := User{}
|
||||
if err := model.BeforeCreate(nil); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
requireGeneratedUUID(t, model.ID)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "user group",
|
||||
run: func(t *testing.T) {
|
||||
model := UserGroup{}
|
||||
if err := model.BeforeCreate(nil); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
requireGeneratedUUID(t, model.ID)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "worksmobile resource mapping",
|
||||
run: func(t *testing.T) {
|
||||
model := WorksmobileResourceMapping{}
|
||||
if err := model.BeforeCreate(nil); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
requireGeneratedUUID(t, model.ID)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, tc.run)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBeforeCreatePreservesExistingIDs(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
run func(t *testing.T)
|
||||
}{
|
||||
{
|
||||
name: "api key",
|
||||
run: func(t *testing.T) {
|
||||
model := ApiKey{ID: "existing-id"}
|
||||
if err := model.BeforeCreate(nil); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if model.ID != "existing-id" {
|
||||
t.Fatalf("expected existing id to be preserved")
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "client consent",
|
||||
run: func(t *testing.T) {
|
||||
model := ClientConsent{ID: "existing-id"}
|
||||
if err := model.BeforeCreate(nil); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if model.ID != "existing-id" {
|
||||
t.Fatalf("expected existing id to be preserved")
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "identity provider config",
|
||||
run: func(t *testing.T) {
|
||||
model := IdentityProviderConfig{ID: "existing-id"}
|
||||
if err := model.BeforeCreate(nil); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if model.ID != "existing-id" {
|
||||
t.Fatalf("expected existing id to be preserved")
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "keto outbox",
|
||||
run: func(t *testing.T) {
|
||||
model := KetoOutbox{ID: "existing-id"}
|
||||
if err := model.BeforeCreate(nil); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if model.ID != "existing-id" {
|
||||
t.Fatalf("expected existing id to be preserved")
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "tenant",
|
||||
run: func(t *testing.T) {
|
||||
model := Tenant{ID: "existing-id"}
|
||||
if err := model.BeforeCreate(nil); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if model.ID != "existing-id" {
|
||||
t.Fatalf("expected existing id to be preserved")
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "tenant domain",
|
||||
run: func(t *testing.T) {
|
||||
model := TenantDomain{ID: "existing-id"}
|
||||
if err := model.BeforeCreate(nil); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if model.ID != "existing-id" {
|
||||
t.Fatalf("expected existing id to be preserved")
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "user",
|
||||
run: func(t *testing.T) {
|
||||
model := User{ID: "existing-id"}
|
||||
if err := model.BeforeCreate(nil); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if model.ID != "existing-id" {
|
||||
t.Fatalf("expected existing id to be preserved")
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "user group",
|
||||
run: func(t *testing.T) {
|
||||
model := UserGroup{ID: "existing-id"}
|
||||
if err := model.BeforeCreate(nil); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if model.ID != "existing-id" {
|
||||
t.Fatalf("expected existing id to be preserved")
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "worksmobile resource mapping",
|
||||
run: func(t *testing.T) {
|
||||
model := WorksmobileResourceMapping{ID: "existing-id"}
|
||||
if err := model.BeforeCreate(nil); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if model.ID != "existing-id" {
|
||||
t.Fatalf("expected existing id to be preserved")
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, tc.run)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTableNames(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
got string
|
||||
expected string
|
||||
}{
|
||||
{name: "keto outbox", got: (&KetoOutbox{}).TableName(), expected: "keto_outbox"},
|
||||
{name: "rp usage event", got: (&RPUsageEvent{}).TableName(), expected: "rp_usage_outbox"},
|
||||
{name: "rp user metadata", got: (RPUserMetadata{}).TableName(), expected: "rp_user_metadata"},
|
||||
{name: "user group", got: (&UserGroup{}).TableName(), expected: "user_groups"},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
if tc.got != tc.expected {
|
||||
t.Fatalf("unexpected table name: got=%s expected=%s", tc.got, tc.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestTenantIsActive(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
status string
|
||||
expected bool
|
||||
}{
|
||||
{name: "active", status: TenantStatusActive, expected: true},
|
||||
{name: "pending", status: TenantStatusPending, expected: false},
|
||||
{name: "suspended", status: TenantStatusSuspended, expected: false},
|
||||
{name: "deleted", status: TenantStatusDeleted, expected: false},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
tenant := Tenant{Status: tc.status}
|
||||
if got := tenant.IsActive(); got != tc.expected {
|
||||
t.Fatalf("unexpected active state: got=%v expected=%v", got, tc.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRPUsageEventBeforeCreateDefaults(t *testing.T) {
|
||||
event := RPUsageEvent{}
|
||||
|
||||
if err := event.BeforeCreate(nil); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
requireGeneratedUUID(t, event.ID)
|
||||
if event.Status != RPUsageOutboxStatusPending {
|
||||
t.Fatalf("unexpected status: %s", event.Status)
|
||||
}
|
||||
if event.OccurredAt.IsZero() {
|
||||
t.Fatalf("expected occurred_at default")
|
||||
}
|
||||
if event.Payload == nil {
|
||||
t.Fatalf("expected empty payload default")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRPUsageEventBeforeCreatePreservesExplicitValues(t *testing.T) {
|
||||
occurredAt := time.Date(2026, 5, 29, 1, 2, 3, 0, time.UTC)
|
||||
event := RPUsageEvent{
|
||||
ID: "existing-id",
|
||||
Status: RPUsageOutboxStatusProcessing,
|
||||
OccurredAt: occurredAt,
|
||||
Payload: JSONMap{"source": "test"},
|
||||
}
|
||||
|
||||
if err := event.BeforeCreate(nil); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if event.ID != "existing-id" {
|
||||
t.Fatalf("expected existing id to be preserved")
|
||||
}
|
||||
if event.Status != RPUsageOutboxStatusProcessing {
|
||||
t.Fatalf("expected status to be preserved")
|
||||
}
|
||||
if !event.OccurredAt.Equal(occurredAt) {
|
||||
t.Fatalf("expected occurred_at to be preserved")
|
||||
}
|
||||
if event.Payload["source"] != "test" {
|
||||
t.Fatalf("expected payload to be preserved")
|
||||
}
|
||||
}
|
||||
|
||||
func TestWorksmobileOutboxBeforeCreateDefaults(t *testing.T) {
|
||||
outbox := WorksmobileOutbox{}
|
||||
|
||||
if err := outbox.BeforeCreate(nil); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
requireGeneratedUUID(t, outbox.ID)
|
||||
if outbox.Status != WorksmobileOutboxStatusPending {
|
||||
t.Fatalf("unexpected status: %s", outbox.Status)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWorksmobileOutboxBeforeCreatePreservesExplicitValues(t *testing.T) {
|
||||
outbox := WorksmobileOutbox{
|
||||
ID: "existing-id",
|
||||
Status: WorksmobileOutboxStatusProcessing,
|
||||
}
|
||||
|
||||
if err := outbox.BeforeCreate(nil); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if outbox.ID != "existing-id" {
|
||||
t.Fatalf("expected existing id to be preserved")
|
||||
}
|
||||
if outbox.Status != WorksmobileOutboxStatusProcessing {
|
||||
t.Fatalf("expected status to be preserved")
|
||||
}
|
||||
}
|
||||
80
backend/internal/domain/shared_link_test.go
Normal file
80
backend/internal/domain/shared_link_test.go
Normal file
@@ -0,0 +1,80 @@
|
||||
package domain
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestSharedLinkBeforeCreate(t *testing.T) {
|
||||
t.Run("generates id and token when missing", func(t *testing.T) {
|
||||
link := SharedLink{}
|
||||
|
||||
if err := link.BeforeCreate(nil); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if link.ID == "" {
|
||||
t.Fatalf("expected generated id")
|
||||
}
|
||||
if len(link.Token) != 64 {
|
||||
t.Fatalf("expected 64-character token, got %q", link.Token)
|
||||
}
|
||||
if _, err := hex.DecodeString(link.Token); err != nil {
|
||||
t.Fatalf("expected hex token: %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("preserves existing id and token", func(t *testing.T) {
|
||||
link := SharedLink{
|
||||
ID: "existing-id",
|
||||
Token: "existing-token",
|
||||
}
|
||||
|
||||
if err := link.BeforeCreate(nil); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if link.ID != "existing-id" || link.Token != "existing-token" {
|
||||
t.Fatalf("expected existing fields to be preserved: %#v", link)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestSharedLinkIsValid(t *testing.T) {
|
||||
future := time.Now().Add(time.Hour)
|
||||
past := time.Now().Add(-time.Hour)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
link SharedLink
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
name: "active link without expiration is valid",
|
||||
link: SharedLink{IsActive: true},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "active link with future expiration is valid",
|
||||
link: SharedLink{IsActive: true, ExpiresAt: &future},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "inactive link is invalid",
|
||||
link: SharedLink{IsActive: false, ExpiresAt: &future},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "expired link is invalid",
|
||||
link: SharedLink{IsActive: true, ExpiresAt: &past},
|
||||
expected: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
if got := tc.link.IsValid(); got != tc.expected {
|
||||
t.Fatalf("unexpected validity: got=%v expected=%v", got, tc.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user