init push

This commit is contained in:
2026-07-16 22:16:45 +07:00
commit 8b068bdb10
1021 changed files with 332816 additions and 0 deletions

View File

@@ -0,0 +1,142 @@
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)
}
}