From 3616afd22a36b437e9dac58e06471963f038aa8b Mon Sep 17 00:00:00 2001 From: Mitja Z Date: Sun, 25 Nov 2018 15:55:44 +0100 Subject: [PATCH] add(system): Team.FindByMemberID (#3) * add(system): Team.FindByMemberID * add(system): Users.Find with Team data * upd(system): error formating --- system/repository/organisation_test.go | 14 +++---- system/repository/team.go | 33 +++++++++++++++- system/repository/team_test.go | 34 ++++++++++------ system/repository/user.go | 38 +++++++++++++++++- system/repository/user_test.go | 55 ++++++++++++++++++++++++++ system/types/team_members.go | 2 +- system/types/user.go | 2 + 7 files changed, 155 insertions(+), 23 deletions(-) create mode 100644 system/repository/user_test.go diff --git a/system/repository/organisation_test.go b/system/repository/organisation_test.go index 53e8d1f7e..c76f34a67 100644 --- a/system/repository/organisation_test.go +++ b/system/repository/organisation_test.go @@ -23,7 +23,7 @@ func TestOrganisation(t *testing.T) { { oa, err := rpo.CreateOrganisation(org) - assert(t, err == nil, "CreateOrganisation error: %v", err) + assert(t, err == nil, "CreateOrganisation error: %+v", err) assert(t, oa.Name == org.Name, "Changes were not stored") } @@ -31,34 +31,34 @@ func TestOrganisation(t *testing.T) { org.Name = "Test organisation v2" oa, err := rpo.UpdateOrganisation(org) - assert(t, err == nil, "UpdateOrganisation error: %v", err) + assert(t, err == nil, "UpdateOrganisation error: %+v", err) assert(t, oa.Name == org.Name, "Changes were not stored") } { oa, err := rpo.FindOrganisationByID(org.ID) - assert(t, err == nil, "FindOrganisationByID error: %v", err) + assert(t, err == nil, "FindOrganisationByID error: %+v", err) assert(t, oa.Name == org.Name, "Changes were not stored") } { oa, err := rpo.FindOrganisations(&types.OrganisationFilter{Query: org.Name}) - assert(t, err == nil, "FindOrganisations error: %v", err) + assert(t, err == nil, "FindOrganisations error: %+v", err) assert(t, len(oa) != 0, "No results found") } { err := rpo.ArchiveOrganisationByID(org.ID) - assert(t, err == nil, "ArchiveOrganisationByID error: %v", err) + assert(t, err == nil, "ArchiveOrganisationByID error: %+v", err) } { err := rpo.UnarchiveOrganisationByID(org.ID) - assert(t, err == nil, "UnarchiveOrganisationByID error: %v", err) + assert(t, err == nil, "UnarchiveOrganisationByID error: %+v", err) } { err := rpo.DeleteOrganisationByID(org.ID) - assert(t, err == nil, "DeleteOrganisationByID error: %v", err) + assert(t, err == nil, "DeleteOrganisationByID error: %+v", err) } } diff --git a/system/repository/team.go b/system/repository/team.go index 11923117c..64300a1f4 100644 --- a/system/repository/team.go +++ b/system/repository/team.go @@ -14,14 +14,19 @@ type ( With(ctx context.Context, db *factory.DB) TeamRepository FindByID(id uint64) (*types.Team, error) + FindByMemberID(userID uint64) ([]*types.Team, error) Find(filter *types.TeamFilter) ([]*types.Team, error) + Create(mod *types.Team) (*types.Team, error) Update(mod *types.Team) (*types.Team, error) + ArchiveByID(id uint64) error UnarchiveByID(id uint64) error DeleteByID(id uint64) error + MergeByID(id, targetTeamID uint64) error MoveByID(id, targetOrganisationID uint64) error + MemberAddByID(id, userID uint64) error MemberRemoveByID(id, userID uint64) error } @@ -60,6 +65,30 @@ func (r *team) FindByID(id uint64) (*types.Team, error) { return mod, isFound(r.db().Get(mod, sql, id), mod.ID > 0, ErrTeamNotFound) } +func (r *team) FindByMemberID(userID uint64) ([]*types.Team, error) { + ids := make([]uint64, 0) + params := make([]interface{}, 0) + + sql := "SELECT DISTINCT rel_team FROM " + r.members + " " + sql += "WHERE rel_user = ?" + params = append(params, userID) + + if err := r.db().Select(&ids, sql, params...); err != nil { + return nil, err + } + + rval := make([]*types.Team, 0) + for _, id := range ids { + mod, err := r.FindByID(id) + if err != nil { + return nil, err + } + rval = append(rval, mod) + } + + return rval, nil +} + func (r *team) Find(filter *types.TeamFilter) ([]*types.Team, error) { rval := make([]*types.Team, 0) params := make([]interface{}, 0) @@ -114,7 +143,7 @@ func (r *team) MoveByID(id, targetOrganisationID uint64) error { func (r *team) MemberAddByID(id, userID uint64) error { mod := &types.TeamMember{ TeamID: id, - UserId: userID, + UserID: userID, } return r.db().Replace(r.members, mod) } @@ -122,7 +151,7 @@ func (r *team) MemberAddByID(id, userID uint64) error { func (r *team) MemberRemoveByID(id, userID uint64) error { mod := &types.TeamMember{ TeamID: id, - UserId: userID, + UserID: userID, } return r.db().Delete(r.members, mod, "rel_team", "rel_user") } diff --git a/system/repository/team_test.go b/system/repository/team_test.go index 6ace5a1a9..f192fc18c 100644 --- a/system/repository/team_test.go +++ b/system/repository/team_test.go @@ -25,7 +25,7 @@ func TestTeam(t *testing.T) { { u1, err := userRepo.Create(user) - assert(t, err == nil, "User.Create error: %v", err) + assert(t, err == nil, "User.Create error: %+v", err) assert(t, user.ID == u1.ID, "Changes were not stored") } @@ -36,56 +36,68 @@ func TestTeam(t *testing.T) { { t1, err := teamRepo.Create(team) - assert(t, err == nil, "Team.Create error: %v", err) + assert(t, err == nil, "Team.Create error: %+v", err) assert(t, team.Name == t1.Name, "Changes were not stored") } { team.Name = "Test team v2" t1, err := teamRepo.Update(team) - assert(t, err == nil, "Team.Update error: %v", err) + assert(t, err == nil, "Team.Update error: %+v", err) assert(t, team.Name == t1.Name, "Changes were not stored") } { t1, err := teamRepo.FindByID(team.ID) - assert(t, err == nil, "Team.FindByID error: %v", err) + assert(t, err == nil, "Team.FindByID error: %+v", err) assert(t, team.Name == t1.Name, "Changes were not stored") } { aa, err := teamRepo.Find(&types.TeamFilter{Query: team.Name}) - assert(t, err == nil, "Team.Find error: %v", err) + assert(t, err == nil, "Team.Find error: %+v", err) assert(t, len(aa) > 0, "No results found") } { err := teamRepo.ArchiveByID(team.ID) - assert(t, err == nil, "Team.ArchiveByID error: %v", err) + assert(t, err == nil, "Team.ArchiveByID error: %+v", err) } { err := teamRepo.UnarchiveByID(team.ID) - assert(t, err == nil, "Team.UnarchiveByID error: %v", err) + assert(t, err == nil, "Team.UnarchiveByID error: %+v", err) } { err := teamRepo.MemberAddByID(team.ID, user.ID) - assert(t, err == nil, "Team.MemberAddByID error: %v", err) + assert(t, err == nil, "Team.MemberAddByID error: %+v", err) + } + + { + teams, err := teamRepo.FindByMemberID(user.ID) + assert(t, err == nil, "Team.FindByMemberID error: %+v", err) + assert(t, len(teams) > 0, "No results found") + } + + { + teams, err := teamRepo.FindByMemberID(0) + assert(t, err == nil, "Team.FindByMemberID error: %+v", err) + assert(t, len(teams) == 0, "Results found") } { err := teamRepo.MemberRemoveByID(team.ID, user.ID) - assert(t, err == nil, "Team.MemberRemoveByID error: %v", err) + assert(t, err == nil, "Team.MemberRemoveByID error: %+v", err) } { err := teamRepo.DeleteByID(team.ID) - assert(t, err == nil, "Team.DeleteByID error: %v", err) + assert(t, err == nil, "Team.DeleteByID error: %+v", err) } { err := userRepo.DeleteByID(user.ID) - assert(t, err == nil, "User.DeleteByID error: %v", err) + assert(t, err == nil, "User.DeleteByID error: %+v", err) } } diff --git a/system/repository/user.go b/system/repository/user.go index c5951b962..d2a813852 100644 --- a/system/repository/user.go +++ b/system/repository/user.go @@ -5,8 +5,9 @@ import ( "fmt" "time" - "github.com/crusttech/crust/system/types" "github.com/titpetric/factory" + + "github.com/crusttech/crust/system/types" ) type ( @@ -98,7 +99,14 @@ func (r *user) Find(filter *types.UserFilter) ([]*types.User, error) { sql += " ORDER BY username ASC" - return rval, r.db().Select(&rval, sql, params...) + if err := r.db().Select(&rval, sql, params...); err != nil { + return nil, err + } + if err := r.prepareAll(rval, "teams"); err != nil { + return nil, err + } + + return rval, nil } func (r *user) Create(mod *types.User) (*types.User, error) { @@ -123,3 +131,29 @@ func (r *user) UnsuspendByID(id uint64) error { func (r *user) DeleteByID(id uint64) error { return r.updateColumnByID(r.users, "deleted_at", time.Now(), id) } + +func (r *user) prepareAll(users []*types.User, fields ...string) error { + for _, user := range users { + if err := r.prepare(user, fields...); err != nil { + return err + } + } + return nil +} + +func (r *user) prepare(user *types.User, fields ...string) (err error) { + api := Team(r.Context(), r.db()) + for _, field := range fields { + switch field { + case "teams": + if user.ID > 0 { + teams, err := api.FindByMemberID(user.ID) + if err != nil { + return err + } + user.Teams = teams + } + } + } + return +} diff --git a/system/repository/user_test.go b/system/repository/user_test.go new file mode 100644 index 000000000..fa9cee2c6 --- /dev/null +++ b/system/repository/user_test.go @@ -0,0 +1,55 @@ +package repository + +import ( + "context" + + "github.com/titpetric/factory" + + "testing" + + "github.com/crusttech/crust/system/types" +) + +func TestUser(t *testing.T) { + if testing.Short() { + t.Skip("skipping test in short mode.") + return + } + + userRepo := User(context.Background(), factory.Database.MustGet()) + user := &types.User{ + Name: "John Doe", + Username: "johndoe", + SatosaID: "1234", + } + user.GeneratePassword("johndoe") + + { + u1, err := userRepo.Create(user) + assert(t, err == nil, "User.Create error: %+v", err) + assert(t, user.ID == u1.ID, "Changes were not stored") + } + + teamRepo := Team(context.Background(), factory.Database.MustGet()) + team := &types.Team{ + Name: "Test team v1", + } + + { + t1, err := teamRepo.Create(team) + assert(t, err == nil, "Team.Create error: %+v", err) + assert(t, team.Name == t1.Name, "Changes were not stored") + } + + { + err := teamRepo.MemberAddByID(team.ID, user.ID) + assert(t, err == nil, "Team.MemberAddByID error: %+v", err) + } + + { + users, err := userRepo.Find(&types.UserFilter{Query: ""}) + assert(t, err == nil, "User.Find error: %+v", err) + assert(t, len(users) > 0, "No user results found") + assert(t, len(users[0].Teams) > 0, "No team results found") + } +} diff --git a/system/types/team_members.go b/system/types/team_members.go index a2ef53aec..f8fba2793 100644 --- a/system/types/team_members.go +++ b/system/types/team_members.go @@ -3,7 +3,7 @@ package types type ( TeamMember struct { TeamID uint64 `db:"rel_team"` - UserId uint64 `db:"rel_user"` + UserID uint64 `db:"rel_user"` } TeamMemberFilter struct { diff --git a/system/types/user.go b/system/types/user.go index c71852b23..394a2dd78 100644 --- a/system/types/user.go +++ b/system/types/user.go @@ -28,6 +28,8 @@ type ( UpdatedAt *time.Time `json:"updatedAt,omitempty" db:"updated_at"` SuspendedAt *time.Time `json:"suspendedAt,omitempty" db:"suspended_at"` DeletedAt *time.Time `json:"deletedAt,omitempty" db:"deleted_at"` + + Teams []*Team `json:"page,omitempty"` } UserFilter struct {