mirror of
https://github.com/EZ-Api/ez-api.git
synced 2026-01-13 17:47:51 +00:00
test(service): add tests for IP ban update edge cases
Add integration tests for `IPBanService.Update` to verify: - Reactivating an expired ban correctly detects overlaps with existing active bans. - Explicitly clearing the `expires_at` field (setting to null) works as expected.
This commit is contained in:
@@ -1,7 +1,14 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ez-api/ez-api/internal/model"
|
||||
"gorm.io/driver/sqlite"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func TestNormalizeCIDR_IPv4Address(t *testing.T) {
|
||||
@@ -150,3 +157,82 @@ func TestCIDROverlaps_InvalidCIDR(t *testing.T) {
|
||||
t.Error("expected no overlap with invalid CIDR")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIPBanService_Update_ReactivateOverlap(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
db, err := gorm.Open(sqlite.Open("file:"+t.Name()+"?mode=memory&cache=shared"), &gorm.Config{})
|
||||
if err != nil {
|
||||
t.Fatalf("open sqlite: %v", err)
|
||||
}
|
||||
if err := db.AutoMigrate(&model.IPBan{}); err != nil {
|
||||
t.Fatalf("migrate: %v", err)
|
||||
}
|
||||
|
||||
active := model.IPBan{CIDR: "10.0.0.0/24", Status: model.IPBanStatusActive}
|
||||
if err := db.Create(&active).Error; err != nil {
|
||||
t.Fatalf("create active ban: %v", err)
|
||||
}
|
||||
|
||||
expired := model.IPBan{CIDR: "10.0.0.128/25", Status: model.IPBanStatusExpired}
|
||||
if err := db.Create(&expired).Error; err != nil {
|
||||
t.Fatalf("create expired ban: %v", err)
|
||||
}
|
||||
|
||||
svc := NewIPBanService(db, nil)
|
||||
_, err = svc.Update(context.Background(), expired.ID, UpdateIPBanRequest{
|
||||
Status: func() *string {
|
||||
s := model.IPBanStatusActive
|
||||
return &s
|
||||
}(),
|
||||
})
|
||||
if !errors.Is(err, ErrCIDROverlap) {
|
||||
t.Fatalf("expected overlap error, got %v", err)
|
||||
}
|
||||
|
||||
var reloaded model.IPBan
|
||||
if err := db.First(&reloaded, expired.ID).Error; err != nil {
|
||||
t.Fatalf("reload expired ban: %v", err)
|
||||
}
|
||||
if reloaded.Status != model.IPBanStatusExpired {
|
||||
t.Fatalf("expected status to remain expired, got %s", reloaded.Status)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIPBanService_Update_ClearExpiresAt(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
db, err := gorm.Open(sqlite.Open("file:"+t.Name()+"?mode=memory&cache=shared"), &gorm.Config{})
|
||||
if err != nil {
|
||||
t.Fatalf("open sqlite: %v", err)
|
||||
}
|
||||
if err := db.AutoMigrate(&model.IPBan{}); err != nil {
|
||||
t.Fatalf("migrate: %v", err)
|
||||
}
|
||||
|
||||
exp := time.Now().Add(time.Hour).Unix()
|
||||
ban := model.IPBan{
|
||||
CIDR: "192.168.1.1/32",
|
||||
Status: model.IPBanStatusActive,
|
||||
ExpiresAt: &exp,
|
||||
}
|
||||
if err := db.Create(&ban).Error; err != nil {
|
||||
t.Fatalf("create ban: %v", err)
|
||||
}
|
||||
|
||||
svc := NewIPBanService(db, nil)
|
||||
if _, err := svc.Update(context.Background(), ban.ID, UpdateIPBanRequest{
|
||||
ExpiresAt: nil,
|
||||
ExpiresAtSet: true,
|
||||
}); err != nil {
|
||||
t.Fatalf("update expires_at: %v", err)
|
||||
}
|
||||
|
||||
var reloaded model.IPBan
|
||||
if err := db.First(&reloaded, ban.ID).Error; err != nil {
|
||||
t.Fatalf("reload ban: %v", err)
|
||||
}
|
||||
if reloaded.ExpiresAt != nil {
|
||||
t.Fatalf("expected expires_at to be cleared, got %v", *reloaded.ExpiresAt)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user