first commit
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"secunda-test/internal/domain"
|
||||
)
|
||||
|
||||
func TestTaskServiceCreateRequiresTeamMembership(t *testing.T) {
|
||||
svc := NewTaskService(&fakeTaskRepo{}, &fakeTeamRepo{members: map[int64]map[int64]domain.Role{}}, noopCache{})
|
||||
_, err := svc.Create(context.Background(), 10, domain.Task{TeamID: 1, Title: "task"})
|
||||
if !errors.Is(err, ErrForbidden) {
|
||||
t.Fatalf("expected forbidden, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTaskServiceRejectsAssigneeOutsideTeam(t *testing.T) {
|
||||
teams := &fakeTeamRepo{members: map[int64]map[int64]domain.Role{1: {10: domain.RoleMember}}}
|
||||
svc := NewTaskService(&fakeTaskRepo{}, teams, noopCache{})
|
||||
assigneeID := int64(20)
|
||||
_, err := svc.Create(context.Background(), 10, domain.Task{TeamID: 1, Title: "task", AssigneeID: &assigneeID})
|
||||
if !errors.Is(err, ErrBadRequest) {
|
||||
t.Fatalf("expected bad request, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTaskServiceMemberCanUpdateAssignedTask(t *testing.T) {
|
||||
assigneeID := int64(10)
|
||||
repo := &fakeTaskRepo{task: domain.Task{ID: 7, TeamID: 1, Title: "old", Status: domain.StatusTodo, AssigneeID: &assigneeID, CreatedBy: 99}}
|
||||
teams := &fakeTeamRepo{members: map[int64]map[int64]domain.Role{1: {10: domain.RoleMember}}}
|
||||
svc := NewTaskService(repo, teams, noopCache{})
|
||||
updated, err := svc.Update(context.Background(), 10, 7, domain.Task{Title: "new", Status: domain.StatusDone})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if updated.Title != "new" || updated.Status != domain.StatusDone {
|
||||
t.Fatalf("unexpected task: %+v", updated)
|
||||
}
|
||||
}
|
||||
|
||||
type fakeTaskRepo struct {
|
||||
task domain.Task
|
||||
}
|
||||
|
||||
func (r *fakeTaskRepo) Create(ctx context.Context, task domain.Task) (domain.Task, error) {
|
||||
task.ID = 1
|
||||
r.task = task
|
||||
return task, nil
|
||||
}
|
||||
|
||||
func (r *fakeTaskRepo) Get(ctx context.Context, id int64) (domain.Task, error) {
|
||||
if r.task.ID == 0 {
|
||||
return domain.Task{}, ErrNotFound
|
||||
}
|
||||
return r.task, nil
|
||||
}
|
||||
|
||||
func (r *fakeTaskRepo) Update(ctx context.Context, task domain.Task, changedBy int64) (domain.Task, error) {
|
||||
r.task = task
|
||||
return task, nil
|
||||
}
|
||||
|
||||
func (r *fakeTaskRepo) List(ctx context.Context, filter domain.TaskFilter) ([]domain.Task, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (r *fakeTaskRepo) History(ctx context.Context, taskID int64) ([]domain.TaskHistory, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (r *fakeTaskRepo) TeamSummary(ctx context.Context) ([]domain.TeamSummary, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (r *fakeTaskRepo) TopCreators(ctx context.Context) ([]domain.TopCreator, error) { return nil, nil }
|
||||
func (r *fakeTaskRepo) InvalidAssignees(ctx context.Context) ([]domain.Task, error) { return nil, nil }
|
||||
|
||||
type fakeTeamRepo struct {
|
||||
members map[int64]map[int64]domain.Role
|
||||
}
|
||||
|
||||
func (r *fakeTeamRepo) Create(ctx context.Context, name string, createdBy int64) (domain.Team, error) {
|
||||
return domain.Team{ID: 1, Name: name, CreatedBy: createdBy}, nil
|
||||
}
|
||||
|
||||
func (r *fakeTeamRepo) AddMember(ctx context.Context, teamID, userID int64, role domain.Role) error {
|
||||
if r.members == nil {
|
||||
r.members = map[int64]map[int64]domain.Role{}
|
||||
}
|
||||
if r.members[teamID] == nil {
|
||||
r.members[teamID] = map[int64]domain.Role{}
|
||||
}
|
||||
r.members[teamID][userID] = role
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *fakeTeamRepo) ListByUser(ctx context.Context, userID int64) ([]domain.Team, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (r *fakeTeamRepo) MemberRole(ctx context.Context, teamID, userID int64) (domain.Role, bool, error) {
|
||||
role, ok := r.members[teamID][userID]
|
||||
return role, ok, nil
|
||||
}
|
||||
|
||||
type noopCache struct{}
|
||||
|
||||
func (noopCache) GetTasks(ctx context.Context, filter domain.TaskFilter) ([]domain.Task, bool, error) {
|
||||
return nil, false, nil
|
||||
}
|
||||
|
||||
func (noopCache) SetTasks(ctx context.Context, filter domain.TaskFilter, tasks []domain.Task) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (noopCache) DeleteTeam(ctx context.Context, teamID int64) error { return nil }
|
||||
Reference in New Issue
Block a user