package service import ( "context" "errors" "testing" "wucher/internal/domain/user" ) type userRepoMock struct { createErr error updateErr error deleteErr error getByIDErr error getByEmailErr error getByUsernameErr error listErr error gotCreate *user.User gotUpdate *user.User gotDelete []byte gotGetByID []byte gotGetByEmail string gotGetByUsername string gotListFilter string gotListSort string gotListLimit int gotListOffset int retByID *user.User retByEmail *user.User retByUsername *user.User retList []user.User retTotal int64 } func (m *userRepoMock) Create(_ context.Context, u *user.User) error { m.gotCreate = u return m.createErr } func (m *userRepoMock) Update(_ context.Context, u *user.User) error { m.gotUpdate = u return m.updateErr } func (m *userRepoMock) Delete(_ context.Context, id []byte) error { m.gotDelete = id return m.deleteErr } func (m *userRepoMock) GetByID(_ context.Context, id []byte) (*user.User, error) { m.gotGetByID = id return m.retByID, m.getByIDErr } func (m *userRepoMock) GetByEmail(_ context.Context, email string) (*user.User, error) { m.gotGetByEmail = email return m.retByEmail, m.getByEmailErr } func (m *userRepoMock) GetByUsername(_ context.Context, username string) (*user.User, error) { m.gotGetByUsername = username return m.retByUsername, m.getByUsernameErr } func (m *userRepoMock) List(_ context.Context, filter, sort string, limit, offset int) ([]user.User, int64, error) { m.gotListFilter = filter m.gotListSort = sort m.gotListLimit = limit m.gotListOffset = offset return m.retList, m.retTotal, m.listErr } func (m *userRepoMock) GetLastNameByID(_ context.Context, _ []byte) (string, error) { return "", nil } func TestUserService_CRUDAndGet(t *testing.T) { repo := &userRepoMock{} svc := NewUserService(repo) u := &user.User{Email: "u@e.com"} if err := svc.Create(context.Background(), u); err != nil { t.Fatalf("create: %v", err) } if repo.gotCreate != u { t.Fatalf("expected create arg passed") } if err := svc.Update(context.Background(), u); err != nil { t.Fatalf("update: %v", err) } if repo.gotUpdate != u { t.Fatalf("expected update arg passed") } id := []byte("id") if err := svc.Delete(context.Background(), id); err != nil { t.Fatalf("delete: %v", err) } if string(repo.gotDelete) != string(id) { t.Fatalf("expected delete id passed") } repo.retByID = u got, err := svc.GetByID(context.Background(), id) if err != nil || got != u { t.Fatalf("getByID failed") } repo.retByEmail = u got, err = svc.GetByEmail(context.Background(), "u@e.com") if err != nil || got != u { t.Fatalf("getByEmail failed") } repo.retByUsername = u got, err = svc.GetByUsername(context.Background(), "john") if err != nil || got != u { t.Fatalf("getByUsername failed") } } func TestUserService_RepoErrors(t *testing.T) { repo := &userRepoMock{ createErr: errors.New("e"), updateErr: errors.New("e"), deleteErr: errors.New("e"), getByIDErr: errors.New("e"), getByEmailErr: errors.New("e"), getByUsernameErr: errors.New("e"), listErr: errors.New("e"), } svc := NewUserService(repo) if svc.Create(context.Background(), &user.User{}) == nil { t.Fatalf("expected create err") } if svc.Update(context.Background(), &user.User{}) == nil { t.Fatalf("expected update err") } if svc.Delete(context.Background(), []byte("id")) == nil { t.Fatalf("expected delete err") } if _, err := svc.GetByID(context.Background(), []byte("id")); err == nil { t.Fatalf("expected getByID err") } if _, err := svc.GetByEmail(context.Background(), "u@e.com"); err == nil { t.Fatalf("expected getByEmail err") } if _, err := svc.GetByUsername(context.Background(), "john"); err == nil { t.Fatalf("expected getByUsername err") } if _, _, err := svc.List(context.Background(), "", "", 1, 0); err == nil { t.Fatalf("expected list err") } } func TestUserService_ListAndNormalizeSort(t *testing.T) { repo := &userRepoMock{retList: []user.User{{Email: "u@e.com"}}, retTotal: 1} svc := NewUserService(repo) _, _, err := svc.List(context.Background(), "u", "-email", 10, 20) if err != nil { t.Fatalf("list: %v", err) } if repo.gotListSort != "users.email DESC" { t.Fatalf("unexpected sort: %s", repo.gotListSort) } cases := map[string]string{ "email": "users.email ASC", "-email": "users.email DESC", "first_name": "users.first_name ASC", "-first_name": "users.first_name DESC", "last_name": "users.last_name ASC", "-last_name": "users.last_name DESC", "created_at": "users.created_at ASC", "-created_at": "users.created_at DESC", "updated_at": "users.updated_at ASC", "-updated_at": "users.updated_at DESC", "bad": "", "": "", } for in, want := range cases { if got := normalizeUserSort(in); got != want { t.Fatalf("normalizeUserSort(%q)=%q want %q", in, got, want) } } }