mirror of
https://github.com/coder/coder.git
synced 2025-07-15 22:20:27 +00:00
test: add unit test to excercise bug when idp sync hits deleted orgs (#17405)
Deleted organizations are still attempting to sync members. This causes an error on inserting the member, and would likely cause issues later in the sync process even if that member is inserted. Deleted orgs should be skipped.
This commit is contained in:
@ -886,7 +886,7 @@ func (s *MethodTestSuite) TestOrganization() {
|
||||
_ = dbgen.OrganizationMember(s.T(), db, database.OrganizationMember{UserID: u.ID, OrganizationID: a.ID})
|
||||
b := dbgen.Organization(s.T(), db, database.Organization{})
|
||||
_ = dbgen.OrganizationMember(s.T(), db, database.OrganizationMember{UserID: u.ID, OrganizationID: b.ID})
|
||||
check.Args(database.GetOrganizationsByUserIDParams{UserID: u.ID, Deleted: false}).Asserts(a, policy.ActionRead, b, policy.ActionRead).Returns(slice.New(a, b))
|
||||
check.Args(database.GetOrganizationsByUserIDParams{UserID: u.ID, Deleted: sql.NullBool{Valid: true, Bool: false}}).Asserts(a, policy.ActionRead, b, policy.ActionRead).Returns(slice.New(a, b))
|
||||
}))
|
||||
s.Run("InsertOrganization", s.Subtest(func(db database.Store, check *expects) {
|
||||
check.Args(database.InsertOrganizationParams{
|
||||
@ -994,8 +994,7 @@ func (s *MethodTestSuite) TestOrganization() {
|
||||
member, policy.ActionRead,
|
||||
member, policy.ActionDelete).
|
||||
WithNotAuthorized("no rows").
|
||||
WithCancelled(cancelledErr).
|
||||
ErrorsWithInMemDB(sql.ErrNoRows)
|
||||
WithCancelled(cancelledErr)
|
||||
}))
|
||||
s.Run("UpdateOrganization", s.Subtest(func(db database.Store, check *expects) {
|
||||
o := dbgen.Organization(s.T(), db, database.Organization{
|
||||
|
@ -17,6 +17,7 @@ type OrganizationBuilder struct {
|
||||
t *testing.T
|
||||
db database.Store
|
||||
seed database.Organization
|
||||
delete bool
|
||||
allUsersAllowance int32
|
||||
members []uuid.UUID
|
||||
groups map[database.Group][]uuid.UUID
|
||||
@ -45,6 +46,12 @@ func (b OrganizationBuilder) EveryoneAllowance(allowance int) OrganizationBuilde
|
||||
return b
|
||||
}
|
||||
|
||||
func (b OrganizationBuilder) Deleted(deleted bool) OrganizationBuilder {
|
||||
//nolint: revive // returns modified struct
|
||||
b.delete = deleted
|
||||
return b
|
||||
}
|
||||
|
||||
func (b OrganizationBuilder) Seed(seed database.Organization) OrganizationBuilder {
|
||||
//nolint: revive // returns modified struct
|
||||
b.seed = seed
|
||||
@ -119,6 +126,17 @@ func (b OrganizationBuilder) Do() OrganizationResponse {
|
||||
}
|
||||
}
|
||||
|
||||
if b.delete {
|
||||
now := dbtime.Now()
|
||||
err = b.db.UpdateOrganizationDeletedByID(ctx, database.UpdateOrganizationDeletedByIDParams{
|
||||
UpdatedAt: now,
|
||||
ID: org.ID,
|
||||
})
|
||||
require.NoError(b.t, err)
|
||||
org.Deleted = true
|
||||
org.UpdatedAt = now
|
||||
}
|
||||
|
||||
return OrganizationResponse{
|
||||
Org: org,
|
||||
AllUsersGroup: everyone,
|
||||
|
@ -2357,10 +2357,13 @@ func (q *FakeQuerier) DeleteOrganizationMember(ctx context.Context, arg database
|
||||
q.mutex.Lock()
|
||||
defer q.mutex.Unlock()
|
||||
|
||||
deleted := slices.DeleteFunc(q.data.organizationMembers, func(member database.OrganizationMember) bool {
|
||||
return member.OrganizationID == arg.OrganizationID && member.UserID == arg.UserID
|
||||
deleted := false
|
||||
q.data.organizationMembers = slices.DeleteFunc(q.data.organizationMembers, func(member database.OrganizationMember) bool {
|
||||
match := member.OrganizationID == arg.OrganizationID && member.UserID == arg.UserID
|
||||
deleted = deleted || match
|
||||
return match
|
||||
})
|
||||
if len(deleted) == 0 {
|
||||
if !deleted {
|
||||
return sql.ErrNoRows
|
||||
}
|
||||
|
||||
@ -4156,6 +4159,9 @@ func (q *FakeQuerier) GetOrganizations(_ context.Context, args database.GetOrgan
|
||||
if args.Name != "" && !strings.EqualFold(org.Name, args.Name) {
|
||||
continue
|
||||
}
|
||||
if args.Deleted != org.Deleted {
|
||||
continue
|
||||
}
|
||||
tmp = append(tmp, org)
|
||||
}
|
||||
|
||||
@ -4172,7 +4178,11 @@ func (q *FakeQuerier) GetOrganizationsByUserID(_ context.Context, arg database.G
|
||||
continue
|
||||
}
|
||||
for _, organization := range q.organizations {
|
||||
if organization.ID != organizationMember.OrganizationID || organization.Deleted != arg.Deleted {
|
||||
if organization.ID != organizationMember.OrganizationID {
|
||||
continue
|
||||
}
|
||||
|
||||
if arg.Deleted.Valid && organization.Deleted != arg.Deleted.Bool {
|
||||
continue
|
||||
}
|
||||
organizations = append(organizations, organization)
|
||||
|
@ -5680,8 +5680,13 @@ SELECT
|
||||
FROM
|
||||
organizations
|
||||
WHERE
|
||||
-- Optionally include deleted organizations
|
||||
deleted = $2 AND
|
||||
-- Optionally provide a filter for deleted organizations.
|
||||
CASE WHEN
|
||||
$2 :: boolean IS NULL THEN
|
||||
true
|
||||
ELSE
|
||||
deleted = $2
|
||||
END AND
|
||||
id = ANY(
|
||||
SELECT
|
||||
organization_id
|
||||
@ -5693,8 +5698,8 @@ WHERE
|
||||
`
|
||||
|
||||
type GetOrganizationsByUserIDParams struct {
|
||||
UserID uuid.UUID `db:"user_id" json:"user_id"`
|
||||
Deleted bool `db:"deleted" json:"deleted"`
|
||||
UserID uuid.UUID `db:"user_id" json:"user_id"`
|
||||
Deleted sql.NullBool `db:"deleted" json:"deleted"`
|
||||
}
|
||||
|
||||
func (q *sqlQuerier) GetOrganizationsByUserID(ctx context.Context, arg GetOrganizationsByUserIDParams) ([]Organization, error) {
|
||||
|
@ -55,8 +55,13 @@ SELECT
|
||||
FROM
|
||||
organizations
|
||||
WHERE
|
||||
-- Optionally include deleted organizations
|
||||
deleted = @deleted AND
|
||||
-- Optionally provide a filter for deleted organizations.
|
||||
CASE WHEN
|
||||
sqlc.narg('deleted') :: boolean IS NULL THEN
|
||||
true
|
||||
ELSE
|
||||
deleted = sqlc.narg('deleted')
|
||||
END AND
|
||||
id = ANY(
|
||||
SELECT
|
||||
organization_id
|
||||
|
Reference in New Issue
Block a user