From a2412492da2def90457a2a20fd043bea21ef415f Mon Sep 17 00:00:00 2001 From: Ethan Koenig Date: Tue, 24 Jan 2017 11:16:36 -0500 Subject: [PATCH] Unit tests and bug fix for models/org --- models/access_test.go | 2 +- models/fixtures/org_user.yml | 24 ++ models/fixtures/repository.yml | 12 + models/fixtures/team.yml | 28 ++ models/fixtures/team_repo.yml | 12 + models/fixtures/team_user.yml | 24 ++ models/fixtures/user.yml | 38 ++- models/org.go | 30 +- models/org_test.go | 520 +++++++++++++++++++++++++++++++++ models/setup_for_test.go | 7 + 10 files changed, 671 insertions(+), 26 deletions(-) create mode 100644 models/org_test.go diff --git a/models/access_test.go b/models/access_test.go index e06db5607b..6b3cce502c 100644 --- a/models/access_test.go +++ b/models/access_test.go @@ -106,7 +106,7 @@ func TestRepository_RecalculateAccesses(t *testing.T) { has, err := x.Get(access) assert.NoError(t, err) assert.True(t, has) - assert.Equal(t, AccessModeWrite, access.Mode) + assert.Equal(t, AccessModeOwner, access.Mode) } func TestRepository_RecalculateAccesses2(t *testing.T) { diff --git a/models/fixtures/org_user.yml b/models/fixtures/org_user.yml index b4df3c0127..a7b8d178aa 100644 --- a/models/fixtures/org_user.yml +++ b/models/fixtures/org_user.yml @@ -5,3 +5,27 @@ is_public: true is_owner: true num_teams: 1 + +- + id: 2 + uid: 4 + org_id: 3 + is_public: false + is_owner: false + num_teams: 0 + +- + id: 3 + uid: 5 + org_id: 6 + is_public: true + is_owner: true + num_teams: 1 + +- + id: 4 + uid: 5 + org_id: 7 + is_public: false + is_owner: true + num_teams: 1 diff --git a/models/fixtures/repository.yml b/models/fixtures/repository.yml index 00b0077283..c415f20732 100644 --- a/models/fixtures/repository.yml +++ b/models/fixtures/repository.yml @@ -41,3 +41,15 @@ num_closed_issues: 0 num_pulls: 0 num_closed_pulls: 0 + +- + id: 5 + owner_id: 3 + lower_name: repo5 + name: repo5 + is_private: true + num_issues: 0 + num_closed_issues: 0 + num_pulls: 0 + num_closed_pulls: 0 + is_mirror: true diff --git a/models/fixtures/team.yml b/models/fixtures/team.yml index 9746f50d81..99e228efeb 100644 --- a/models/fixtures/team.yml +++ b/models/fixtures/team.yml @@ -1,7 +1,35 @@ - id: 1 org_id: 3 + lower_name: owners + name: owners + authorize: 4 # owner + num_repos: 1 + num_members: 1 + +- + id: 2 + org_id: 3 lower_name: team1 name: team1 authorize: 2 # write num_repos: 1 + num_members: 2 + +- + id: 3 + org_id: 6 + lower_name: owners + name: owners + authorize: 4 # owner + num_repos: 0 + num_members: 1 + +- + id: 4 + org_id: 7 + lower_name: owners + name: owners + authorize: 4 # owner + num_repos: 0 + num_members: 1 diff --git a/models/fixtures/team_repo.yml b/models/fixtures/team_repo.yml index b954ae8c10..1f7385e7e9 100644 --- a/models/fixtures/team_repo.yml +++ b/models/fixtures/team_repo.yml @@ -3,3 +3,15 @@ org_id: 3 team_id: 1 repo_id: 3 + +- + id: 2 + org_id: 3 + team_id: 2 + repo_id: 3 + +- + id: 3 + org_id: 3 + team_id: 1 + repo_id: 5 diff --git a/models/fixtures/team_user.yml b/models/fixtures/team_user.yml index e569f9f3d9..955a80e4cd 100644 --- a/models/fixtures/team_user.yml +++ b/models/fixtures/team_user.yml @@ -3,3 +3,27 @@ org_id: 3 team_id: 1 uid: 2 + +- + id: 2 + org_id: 3 + team_id: 2 + uid: 2 + +- + id: 3 + org_id: 3 + team_id: 2 + uid: 4 + +- + id: 4 + org_id: 6 + team_id: 3 + uid: 5 + +- + id: 5 + org_id: 7 + team_id: 4 + uid: 5 diff --git a/models/fixtures/user.yml b/models/fixtures/user.yml index a38b4016e3..aa1d80d6f0 100644 --- a/models/fixtures/user.yml +++ b/models/fixtures/user.yml @@ -38,7 +38,8 @@ is_admin: false avatar: avatar3 avatar_email: user3@example.com - num_repos: 1 + num_repos: 2 + num_members: 2 - id: 4 @@ -47,7 +48,7 @@ full_name: User Four email: user4@example.com passwd: password - type: 1 # individual + type: 0 # individual salt: salt is_admin: false avatar: avatar4 @@ -61,9 +62,40 @@ full_name: User Five email: user5@example.com passwd: password - type: 1 # individual + type: 0 # individual salt: salt is_admin: false avatar: avatar5 avatar_email: user5@example.com num_repos: 1 + allow_create_organization: false + +- + id: 6 + lower_name: user6 + name: user6 + full_name: User Six + email: user6@example.com + passwd: password + type: 1 # organization + salt: salt + is_admin: false + avatar: avatar6 + avatar_email: user6@example.com + num_repos: 0 + num_members: 1 + +- + id: 7 + lower_name: user7 + name: user7 + full_name: User Seven + email: user7@example.com + passwd: password + type: 1 # organization + salt: salt + is_admin: false + avatar: avatar7 + avatar_email: user7@example.com + num_repos: 0 + num_members: 1 diff --git a/models/org.go b/models/org.go index 02f7bc4e7d..9911523b70 100644 --- a/models/org.go +++ b/models/org.go @@ -124,6 +124,7 @@ func CreateOrganization(org, owner *User) (err error) { org.MaxRepoCreation = -1 org.NumTeams = 1 org.NumMembers = 1 + org.Type = UserTypeOrganization sess := x.NewSession() defer sessionRelease(sess) @@ -350,12 +351,6 @@ func GetOrgsByUserID(userID int64, showAll bool) ([]*User, error) { return getOrgsByUserID(sess, userID, showAll) } -// GetOrgsByUserIDDesc returns a list of organizations that the given user ID -// has joined, ordered descending by the given condition. -func GetOrgsByUserIDDesc(userID int64, desc string, showAll bool) ([]*User, error) { - return getOrgsByUserID(x.Desc(desc), userID, showAll) -} - func getOwnedOrgsByUserID(sess *xorm.Session, userID int64) ([]*User, error) { orgs := make([]*User, 0, 10) return orgs, sess. @@ -464,10 +459,6 @@ func RemoveOrgUser(orgID, userID int64) error { return nil } - user, err := GetUserByID(userID) - if err != nil { - return fmt.Errorf("GetUserByID [%d]: %v", userID, err) - } org, err := GetUserByID(orgID) if err != nil { return fmt.Errorf("GetUserByID [%d]: %v", orgID, err) @@ -497,23 +488,23 @@ func RemoveOrgUser(orgID, userID int64) error { } // Delete all repository accesses and unwatch them. - env, err := org.AccessibleReposEnv(user.ID) + env, err := org.AccessibleReposEnv(userID) if err != nil { return fmt.Errorf("AccessibleReposEnv: %v", err) } repoIDs, err := env.RepoIDs(1, org.NumRepos) if err != nil { - return fmt.Errorf("GetUserRepositories [%d]: %v", user.ID, err) + return fmt.Errorf("GetUserRepositories [%d]: %v", userID, err) } for _, repoID := range repoIDs { - if err = watchRepo(sess, user.ID, repoID, false); err != nil { + if err = watchRepo(sess, userID, repoID, false); err != nil { return err } } if len(repoIDs) > 0 { if _, err = sess. - Where("user_id = ?", user.ID). + Where("user_id = ?", userID). In("repo_id", repoIDs). Delete(new(Access)); err != nil { return err @@ -521,12 +512,12 @@ func RemoveOrgUser(orgID, userID int64) error { } // Delete member in his/her teams. - teams, err := getUserTeams(sess, org.ID, user.ID) + teams, err := getUserTeams(sess, org.ID, userID) if err != nil { return err } for _, t := range teams { - if err = removeTeamMember(sess, org.ID, t.ID, user.ID); err != nil { + if err = removeTeamMember(sess, org.ID, t.ID, userID); err != nil { return err } } @@ -542,11 +533,6 @@ func removeOrgRepo(e Engine, orgID, repoID int64) error { return err } -// RemoveOrgRepo removes all team-repository relations of given organization. -func RemoveOrgRepo(orgID, repoID int64) error { - return removeOrgRepo(x, orgID, repoID) -} - func (org *User) getUserTeams(e Engine, userID int64, cols ...string) ([]*Team, error) { teams := make([]*Team, 0, org.NumTeams) return teams, e. @@ -619,7 +605,7 @@ func (env *accessibleReposEnv) CountRepos() (int64, error) { repoCount, err := x. Join("INNER", "team_repo", "`team_repo`.repo_id=`repository`.id"). Where(env.cond()). - GroupBy("`repository`.id"). + Distinct("`repository`.id"). Count(&Repository{}) if err != nil { return 0, fmt.Errorf("count user repositories in organization: %v", err) diff --git a/models/org_test.go b/models/org_test.go new file mode 100644 index 0000000000..bf505b0abb --- /dev/null +++ b/models/org_test.go @@ -0,0 +1,520 @@ +// Copyright 2017 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package models + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestUser_IsOwnedBy(t *testing.T) { + assert.NoError(t, PrepareTestDatabase()) + org := AssertExistsAndLoadBean(t, &User{ID: 3}).(*User) + assert.True(t, org.IsOwnedBy(2)) + assert.False(t, org.IsOwnedBy(1)) + assert.False(t, org.IsOwnedBy(3)) + assert.False(t, org.IsOwnedBy(4)) + + nonOrg := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User) + assert.False(t, nonOrg.IsOwnedBy(2)) + assert.False(t, nonOrg.IsOwnedBy(3)) +} + +func TestUser_IsOrgMember(t *testing.T) { + assert.NoError(t, PrepareTestDatabase()) + org := AssertExistsAndLoadBean(t, &User{ID: 3}).(*User) + assert.True(t, org.IsOrgMember(2)) + assert.True(t, org.IsOrgMember(4)) + assert.False(t, org.IsOrgMember(1)) + assert.False(t, org.IsOrgMember(3)) + + nonOrg := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User) + assert.False(t, nonOrg.IsOrgMember(2)) + assert.False(t, nonOrg.IsOrgMember(3)) +} + +func TestUser_GetTeam(t *testing.T) { + assert.NoError(t, PrepareTestDatabase()) + org := AssertExistsAndLoadBean(t, &User{ID: 3}).(*User) + team, err := org.GetTeam("team1") + assert.NoError(t, err) + assert.Equal(t, org.ID, team.OrgID) + assert.Equal(t, "team1", team.LowerName) + + _, err = org.GetTeam("does not exist") + assert.Equal(t, ErrTeamNotExist, err) + + nonOrg := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User) + _, err = nonOrg.GetTeam("team") + assert.Equal(t, ErrTeamNotExist, err) +} + +func TestUser_GetOwnerTeam(t *testing.T) { + assert.NoError(t, PrepareTestDatabase()) + org := AssertExistsAndLoadBean(t, &User{ID: 3}).(*User) + team, err := org.GetOwnerTeam() + assert.NoError(t, err) + assert.Equal(t, org.ID, team.OrgID) + + nonOrg := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User) + _, err = nonOrg.GetOwnerTeam() + assert.Equal(t, ErrTeamNotExist, err) +} + +func TestUser_GetTeams(t *testing.T) { + assert.NoError(t, PrepareTestDatabase()) + org := AssertExistsAndLoadBean(t, &User{ID: 3}).(*User) + assert.NoError(t, org.GetTeams()) + assert.Len(t, org.Teams, 2) + assert.Equal(t, int64(1), org.Teams[0].ID) + assert.Equal(t, int64(2), org.Teams[1].ID) +} + +func TestUser_GetMembers(t *testing.T) { + assert.NoError(t, PrepareTestDatabase()) + org := AssertExistsAndLoadBean(t, &User{ID: 3}).(*User) + assert.NoError(t, org.GetMembers()) + assert.Len(t, org.Members, 2) + assert.Equal(t, int64(2), org.Members[0].ID) + assert.Equal(t, int64(4), org.Members[1].ID) +} + +func TestUser_AddMember(t *testing.T) { + assert.NoError(t, PrepareTestDatabase()) + org := AssertExistsAndLoadBean(t, &User{ID: 3}).(*User) + + // add a user that is not a member + AssertNotExistsBean(t, &OrgUser{UID: 5, OrgID: 3}) + prevNumMembers := org.NumMembers + assert.NoError(t, org.AddMember(5)) + AssertExistsAndLoadBean(t, &OrgUser{UID: 5, OrgID: 3}) + org = AssertExistsAndLoadBean(t, &User{ID: 3}).(*User) + assert.Equal(t, prevNumMembers+1, org.NumMembers) + + // add a user that is already a member + AssertExistsAndLoadBean(t, &OrgUser{UID: 4, OrgID: 3}) + prevNumMembers = org.NumMembers + assert.NoError(t, org.AddMember(4)) + AssertExistsAndLoadBean(t, &OrgUser{UID: 4, OrgID: 3}) + org = AssertExistsAndLoadBean(t, &User{ID: 3}).(*User) + assert.Equal(t, prevNumMembers, org.NumMembers) +} + +func TestUser_RemoveMember(t *testing.T) { + assert.NoError(t, PrepareTestDatabase()) + org := AssertExistsAndLoadBean(t, &User{ID: 3}).(*User) + + // remove a user that is a member + AssertExistsAndLoadBean(t, &OrgUser{UID: 4, OrgID: 3}) + prevNumMembers := org.NumMembers + assert.NoError(t, org.RemoveMember(4)) + AssertNotExistsBean(t, &OrgUser{UID: 4, OrgID: 3}) + org = AssertExistsAndLoadBean(t, &User{ID: 3}).(*User) + assert.Equal(t, prevNumMembers-1, org.NumMembers) + + // remove a user that is not a member + AssertNotExistsBean(t, &OrgUser{UID: 5, OrgID: 3}) + prevNumMembers = org.NumMembers + assert.NoError(t, org.RemoveMember(5)) + AssertNotExistsBean(t, &OrgUser{UID: 5, OrgID: 3}) + org = AssertExistsAndLoadBean(t, &User{ID: 3}).(*User) + assert.Equal(t, prevNumMembers, org.NumMembers) +} + +func TestUser_RemoveOrgRepo(t *testing.T) { + assert.NoError(t, PrepareTestDatabase()) + org := AssertExistsAndLoadBean(t, &User{ID: 3}).(*User) + repo := AssertExistsAndLoadBean(t, &Repository{OwnerID: org.ID}).(*Repository) + + // remove a repo that does belong to org + AssertExistsAndLoadBean(t, &TeamRepo{RepoID: repo.ID, OrgID: org.ID}) + assert.NoError(t, org.RemoveOrgRepo(repo.ID)) + AssertNotExistsBean(t, &TeamRepo{RepoID: repo.ID, OrgID: org.ID}) + AssertExistsAndLoadBean(t, &Repository{ID: repo.ID}) // repo should still exist + + // remove a repo that does not belong to org + assert.NoError(t, org.RemoveOrgRepo(repo.ID)) + AssertNotExistsBean(t, &TeamRepo{RepoID: repo.ID, OrgID: org.ID}) + + assert.NoError(t, org.RemoveOrgRepo(NonexistentID)) +} + +func TestCreateOrganization(t *testing.T) { + // successful creation of org + assert.NoError(t, PrepareTestDatabase()) + + owner := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User) + const newOrgName = "neworg" + org := &User{ + Name: newOrgName, + } + + AssertNotExistsBean(t, &User{Name: newOrgName, Type: UserTypeOrganization}) + assert.NoError(t, CreateOrganization(org, owner)) + org = AssertExistsAndLoadBean(t, + &User{Name: newOrgName, Type: UserTypeOrganization}).(*User) + ownerTeam := AssertExistsAndLoadBean(t, + &Team{Name: ownerTeamName, OrgID: org.ID}).(*Team) + AssertExistsAndLoadBean(t, &TeamUser{UID: owner.ID, TeamID: ownerTeam.ID}) +} + +func TestCreateOrganization2(t *testing.T) { + // unauthorized creation of org + assert.NoError(t, PrepareTestDatabase()) + + owner := AssertExistsAndLoadBean(t, &User{ID: 5}).(*User) + const newOrgName = "neworg" + org := &User{ + Name: newOrgName, + } + + AssertNotExistsBean(t, &User{Name: newOrgName, Type: UserTypeOrganization}) + err := CreateOrganization(org, owner) + assert.Error(t, err) + assert.True(t, IsErrUserNotAllowedCreateOrg(err)) + AssertNotExistsBean(t, &User{Name: newOrgName, Type: UserTypeOrganization}) +} + +func TestCreateOrganization3(t *testing.T) { + // create org with same name as existent org + assert.NoError(t, PrepareTestDatabase()) + + owner := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User) + org := &User{Name: "user3"} // should already exist + AssertExistsAndLoadBean(t, &User{Name: org.Name}) // sanity check + err := CreateOrganization(org, owner) + assert.Error(t, err) + assert.True(t, IsErrUserAlreadyExist(err)) +} + +func TestCreateOrganization4(t *testing.T) { + // create org with unusable name + assert.NoError(t, PrepareTestDatabase()) + + owner := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User) + err := CreateOrganization(&User{Name: "assets"}, owner) + assert.Error(t, err) + assert.True(t, IsErrNameReserved(err)) +} + +func TestGetOrgByName(t *testing.T) { + assert.NoError(t, PrepareTestDatabase()) + + org, err := GetOrgByName("user3") + assert.NoError(t, err) + assert.EqualValues(t, 3, org.ID) + assert.Equal(t, "user3", org.Name) + + org, err = GetOrgByName("user2") // user2 is an individual + assert.Equal(t, ErrOrgNotExist, err) + + org, err = GetOrgByName("") // corner case + assert.Equal(t, ErrOrgNotExist, err) +} + +func TestCountOrganizations(t *testing.T) { + assert.NoError(t, PrepareTestDatabase()) + expected, err := x.Where("type=?", UserTypeOrganization).Count(&User{}) + assert.NoError(t, err) + assert.Equal(t, expected, CountOrganizations()) +} + +func TestOrganizations(t *testing.T) { + assert.NoError(t, PrepareTestDatabase()) + testSuccess := func(opts *SearchUserOptions, expectedOrgIDs []int64) { + orgs, err := Organizations(opts) + assert.NoError(t, err) + assert.Len(t, orgs, len(expectedOrgIDs)) + for i, expectedOrgID := range expectedOrgIDs { + assert.EqualValues(t, expectedOrgID, orgs[i].ID) + } + } + testSuccess(&SearchUserOptions{OrderBy: "id ASC", Page: 1, PageSize: 2}, + []int64{3, 6}) + + testSuccess(&SearchUserOptions{OrderBy: "id ASC", Page: 2, PageSize: 2}, + []int64{7}) + + testSuccess(&SearchUserOptions{Page: 3, PageSize: 2}, + []int64{}) +} + +func TestDeleteOrganization(t *testing.T) { + assert.NoError(t, PrepareTestDatabase()) + org := AssertExistsAndLoadBean(t, &User{ID: 6}).(*User) + assert.NoError(t, DeleteOrganization(org)) + AssertNotExistsBean(t, &User{ID: 6}) + AssertNotExistsBean(t, &OrgUser{OrgID: 6}) + AssertNotExistsBean(t, &Team{OrgID: 6}) + + org = AssertExistsAndLoadBean(t, &User{ID: 3}).(*User) + err := DeleteOrganization(org) + assert.Error(t, err) + assert.True(t, IsErrUserOwnRepos(err)) + + nonOrg := AssertExistsAndLoadBean(t, &User{ID: 5}).(*User) + assert.Error(t, DeleteOrganization(nonOrg)) +} + +func TestIsOrganizationOwner(t *testing.T) { + assert.NoError(t, PrepareTestDatabase()) + assert.True(t, IsOrganizationOwner(3, 2)) + assert.False(t, IsOrganizationOwner(3, 3)) + assert.True(t, IsOrganizationOwner(6, 5)) + assert.False(t, IsOrganizationOwner(6, 4)) + assert.False(t, IsOrganizationOwner(NonexistentID, NonexistentID)) +} + +func TestIsOrganizationMember(t *testing.T) { + assert.NoError(t, PrepareTestDatabase()) + assert.True(t, IsOrganizationMember(3, 2)) + assert.False(t, IsOrganizationMember(3, 3)) + assert.True(t, IsOrganizationMember(3, 4)) + assert.True(t, IsOrganizationMember(6, 5)) + assert.False(t, IsOrganizationMember(6, 4)) + assert.False(t, IsOrganizationMember(NonexistentID, NonexistentID)) +} + +func TestIsPublicMembership(t *testing.T) { + assert.NoError(t, PrepareTestDatabase()) + assert.True(t, IsPublicMembership(3, 2)) + assert.False(t, IsPublicMembership(3, 3)) + assert.False(t, IsPublicMembership(3, 4)) + assert.True(t, IsPublicMembership(6, 5)) + assert.False(t, IsPublicMembership(6, 4)) + assert.False(t, IsPublicMembership(NonexistentID, NonexistentID)) +} + +func TestGetOrgsByUserID(t *testing.T) { + assert.NoError(t, PrepareTestDatabase()) + + orgs, err := GetOrgsByUserID(4, true) + assert.NoError(t, err) + assert.Len(t, orgs, 1) + assert.EqualValues(t, 3, orgs[0].ID) + + orgs, err = GetOrgsByUserID(4, false) + assert.NoError(t, err) + assert.Len(t, orgs, 0) +} + +func TestGetOwnedOrgsByUserID(t *testing.T) { + assert.NoError(t, PrepareTestDatabase()) + + orgs, err := GetOwnedOrgsByUserID(2) + assert.NoError(t, err) + assert.Len(t, orgs, 1) + assert.EqualValues(t, 3, orgs[0].ID) + + orgs, err = GetOwnedOrgsByUserID(4) + assert.NoError(t, err) + assert.Len(t, orgs, 0) +} + +func TestGetOwnedOrgsByUserIDDesc(t *testing.T) { + assert.NoError(t, PrepareTestDatabase()) + + orgs, err := GetOwnedOrgsByUserIDDesc(5, "id") + assert.NoError(t, err) + assert.Len(t, orgs, 2) + assert.EqualValues(t, 7, orgs[0].ID) + assert.EqualValues(t, 6, orgs[1].ID) + + orgs, err = GetOwnedOrgsByUserIDDesc(4, "id") + assert.NoError(t, err) + assert.Len(t, orgs, 0) +} + +func TestGetOrgUsersByUserID(t *testing.T) { + assert.NoError(t, PrepareTestDatabase()) + + orgUsers, err := GetOrgUsersByUserID(5, true) + assert.NoError(t, err) + assert.Len(t, orgUsers, 2) + assert.Equal(t, OrgUser{ + ID: orgUsers[0].ID, + OrgID: 6, + UID: 5, + IsOwner: true, + IsPublic: true, + NumTeams: 1}, *orgUsers[0]) + assert.Equal(t, OrgUser{ + ID: orgUsers[1].ID, + OrgID: 7, + UID: 5, + IsOwner: true, + IsPublic: false, + NumTeams: 1}, *orgUsers[1]) + + publicOrgUsers, err := GetOrgUsersByUserID(5, false) + assert.NoError(t, err) + assert.Len(t, publicOrgUsers, 1) + assert.Equal(t, *orgUsers[0], *publicOrgUsers[0]) + + orgUsers, err = GetOrgUsersByUserID(1, true) + assert.NoError(t, err) + assert.Len(t, orgUsers, 0) +} + +func TestGetOrgUsersByOrgID(t *testing.T) { + assert.NoError(t, PrepareTestDatabase()) + + orgUsers, err := GetOrgUsersByOrgID(3) + assert.NoError(t, err) + assert.Len(t, orgUsers, 2) + assert.Equal(t, OrgUser{ + ID: orgUsers[0].ID, + OrgID: 3, + UID: 2, + IsOwner: true, + IsPublic: true, + NumTeams: 1}, *orgUsers[0]) + assert.Equal(t, OrgUser{ + ID: orgUsers[1].ID, + OrgID: 3, + UID: 4, + IsOwner: false, + IsPublic: false, + NumTeams: 0}, *orgUsers[1]) + + orgUsers, err = GetOrgUsersByOrgID(NonexistentID) + assert.NoError(t, err) + assert.Len(t, orgUsers, 0) +} + +func TestChangeOrgUserStatus(t *testing.T) { + assert.NoError(t, PrepareTestDatabase()) + + testSuccess := func(orgID, userID int64, public bool) { + assert.NoError(t, ChangeOrgUserStatus(orgID, userID, public)) + orgUser := AssertExistsAndLoadBean(t, &OrgUser{OrgID: orgID, UID: userID}).(*OrgUser) + assert.Equal(t, public, orgUser.IsPublic) + } + + testSuccess(3, 2, false) + testSuccess(3, 2, false) + testSuccess(3, 4, true) + assert.NoError(t, ChangeOrgUserStatus(NonexistentID, NonexistentID, true)) +} + +func TestAddOrgUser(t *testing.T) { + assert.NoError(t, PrepareTestDatabase()) + testSuccess := func(orgID, userID int64) { + org := AssertExistsAndLoadBean(t, &User{ID: orgID}).(*User) + expectedNumMembers := org.NumMembers + if !BeanExists(t, &OrgUser{OrgID: orgID, UID: userID}) { + expectedNumMembers++ + } + assert.NoError(t, AddOrgUser(orgID, userID)) + AssertExistsAndLoadBean(t, &OrgUser{OrgID: orgID, UID: userID}) + org = AssertExistsAndLoadBean(t, &User{ID: orgID}).(*User) + assert.EqualValues(t, expectedNumMembers, org.NumMembers) + } + testSuccess(3, 5) + testSuccess(3, 5) + testSuccess(6, 2) +} + +func TestRemoveOrgUser(t *testing.T) { + assert.NoError(t, PrepareTestDatabase()) + testSuccess := func(orgID, userID int64) { + org := AssertExistsAndLoadBean(t, &User{ID: orgID}).(*User) + expectedNumMembers := org.NumMembers + if BeanExists(t, &OrgUser{OrgID: orgID, UID: userID}) { + expectedNumMembers-- + } + assert.NoError(t, RemoveOrgUser(orgID, userID)) + AssertNotExistsBean(t, &OrgUser{OrgID: orgID, UID: userID}) + org = AssertExistsAndLoadBean(t, &User{ID: orgID}).(*User) + assert.EqualValues(t, expectedNumMembers, org.NumMembers) + } + testSuccess(3, 4) + testSuccess(3, 4) + + err := RemoveOrgUser(7, 5) + assert.Error(t, err) + assert.True(t, IsErrLastOrgOwner(err)) + AssertExistsAndLoadBean(t, &OrgUser{OrgID: 7, UID: 5}) +} + +func TestUser_GetUserTeamIDs(t *testing.T) { + assert.NoError(t, PrepareTestDatabase()) + org := AssertExistsAndLoadBean(t, &User{ID: 3}).(*User) + testSuccess := func(userID int64, expected []int64) { + teamIDs, err := org.GetUserTeamIDs(userID) + assert.NoError(t, err) + assert.Equal(t, expected, teamIDs) + } + testSuccess(2, []int64{1, 2}) + testSuccess(4, []int64{2}) + testSuccess(NonexistentID, []int64{}) +} + +func TestAccessibleReposEnv_CountRepos(t *testing.T) { + assert.NoError(t, PrepareTestDatabase()) + org := AssertExistsAndLoadBean(t, &User{ID: 3}).(*User) + testSuccess := func(userID, expectedCount int64) { + env, err := org.AccessibleReposEnv(userID) + assert.NoError(t, err) + count, err := env.CountRepos() + assert.NoError(t, err) + assert.EqualValues(t, expectedCount, count) + } + testSuccess(2, 2) + testSuccess(4, 1) +} + +func TestAccessibleReposEnv_RepoIDs(t *testing.T) { + assert.NoError(t, PrepareTestDatabase()) + org := AssertExistsAndLoadBean(t, &User{ID: 3}).(*User) + testSuccess := func(userID, page, pageSize int64, expectedRepoIDs []int64) { + env, err := org.AccessibleReposEnv(userID) + assert.NoError(t, err) + repoIDs, err := env.RepoIDs(1, 100) + assert.NoError(t, err) + assert.Equal(t, expectedRepoIDs, repoIDs) + } + testSuccess(2, 1, 100, []int64{3, 5}) + testSuccess(4, 0, 100, []int64{3}) +} + +func TestAccessibleReposEnv_Repos(t *testing.T) { + assert.NoError(t, PrepareTestDatabase()) + org := AssertExistsAndLoadBean(t, &User{ID: 3}).(*User) + testSuccess := func(userID int64, expectedRepoIDs []int64) { + env, err := org.AccessibleReposEnv(userID) + assert.NoError(t, err) + repos, err := env.Repos(1, 100) + assert.NoError(t, err) + expectedRepos := make([]*Repository, len(expectedRepoIDs)) + for i, repoID := range expectedRepoIDs { + expectedRepos[i] = AssertExistsAndLoadBean(t, + &Repository{ID: repoID}).(*Repository) + } + assert.Equal(t, expectedRepos, repos) + } + testSuccess(2, []int64{3, 5}) + testSuccess(4, []int64{3}) +} + +func TestAccessibleReposEnv_MirrorRepos(t *testing.T) { + assert.NoError(t, PrepareTestDatabase()) + org := AssertExistsAndLoadBean(t, &User{ID: 3}).(*User) + testSuccess := func(userID int64, expectedRepoIDs []int64) { + env, err := org.AccessibleReposEnv(userID) + assert.NoError(t, err) + repos, err := env.MirrorRepos() + assert.NoError(t, err) + expectedRepos := make([]*Repository, len(expectedRepoIDs)) + for i, repoID := range expectedRepoIDs { + expectedRepos[i] = AssertExistsAndLoadBean(t, + &Repository{ID: repoID}).(*Repository) + } + assert.Equal(t, expectedRepos, repos) + } + testSuccess(2, []int64{5}) + testSuccess(4, []int64{}) +} diff --git a/models/setup_for_test.go b/models/setup_for_test.go index 058436ca66..aec409622b 100644 --- a/models/setup_for_test.go +++ b/models/setup_for_test.go @@ -59,6 +59,13 @@ func loadBeanIfExists(bean interface{}, conditions ...interface{}) (bool, error) return sess.Get(bean) } +// BeanExists for testing, check if a bean exists +func BeanExists(t *testing.T, bean interface{}, conditions ...interface{}) bool { + exists, err := loadBeanIfExists(bean, conditions...) + assert.NoError(t, err) + return exists +} + // AssertExistsAndLoadBean assert that a bean exists and load it from the test // database func AssertExistsAndLoadBean(t *testing.T, bean interface{}, conditions ...interface{}) interface{} {