| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- package service
- import (
- "testing"
- "github.com/mhsanaei/3x-ui/v3/internal/database/model"
- )
- func inboundKeepAlive(t *testing.T, inboundSvc *InboundService, ibId int, email string) int {
- t.Helper()
- ib, err := inboundSvc.GetInbound(ibId)
- if err != nil {
- t.Fatalf("GetInbound %d: %v", ibId, err)
- }
- clients, err := inboundSvc.GetClients(ib)
- if err != nil {
- t.Fatalf("GetClients %d: %v", ibId, err)
- }
- for i := range clients {
- if clients[i].Email == email {
- return clients[i].KeepAliveSeconds()
- }
- }
- t.Fatalf("email %q not found on inbound %d", email, ibId)
- return 0
- }
- // seedKeepAliveClient attaches one WireGuard client already carrying a
- // PersistentKeepalive, and returns its inbound and client-record id.
- func seedKeepAliveClient(t *testing.T, email string, keepAlive int) (*model.Inbound, int) {
- t.Helper()
- svc := &ClientService{}
- seeded := model.Client{
- Email: email,
- SubID: "sub-" + email,
- Enable: true,
- AllowedIPs: []string{"10.0.0.5/32"},
- KeepAlive: model.KeepAlivePtr(keepAlive),
- }
- ib := mkInbound(t, 51820, model.WireGuard, clientsSettings(t, []model.Client{seeded}))
- if err := svc.SyncInbound(nil, ib.Id, []model.Client{seeded}); err != nil {
- t.Fatalf("seed linkage: %v", err)
- }
- return ib, lookupClientRecord(t, email).Id
- }
- // Carrying forward on a zero incoming keepalive was a 0 -> 0 no-op while no UI
- // could set the field; once the client form could, "0 disables it" was unreachable.
- func TestUpdateCanClearKeepAliveOnAnExistingClient(t *testing.T) {
- setupBulkDB(t)
- inboundSvc := &InboundService{}
- svc := &ClientService{}
- ib, recId := seedKeepAliveClient(t, "ka@x", 25)
- if got := inboundKeepAlive(t, inboundSvc, ib.Id, "ka@x"); got != 25 {
- t.Fatalf("seeded keepAlive = %d, want 25", got)
- }
- updated := model.Client{
- Email: "ka@x",
- Enable: true,
- AllowedIPs: []string{"10.0.0.5/32"},
- KeepAlive: model.KeepAlivePtr(0),
- }
- if _, err := svc.Update(inboundSvc, recId, updated, 0); err != nil {
- t.Fatalf("Update: %v", err)
- }
- if got := inboundKeepAlive(t, inboundSvc, ib.Id, "ka@x"); got != 0 {
- t.Fatalf("inbound keepAlive after an explicit 0 = %d, want 0", got)
- }
- if got := lookupClientRecord(t, "ka@x").KeepAlive; got != 0 {
- t.Fatalf("stored wg_keep_alive after an explicit 0 = %d, want 0", got)
- }
- }
- // The other half of the contract: a payload that never mentions keepAlive (a
- // metadata-only edit from the bot or the API) leaves the stored value alone.
- func TestUpdateWithoutKeepAlivePreservesTheStoredValue(t *testing.T) {
- setupBulkDB(t)
- inboundSvc := &InboundService{}
- svc := &ClientService{}
- ib, recId := seedKeepAliveClient(t, "ka@x", 25)
- updated := model.Client{
- Email: "ka@x",
- Enable: true,
- AllowedIPs: []string{"10.0.0.5/32"},
- }
- if _, err := svc.Update(inboundSvc, recId, updated, 0); err != nil {
- t.Fatalf("Update: %v", err)
- }
- if got := inboundKeepAlive(t, inboundSvc, ib.Id, "ka@x"); got != 25 {
- t.Fatalf("inbound keepAlive after an edit that omitted it = %d, want 25", got)
- }
- if got := lookupClientRecord(t, "ka@x").KeepAlive; got != 25 {
- t.Fatalf("stored wg_keep_alive after an edit that omitted it = %d, want 25", got)
- }
- }
|