143 lines
4.3 KiB
Go
143 lines
4.3 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"testing"
|
|
|
|
otherperson "wucher/internal/domain/other_person"
|
|
"wucher/internal/shared/pkg/uuidv7"
|
|
)
|
|
|
|
type fakeOtherPersonRepo struct {
|
|
byID map[string]*otherperson.OtherPerson
|
|
identity map[string]*otherperson.OtherPerson // key: name|phone|email
|
|
created *otherperson.OtherPerson
|
|
updated *otherperson.OtherPerson
|
|
deletedID []byte
|
|
forceError error
|
|
}
|
|
|
|
func newFakeOtherPersonRepo() *fakeOtherPersonRepo {
|
|
return &fakeOtherPersonRepo{
|
|
byID: map[string]*otherperson.OtherPerson{},
|
|
identity: map[string]*otherperson.OtherPerson{},
|
|
}
|
|
}
|
|
|
|
func identityKey(name, phone, email string) string { return name + "|" + phone + "|" + email }
|
|
|
|
func (r *fakeOtherPersonRepo) Upsert(context.Context, *otherperson.OtherPerson) error { return nil }
|
|
|
|
func (r *fakeOtherPersonRepo) Create(_ context.Context, p *otherperson.OtherPerson) error {
|
|
if r.forceError != nil {
|
|
return r.forceError
|
|
}
|
|
if len(p.ID) == 0 {
|
|
p.ID = uuidv7.MustBytes()
|
|
}
|
|
r.created = p
|
|
cp := *p
|
|
r.byID[string(p.ID)] = &cp
|
|
r.identity[identityKey(p.Name, p.MobilePhone, p.Email)] = &cp
|
|
return nil
|
|
}
|
|
|
|
func (r *fakeOtherPersonRepo) Update(_ context.Context, p *otherperson.OtherPerson) error {
|
|
if r.forceError != nil {
|
|
return r.forceError
|
|
}
|
|
r.updated = p
|
|
cp := *p
|
|
r.byID[string(p.ID)] = &cp
|
|
return nil
|
|
}
|
|
|
|
func (r *fakeOtherPersonRepo) Delete(_ context.Context, id, _ []byte) error {
|
|
if r.forceError != nil {
|
|
return r.forceError
|
|
}
|
|
r.deletedID = id
|
|
delete(r.byID, string(id))
|
|
return nil
|
|
}
|
|
|
|
func (r *fakeOtherPersonRepo) GetByID(_ context.Context, id []byte) (*otherperson.OtherPerson, error) {
|
|
return r.byID[string(id)], nil
|
|
}
|
|
|
|
func (r *fakeOtherPersonRepo) FindByIdentity(_ context.Context, name, phone, email string) (*otherperson.OtherPerson, error) {
|
|
return r.identity[identityKey(name, phone, email)], nil
|
|
}
|
|
|
|
func (r *fakeOtherPersonRepo) Search(context.Context, string, int, int) ([]otherperson.OtherPerson, int64, error) {
|
|
return nil, 0, nil
|
|
}
|
|
|
|
func TestOtherPersonServiceCreate(t *testing.T) {
|
|
repo := newFakeOtherPersonRepo()
|
|
svc := NewOtherPersonService(repo)
|
|
ctx := context.Background()
|
|
|
|
// Name required.
|
|
if err := svc.Create(ctx, &otherperson.OtherPerson{Name: " "}); !errors.Is(err, otherperson.ErrNameRequired) {
|
|
t.Fatalf("expected ErrNameRequired, got %v", err)
|
|
}
|
|
|
|
// Happy path.
|
|
p := &otherperson.OtherPerson{Name: "Guest", MobilePhone: "1", Email: "g@x.io"}
|
|
if err := svc.Create(ctx, p); err != nil {
|
|
t.Fatalf("create: %v", err)
|
|
}
|
|
if len(p.ID) == 0 || repo.created == nil {
|
|
t.Fatalf("expected create persisted")
|
|
}
|
|
|
|
// Duplicate identity rejected.
|
|
dup := &otherperson.OtherPerson{Name: "Guest", MobilePhone: "1", Email: "g@x.io"}
|
|
if err := svc.Create(ctx, dup); !errors.Is(err, otherperson.ErrDuplicate) {
|
|
t.Fatalf("expected ErrDuplicate, got %v", err)
|
|
}
|
|
}
|
|
|
|
func TestOtherPersonServiceUpdate(t *testing.T) {
|
|
repo := newFakeOtherPersonRepo()
|
|
svc := NewOtherPersonService(repo)
|
|
ctx := context.Background()
|
|
|
|
// Seed two rows.
|
|
a := &otherperson.OtherPerson{Name: "Alpha", MobilePhone: "1", Email: "a@x.io"}
|
|
b := &otherperson.OtherPerson{Name: "Beta", MobilePhone: "2", Email: "b@x.io"}
|
|
_ = svc.Create(ctx, a)
|
|
_ = svc.Create(ctx, b)
|
|
|
|
// Updating a missing id -> not found.
|
|
missing := &otherperson.OtherPerson{ID: uuidv7.MustBytes(), Name: "X"}
|
|
if err := svc.Update(ctx, missing); !errors.Is(err, otherperson.ErrNotFound) {
|
|
t.Fatalf("expected ErrNotFound, got %v", err)
|
|
}
|
|
|
|
// Updating A to B's identity -> duplicate.
|
|
clash := &otherperson.OtherPerson{ID: a.ID, Name: "Beta", MobilePhone: "2", Email: "b@x.io"}
|
|
if err := svc.Update(ctx, clash); !errors.Is(err, otherperson.ErrDuplicate) {
|
|
t.Fatalf("expected ErrDuplicate, got %v", err)
|
|
}
|
|
|
|
// Updating A to a fresh identity -> ok.
|
|
ok := &otherperson.OtherPerson{ID: a.ID, Name: "Alpha2", MobilePhone: "1", Email: "a@x.io"}
|
|
if err := svc.Update(ctx, ok); err != nil {
|
|
t.Fatalf("expected update ok, got %v", err)
|
|
}
|
|
if repo.updated == nil || repo.updated.Name != "Alpha2" {
|
|
t.Fatalf("update not forwarded")
|
|
}
|
|
}
|
|
|
|
func TestOtherPersonServiceDeleteNotFound(t *testing.T) {
|
|
repo := newFakeOtherPersonRepo()
|
|
svc := NewOtherPersonService(repo)
|
|
if err := svc.Delete(context.Background(), uuidv7.MustBytes(), nil); !errors.Is(err, otherperson.ErrNotFound) {
|
|
t.Fatalf("expected ErrNotFound, got %v", err)
|
|
}
|
|
}
|