@@ -0,0 +1,164 @@
|
||||
package ai_mate_ser
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"91porn-server/models/v/usermod"
|
||||
"91porn-server/models/v/walletmod"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
func TestLoginCreatesAiMateUserAndCreditsLocalBalance(t *testing.T) {
|
||||
const uid = uint64(32239213)
|
||||
var (
|
||||
updatedAiMateUID string
|
||||
accessAiMateUID string
|
||||
creditedBalance float64
|
||||
)
|
||||
deps := loginDependencies{
|
||||
findUser: func(gotUID uint64) (*usermod.User, error) {
|
||||
if gotUID != uid {
|
||||
t.Fatalf("findUser uid = %d, want %d", gotUID, uid)
|
||||
}
|
||||
return &usermod.User{
|
||||
ID: primitive.NewObjectID(),
|
||||
UID: uid,
|
||||
Name: "tester",
|
||||
}, nil
|
||||
},
|
||||
updateUser: func(gotUID uint64, selector usermod.UserSelector) (*usermod.User, error) {
|
||||
if gotUID != uid || selector.AiMateUid == nil {
|
||||
t.Fatalf("unexpected updateUser arguments: uid=%d selector=%+v", gotUID, selector)
|
||||
}
|
||||
updatedAiMateUID = *selector.AiMateUid
|
||||
return &usermod.User{}, nil
|
||||
},
|
||||
getWallet: func(uint64) (*walletmod.Wallet, error) {
|
||||
return &walletmod.Wallet{AiMateBalance: 12}, nil
|
||||
},
|
||||
getRemoteBalance: func(uint64, string) (float64, error) {
|
||||
t.Fatal("new AI mate user must not query a remote balance")
|
||||
return 0, nil
|
||||
},
|
||||
getAccessURL: func(gotUID uint64, aiMateUID, name string, balance float64) (string, error) {
|
||||
if gotUID != uid || name != "tester" {
|
||||
t.Fatalf("unexpected access URL arguments: uid=%d name=%q", gotUID, name)
|
||||
}
|
||||
accessAiMateUID = aiMateUID
|
||||
creditedBalance = balance
|
||||
return "https://example.com/login", nil
|
||||
},
|
||||
newUUID: func() string { return "new-ai-mate-uid" },
|
||||
}
|
||||
|
||||
got, err := login(uid, deps)
|
||||
if err != nil {
|
||||
t.Fatalf("login() error = %v", err)
|
||||
}
|
||||
if got.URL != "https://example.com/login" {
|
||||
t.Fatalf("login() URL = %q", got.URL)
|
||||
}
|
||||
if updatedAiMateUID != "new-ai-mate-uid" || accessAiMateUID != updatedAiMateUID {
|
||||
t.Fatalf("AI mate uid update=%q access=%q", updatedAiMateUID, accessAiMateUID)
|
||||
}
|
||||
if creditedBalance != 12 {
|
||||
t.Fatalf("credited balance = %v, want 12", creditedBalance)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoginOnlyCreditsBalanceDifference(t *testing.T) {
|
||||
const uid = uint64(32239213)
|
||||
var creditedBalance float64
|
||||
deps := loginDependencies{
|
||||
findUser: func(uint64) (*usermod.User, error) {
|
||||
return &usermod.User{
|
||||
ID: primitive.NewObjectID(),
|
||||
UID: uid,
|
||||
Name: "tester",
|
||||
AiMateUid: "existing-ai-mate-uid",
|
||||
}, nil
|
||||
},
|
||||
updateUser: func(uint64, usermod.UserSelector) (*usermod.User, error) {
|
||||
t.Fatal("existing AI mate user must not be updated")
|
||||
return nil, nil
|
||||
},
|
||||
getWallet: func(uint64) (*walletmod.Wallet, error) {
|
||||
return &walletmod.Wallet{AiMateBalance: 15}, nil
|
||||
},
|
||||
getRemoteBalance: func(gotUID uint64, aiMateUID string) (float64, error) {
|
||||
if gotUID != uid || aiMateUID != "existing-ai-mate-uid" {
|
||||
t.Fatalf("unexpected remote balance arguments: uid=%d aiMateUID=%q", gotUID, aiMateUID)
|
||||
}
|
||||
return 9, nil
|
||||
},
|
||||
getAccessURL: func(_ uint64, _ string, _ string, balance float64) (string, error) {
|
||||
creditedBalance = balance
|
||||
return "https://example.com/login", nil
|
||||
},
|
||||
newUUID: func() string {
|
||||
t.Fatal("existing AI mate user must not generate another uid")
|
||||
return ""
|
||||
},
|
||||
}
|
||||
|
||||
if _, err := login(uid, deps); err != nil {
|
||||
t.Fatalf("login() error = %v", err)
|
||||
}
|
||||
if creditedBalance != 6 {
|
||||
t.Fatalf("credited balance = %v, want 6", creditedBalance)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoginStopsWhenRemoteBalanceCannotBeRead(t *testing.T) {
|
||||
expectedErr := errors.New("remote unavailable")
|
||||
accessCalled := false
|
||||
deps := loginDependencies{
|
||||
findUser: func(uint64) (*usermod.User, error) {
|
||||
return &usermod.User{
|
||||
ID: primitive.NewObjectID(),
|
||||
UID: 1,
|
||||
AiMateUid: "existing-ai-mate-uid",
|
||||
}, nil
|
||||
},
|
||||
getWallet: func(uint64) (*walletmod.Wallet, error) {
|
||||
return &walletmod.Wallet{AiMateBalance: 10}, nil
|
||||
},
|
||||
getRemoteBalance: func(uint64, string) (float64, error) {
|
||||
return 0, expectedErr
|
||||
},
|
||||
getAccessURL: func(uint64, string, string, float64) (string, error) {
|
||||
accessCalled = true
|
||||
return "", nil
|
||||
},
|
||||
}
|
||||
|
||||
if _, err := login(1, deps); !errors.Is(err, expectedErr) {
|
||||
t.Fatalf("login() error = %v, want %v", err, expectedErr)
|
||||
}
|
||||
if accessCalled {
|
||||
t.Fatal("access URL must not be requested when the remote balance is unknown")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBalanceTopUp(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
local float64
|
||||
remote float64
|
||||
want float64
|
||||
}{
|
||||
{name: "new credit", local: 10, remote: 4, want: 6},
|
||||
{name: "already synchronized", local: 10, remote: 10, want: 0},
|
||||
{name: "remote ahead", local: 8, remote: 10, want: 0},
|
||||
{name: "empty", local: 0, remote: 0, want: 0},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
if got := balanceTopUp(test.local, test.remote); got != test.want {
|
||||
t.Fatalf("balanceTopUp(%v, %v) = %v, want %v", test.local, test.remote, got, test.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user