package tests
import (
"context"
"encoding/base64"
"fmt"
"strings"
"time"
"github.com/navidrome/navidrome/model"
)
func CreateMockUserRepo() *MockedUserRepo {
return &MockedUserRepo{
Data: map[string]*model.User{},
UserLibraries: map[string][]int{},
}
}
type MockedUserRepo struct {
model.UserRepository
Error error
Data map[string]*model.User
UserLibraries map[string][]int
}
func (u *MockedUserRepo) CountAll(_ context.Context, qo ...model.QueryOptions) (int64, error) {
if u.Error != nil {
return 0, u.Error
}
return int64(len(u.Data)), nil
}
func (u *MockedUserRepo) Put(_ context.Context, usr *model.User) error {
if u.Error != nil {
return u.Error
}
if usr.ID == "" {
usr.ID = base64.StdEncoding.EncodeToString([]byte(usr.UserName))
}
usr.Password = usr.NewPassword
u.Data[strings.ToLower(usr.UserName)] = usr
return nil
}
func (u *MockedUserRepo) FindByUsername(_ context.Context, username string) (*model.User, error) {
if u.Error != nil {
return nil, u.Error
}
usr, ok := u.Data[strings.ToLower(username)]
if !ok {
return nil, model.ErrNotFound
}
return usr, nil
}
func (u *MockedUserRepo) FindByUsernameWithPassword(ctx context.Context, username string) (*model.User, error) {
return u.FindByUsername(ctx, username)
}
func (u *MockedUserRepo) FindFirstAdmin(_ context.Context) (*model.User, error) {
if u.Error != nil {
return nil, u.Error
}
for _, usr := range u.Data {
if usr.IsAdmin {
return usr, nil
}
}
return nil, model.ErrNotFound
}
func (u *MockedUserRepo) Get(_ context.Context, id string) (*model.User, error) {
if u.Error != nil {
return nil, u.Error
}
for _, usr := range u.Data {
if usr.ID == id {
return usr, nil
}
}
return nil, model.ErrNotFound
}
func (u *MockedUserRepo) GetAll(_ context.Context, options ...model.QueryOptions) (model.Users, error) {
if u.Error != nil {
return nil, u.Error
}
var users model.Users
for _, usr := range u.Data {
users = append(users, *usr)
}
return users, nil
}
func (u *MockedUserRepo) UpdateLastLoginAt(_ context.Context, id string) error {
for _, usr := range u.Data {
if usr.ID == id {
usr.LastLoginAt = new(time.Now())
return nil
}
}
return u.Error
}
func (u *MockedUserRepo) UpdateLastAccessAt(_ context.Context, id string) error {
for _, usr := range u.Data {
if usr.ID == id {
usr.LastAccessAt = new(time.Now())
return nil
}
}
return u.Error
}
func (u *MockedUserRepo) GetUserLibraries(_ context.Context, userID string) (model.Libraries, error) {
if u.Error != nil {
return nil, u.Error
}
libraryIDs, exists := u.UserLibraries[userID]
if !exists {
return model.Libraries{}, nil
}
var libraries model.Libraries
for _, id := range libraryIDs {
libraries = append(libraries, model.Library{
ID: id,
Name: fmt.Sprintf("Test Library %d", id),
Path: fmt.Sprintf("/music/library%d", id),
})
}
return libraries, nil
}
func (u *MockedUserRepo) SetUserLibraries(_ context.Context, userID string, libraryIDs []int) error {
if u.Error != nil {
return u.Error
}
if u.UserLibraries == nil {
u.UserLibraries = make(map[string][]int)
}
u.UserLibraries[userID] = libraryIDs
return nil
}
func (u *MockedUserRepo) Delete(_ context.Context, ids ...string) error {
if u.Error != nil {
return u.Error
}
for _, id := range ids {
if err := u.deleteOne(id); err != nil {
return err
}
}
return nil
}
func (u *MockedUserRepo) deleteOne(id string) error {
for key, usr := range u.Data {
if usr.ID == id {
delete(u.Data, key)
delete(u.UserLibraries, id)
return nil
}
}
return model.ErrNotFound
}
func (u *MockedUserRepo) Save(ctx context.Context, usr *model.User) (string, error) {
if err := u.Put(ctx, usr); err != nil {
return "", err
}
return usr.ID, nil
}
func (u *MockedUserRepo) Update(ctx context.Context, id string, entity model.User, _ ...string) error {
if u.Error != nil {
return u.Error
}
entity.ID = id
return u.Put(ctx, &entity)
}