fixup! fixup! fixup! fixup! feat(db): adding org table to relational model

This commit is contained in:
Iraq Jaber
2025-06-16 14:28:31 +02:00
parent 4a3aaa78bd
commit 88d098e4cf
8 changed files with 775 additions and 42 deletions

View File

@@ -7,16 +7,18 @@ import (
"github.com/zitadel/zitadel/backend/v3/storage/database" "github.com/zitadel/zitadel/backend/v3/storage/database"
) )
var State []string = []string{ type State string
"ACTIVE",
"INACTIVE", const (
} Active State = "ACTIVE"
Inactive State = "INACTIVE"
)
type Organization struct { type Organization struct {
ID string `json:"id,omitempty" db:"id"` ID string `json:"id,omitempty" db:"id"`
Name string `json:"name,omitempty" db:"name"` Name string `json:"name,omitempty" db:"name"`
InstanceID string `json:"instance_id,omitempty" db:"instance_id"` InstanceID string `json:"instance_id,omitempty" db:"instance_id"`
State string `json:"state,omitempty" db:"state"` State State `json:"state,omitempty" db:"state"`
CreatedAt time.Time `json:"created_at,omitempty" db:"created_at"` CreatedAt time.Time `json:"created_at,omitempty" db:"created_at"`
UpdatedAt time.Time `json:"updated_at,omitempty" db:"updated_at"` UpdatedAt time.Time `json:"updated_at,omitempty" db:"updated_at"`
DeletedAt *time.Time `json:"deleted_at,omitempty" db:"deleted_at"` DeletedAt *time.Time `json:"deleted_at,omitempty" db:"deleted_at"`
@@ -52,6 +54,7 @@ type organizationConditions interface {
type organizationChanges interface { type organizationChanges interface {
// SetName sets the name column. // SetName sets the name column.
SetName(name string) database.Change SetName(name string) database.Change
SetState(state State) database.Change
} }
// OrganizationRepository is the interface for the instance repository. // OrganizationRepository is the interface for the instance repository.

View File

@@ -4,9 +4,9 @@ CREATE TYPE zitadel.organization_state AS ENUM (
); );
CREATE TABLE zitadel.organizations( CREATE TABLE zitadel.organizations(
id TEXT NOT NULL PRIMARY KEY, id TEXT NOT NULL CHECK (id <> '') PRIMARY KEY,
name TEXT NOT NULL, name TEXT NOT NULL CHECK (name <> ''),
instance_id TEXT NOT NULL, instance_id TEXT NOT NULL CHECK (instance_id <> ''),
state zitadel.organization_state NOT NULL, state zitadel.organization_state NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW(), created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(), updated_at TIMESTAMPTZ DEFAULT NOW(),

View File

@@ -37,13 +37,11 @@ func TestServer_TestOrganizationAddReduces(t *testing.T) {
) )
require.NoError(t, err) require.NoError(t, err)
activeState := domain.State[0]
// event org.added // event org.added
require.NotNil(t, organization.ID) require.NotNil(t, organization.ID)
require.Equal(t, orgName, organization.Name) require.Equal(t, orgName, organization.Name)
require.NotNil(t, organization.InstanceID) require.NotNil(t, organization.InstanceID)
require.Equal(t, activeState, organization.State) require.Equal(t, domain.Active, organization.State)
assert.WithinRange(t, organization.CreatedAt, beforeCreate, afterCreate) assert.WithinRange(t, organization.CreatedAt, beforeCreate, afterCreate)
assert.WithinRange(t, organization.UpdatedAt, beforeCreate, afterCreate) assert.WithinRange(t, organization.UpdatedAt, beforeCreate, afterCreate)
require.Nil(t, organization.DeletedAt) require.Nil(t, organization.DeletedAt)
@@ -107,11 +105,9 @@ func TestServer_TestOrganizationDeactivateReduces(t *testing.T) {
) )
require.NoError(t, err) require.NoError(t, err)
deactiveState := domain.State[1]
// event org.deactivate // event org.deactivate
require.Equal(t, orgName, organization.Name) require.Equal(t, orgName, organization.Name)
require.Equal(t, deactiveState, organization.State) require.Equal(t, domain.Inactive, organization.State)
assert.WithinRange(t, organization.UpdatedAt, beforeCreate, afterCreate) assert.WithinRange(t, organization.UpdatedAt, beforeCreate, afterCreate)
}, retryDuration, tick) }, retryDuration, tick)
} }
@@ -144,11 +140,9 @@ func TestServer_TestOrganizationActivateReduces(t *testing.T) {
) )
require.NoError(t, err) require.NoError(t, err)
deactiveState := domain.State[1]
// event org.reactivate // event org.reactivate
require.Equal(t, orgName, organization.Name) require.Equal(t, orgName, organization.Name)
require.Equal(t, deactiveState, organization.State) require.Equal(t, domain.Inactive, organization.State)
assert.WithinRange(t, organization.UpdatedAt, beforeCreate, afterCreate) assert.WithinRange(t, organization.UpdatedAt, beforeCreate, afterCreate)
}, retryDuration, tick) }, retryDuration, tick)
} }

View File

@@ -76,16 +76,16 @@ func (i *instance) Create(ctx context.Context, instance *domain.Instance) error
// constraint violation // constraint violation
if pgErr.Code == "23514" { if pgErr.Code == "23514" {
if pgErr.ConstraintName == "instances_name_check" { if pgErr.ConstraintName == "instances_name_check" {
return errors.New("instnace name not provided") return errors.New("instance name not provided")
} }
if pgErr.ConstraintName == "instances_id_check" { if pgErr.ConstraintName == "instances_id_check" {
return errors.New("instnace id not provided") return errors.New("instance id not provided")
} }
} }
// duplicate // duplicate
if pgErr.Code == "23505" { if pgErr.Code == "23505" {
if pgErr.ConstraintName == "instances_pkey" { if pgErr.ConstraintName == "instances_pkey" {
return errors.New("instnace id already exists") return errors.New("instance id already exists")
} }
} }
} }

View File

@@ -54,7 +54,7 @@ func TestCreateInstance(t *testing.T) {
} }
return instance return instance
}(), }(),
err: errors.New("instnace name not provided"), err: errors.New("instance name not provided"),
}, },
{ {
name: "adding same instance twice", name: "adding same instance twice",
@@ -78,7 +78,7 @@ func TestCreateInstance(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
return &inst return &inst
}, },
err: errors.New("instnace id already exists"), err: errors.New("instance id already exists"),
}, },
{ {
name: "adding instance with no id", name: "adding instance with no id",
@@ -96,7 +96,7 @@ func TestCreateInstance(t *testing.T) {
} }
return instance return instance
}(), }(),
err: errors.New("instnace id not provided"), err: errors.New("instance id not provided"),
}, },
} }
for _, tt := range tests { for _, tt := range tests {

View File

@@ -88,16 +88,19 @@ func (o *org) Create(ctx context.Context, organization *domain.Organization) err
// constraint violation // constraint violation
if pgErr.Code == "23514" { if pgErr.Code == "23514" {
if pgErr.ConstraintName == "organizations_name_check" { if pgErr.ConstraintName == "organizations_name_check" {
return errors.New("instnace name not provided") return errors.New("organization name not provided")
} }
if pgErr.ConstraintName == "organizations_id_check" { if pgErr.ConstraintName == "organizations_id_check" {
return errors.New("instnace id not provided") return errors.New("organization id not provided")
}
if pgErr.ConstraintName == "organizations_instance_id_check" {
return errors.New("instance id not provided")
} }
} }
// duplicate // duplicate
if pgErr.Code == "23505" { if pgErr.Code == "23505" {
if pgErr.ConstraintName == "organizations_pkey" { if pgErr.ConstraintName == "organizations_pkey" {
return errors.New("instnace id already exists") return errors.New("organization id already exists")
} }
} }
} }
@@ -137,8 +140,13 @@ func (o org) Delete(ctx context.Context, condition database.Condition) error {
// ------------------------------------------------------------- // -------------------------------------------------------------
// SetName implements [domain.organizationChanges]. // SetName implements [domain.organizationChanges].
func (i org) SetName(name string) database.Change { func (o org) SetName(name string) database.Change {
return database.NewChange(i.NameColumn(), name) return database.NewChange(o.NameColumn(), name)
}
// SetState implements [domain.organizationChanges].
func (i org) SetState(state domain.State) database.Change {
return database.NewChange(i.StateColumn(), state)
} }
// ------------------------------------------------------------- // -------------------------------------------------------------

View File

@@ -1,10 +1,743 @@
package repository_test package repository_test
// iraq: I had to comment out so that the UTs would pass import (
// TestBla is an example and can be removed later "context"
// func TestBla(t *testing.T) { "errors"
// var count int "testing"
// err := pool.QueryRow(context.Background(), "select count(*) from zitadel.instances").Scan(&count) "time"
// assert.NoError(t, err)
// assert.Equal(t, 0, count) "github.com/brianvoe/gofakeit/v6"
"github.com/stretchr/testify/assert"
"github.com/zitadel/zitadel/backend/v3/domain"
"github.com/zitadel/zitadel/backend/v3/storage/database"
"github.com/zitadel/zitadel/backend/v3/storage/database/repository"
)
func TestCreateOrganization(t *testing.T) {
tests := []struct {
name string
testFunc func() *domain.Organization
organization domain.Organization
err error
}{
{
name: "happy path",
organization: func() domain.Organization {
organizationId := gofakeit.Name()
organizationName := gofakeit.Name()
instanceId := gofakeit.Name()
organization := domain.Organization{
ID: organizationId,
Name: organizationName,
InstanceID: instanceId,
State: domain.Active,
}
return organization
}(),
},
{
name: "create organization wihtout name",
organization: func() domain.Organization {
organizationId := gofakeit.Name()
// organizationName := gofakeit.Name()
instanceId := gofakeit.Name()
organization := domain.Organization{
ID: organizationId,
Name: "",
InstanceID: instanceId,
State: domain.Active,
}
return organization
}(),
err: errors.New("organization name not provided"),
},
{
name: "adding same organization twice",
testFunc: func() *domain.Organization {
organizationRepo := repository.OrgRepository(pool)
organizationId := gofakeit.Name()
organizationName := gofakeit.Name()
instanceId := gofakeit.Name()
ctx := context.Background()
inst := domain.Organization{
ID: organizationId,
Name: organizationName,
InstanceID: instanceId,
State: domain.Active,
}
err := organizationRepo.Create(ctx, &inst)
assert.NoError(t, err)
return &inst
},
err: errors.New("organization id already exists"),
},
{
name: "adding organization with no id",
organization: func() domain.Organization {
// organizationId := gofakeit.Name()
organizationName := gofakeit.Name()
instanceId := gofakeit.Name()
organization := domain.Organization{
// ID: organizationId,
Name: organizationName,
InstanceID: instanceId,
State: domain.Active,
}
return organization
}(),
err: errors.New("organization id not provided"),
},
{
name: "adding organization with no instance id",
organization: func() domain.Organization {
organizationId := gofakeit.Name()
organizationName := gofakeit.Name()
organization := domain.Organization{
ID: organizationId,
Name: organizationName,
// InstanceID: instanceId,
State: domain.Active,
}
return organization
}(),
err: errors.New("instance id not provided"),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ctx := context.Background()
var organization *domain.Organization
if tt.testFunc != nil {
organization = tt.testFunc()
} else {
organization = &tt.organization
}
organizationRepo := repository.OrgRepository(pool)
// create organization
beforeCreate := time.Now()
err := organizationRepo.Create(ctx, organization)
assert.Equal(t, tt.err, err)
if err != nil {
return
}
afterCreate := time.Now()
// check organization values
organization, err = organizationRepo.Get(ctx,
organizationRepo.NameCondition(database.TextOperationEqual, organization.Name),
)
assert.NoError(t, err)
assert.Equal(t, tt.organization.ID, organization.ID)
assert.Equal(t, tt.organization.Name, organization.Name)
assert.Equal(t, tt.organization.InstanceID, organization.InstanceID)
assert.Equal(t, tt.organization.State, organization.State)
assert.WithinRange(t, organization.CreatedAt, beforeCreate, afterCreate)
assert.WithinRange(t, organization.UpdatedAt, beforeCreate, afterCreate)
assert.Nil(t, organization.DeletedAt)
})
}
}
func TestUpdateOrganization(t *testing.T) {
organizationRepo := repository.OrgRepository(pool)
tests := []struct {
name string
testFunc func() *domain.Organization
update []database.Change
rowsAffected int64
}{
{
name: "happy path update name",
testFunc: func() *domain.Organization {
organizationId := gofakeit.Name()
organizationName := gofakeit.Name()
instanceId := gofakeit.Name()
ctx := context.Background()
org := domain.Organization{
ID: organizationId,
Name: organizationName,
InstanceID: instanceId,
State: domain.Active,
}
// create organization
err := organizationRepo.Create(ctx, &org)
assert.NoError(t, err)
// update with updated value
org.Name = "new_name"
return &org
},
update: []database.Change{organizationRepo.SetName("new_name")},
rowsAffected: 1,
},
{
name: "happy path change state",
testFunc: func() *domain.Organization {
organizationId := gofakeit.Name()
organizationName := gofakeit.Name()
instanceId := gofakeit.Name()
ctx := context.Background()
org := domain.Organization{
ID: organizationId,
Name: organizationName,
InstanceID: instanceId,
State: domain.Active,
}
// create organization
err := organizationRepo.Create(ctx, &org)
assert.NoError(t, err)
// update with updated value
org.State = domain.Inactive
return &org
},
update: []database.Change{organizationRepo.SetState(domain.Inactive)},
rowsAffected: 1,
},
// {
// name: "update non existent organization",
// testFunc: func() *domain.Organization {
// organizationId := gofakeit.Name()
// org := domain.Organization{
// ID: organizationId,
// }
// return &org
// },
// rowsAffected: 0,
// },
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
beforeUpdate := time.Now()
ctx := context.Background()
organizationRepo := repository.OrgRepository(pool)
createdOrg := tt.testFunc()
// update org
rowsAffected, err := organizationRepo.Update(ctx,
organizationRepo.IDCondition(createdOrg.ID),
tt.update...,
)
afterUpdate := time.Now()
assert.NoError(t, err)
assert.Equal(t, tt.rowsAffected, rowsAffected)
if rowsAffected == 0 {
return
}
// check organization values
organization, err := organizationRepo.Get(ctx,
organizationRepo.IDCondition(createdOrg.ID),
)
assert.NoError(t, err)
assert.Equal(t, createdOrg.ID, organization.ID)
assert.Equal(t, createdOrg.Name, organization.Name)
assert.Equal(t, createdOrg.State, organization.State)
assert.WithinRange(t, organization.UpdatedAt, beforeUpdate, afterUpdate)
assert.Nil(t, organization.DeletedAt)
})
}
}
// func TestGetOrganization(t *testing.T) {
// organizationRepo := repository.OrgRepository(pool)
// type test struct {
// name string
// testFunc func() *domain.Organization
// conditionClauses []database.Condition
// noOrganizationReturned bool
// }
// tests := []test{
// func() test {
// organizationId := gofakeit.Name()
// return test{
// name: "happy path get using id",
// testFunc: func() *domain.Organization {
// organizationName := gofakeit.Name()
// ctx := context.Background()
// inst := domain.Organization{
// ID: organizationId,
// Name: organizationName,
// DefaultOrgID: "defaultOrgId",
// IAMProjectID: "iamProject",
// ConsoleClientID: "consoleCLient",
// ConsoleAppID: "consoleApp",
// DefaultLanguage: "defaultLanguage",
// }
// // create organization
// err := organizationRepo.Create(ctx, &inst)
// assert.NoError(t, err)
// return &inst
// },
// conditionClauses: []database.Condition{organizationRepo.IDCondition(organizationId)},
// }
// }(),
// func() test {
// organizationName := gofakeit.Name()
// return test{
// name: "happy path get using name",
// testFunc: func() *domain.Organization {
// organizationId := gofakeit.Name()
// ctx := context.Background()
// inst := domain.Organization{
// ID: organizationId,
// Name: organizationName,
// DefaultOrgID: "defaultOrgId",
// IAMProjectID: "iamProject",
// ConsoleClientID: "consoleCLient",
// ConsoleAppID: "consoleApp",
// DefaultLanguage: "defaultLanguage",
// }
// // create organization
// err := organizationRepo.Create(ctx, &inst)
// assert.NoError(t, err)
// return &inst
// },
// conditionClauses: []database.Condition{organizationRepo.NameCondition(database.TextOperationEqual, organizationName)},
// }
// }(),
// {
// name: "get non existent organization",
// testFunc: func() *domain.Organization {
// organizationId := gofakeit.Name()
// inst := domain.Organization{
// ID: organizationId,
// }
// return &inst
// },
// conditionClauses: []database.Condition{organizationRepo.NameCondition(database.TextOperationEqual, "non-existent-organization-name")},
// noOrganizationReturned: true,
// },
// }
// for _, tt := range tests {
// t.Run(tt.name, func(t *testing.T) {
// ctx := context.Background()
// organizationRepo := repository.OrgRepository(pool)
// var organization *domain.Organization
// if tt.testFunc != nil {
// organization = tt.testFunc()
// }
// // check organization values
// returnedOrganization, err := organizationRepo.Get(ctx,
// tt.conditionClauses...,
// )
// assert.NoError(t, err)
// if tt.noOrganizationReturned {
// assert.Nil(t, returnedOrganization)
// return
// }
// assert.Equal(t, returnedOrganization.ID, organization.ID)
// assert.Equal(t, returnedOrganization.Name, organization.Name)
// assert.Equal(t, returnedOrganization.DefaultOrgID, organization.DefaultOrgID)
// assert.Equal(t, returnedOrganization.IAMProjectID, organization.IAMProjectID)
// assert.Equal(t, returnedOrganization.ConsoleClientID, organization.ConsoleClientID)
// assert.Equal(t, returnedOrganization.ConsoleAppID, organization.ConsoleAppID)
// assert.Equal(t, returnedOrganization.DefaultLanguage, organization.DefaultLanguage)
// assert.NoError(t, err)
// })
// }
// }
// func TestListOrganization(t *testing.T) {
// type test struct {
// name string
// testFunc func() ([]*domain.Organization, database.PoolTest, func())
// conditionClauses []database.Condition
// noOrganizationReturned bool
// }
// tests := []test{
// {
// name: "happy path single organization no filter",
// testFunc: func() ([]*domain.Organization, database.PoolTest, func()) {
// ctx := context.Background()
// // create new db to make sure no organizations exist
// pool, stop, err := newEmbeededDB()
// assert.NoError(t, err)
// organizationRepo := repository.OrgRepository(pool)
// noOfOrganizations := 1
// organizations := make([]*domain.Organization, noOfOrganizations)
// for i := range noOfOrganizations {
// organizationId := gofakeit.Name()
// organizationName := gofakeit.Name()
// inst := domain.Organization{
// ID: organizationId,
// Name: organizationName,
// DefaultOrgID: "defaultOrgId",
// IAMProjectID: "iamProject",
// ConsoleClientID: "consoleCLient",
// ConsoleAppID: "consoleApp",
// DefaultLanguage: "defaultLanguage",
// }
// // create organization
// err := organizationRepo.Create(ctx, &inst)
// assert.NoError(t, err)
// organizations[i] = &inst
// }
// return organizations, pool, stop
// },
// },
// {
// name: "happy path multiple organization no filter",
// testFunc: func() ([]*domain.Organization, database.PoolTest, func()) {
// ctx := context.Background()
// // create new db to make sure no organizations exist
// pool, stop, err := newEmbeededDB()
// assert.NoError(t, err)
// organizationRepo := repository.OrgRepository(pool)
// noOfOrganizations := 5
// organizations := make([]*domain.Organization, noOfOrganizations)
// for i := range noOfOrganizations {
// organizationId := gofakeit.Name()
// organizationName := gofakeit.Name()
// inst := domain.Organization{
// ID: organizationId,
// Name: organizationName,
// DefaultOrgID: "defaultOrgId",
// IAMProjectID: "iamProject",
// ConsoleClientID: "consoleCLient",
// ConsoleAppID: "consoleApp",
// DefaultLanguage: "defaultLanguage",
// }
// // create organization
// err := organizationRepo.Create(ctx, &inst)
// assert.NoError(t, err)
// organizations[i] = &inst
// }
// return organizations, pool, stop
// },
// },
// func() test {
// organizationRepo := repository.OrgRepository(pool)
// organizationId := gofakeit.Name()
// return test{
// name: "organization filter on id",
// testFunc: func() ([]*domain.Organization, database.PoolTest, func()) {
// ctx := context.Background()
// noOfOrganizations := 1
// organizations := make([]*domain.Organization, noOfOrganizations)
// for i := range noOfOrganizations {
// organizationName := gofakeit.Name()
// inst := domain.Organization{
// ID: organizationId,
// Name: organizationName,
// DefaultOrgID: "defaultOrgId",
// IAMProjectID: "iamProject",
// ConsoleClientID: "consoleCLient",
// ConsoleAppID: "consoleApp",
// DefaultLanguage: "defaultLanguage",
// }
// // create organization
// err := organizationRepo.Create(ctx, &inst)
// assert.NoError(t, err)
// organizations[i] = &inst
// }
// return organizations, nil, nil
// },
// conditionClauses: []database.Condition{organizationRepo.IDCondition(organizationId)},
// }
// }(),
// func() test {
// organizationRepo := repository.OrgRepository(pool)
// organizationName := gofakeit.Name()
// return test{
// name: "multiple organization filter on name",
// testFunc: func() ([]*domain.Organization, database.PoolTest, func()) {
// ctx := context.Background()
// noOfOrganizations := 5
// organizations := make([]*domain.Organization, noOfOrganizations)
// for i := range noOfOrganizations {
// organizationId := gofakeit.Name()
// inst := domain.Organization{
// ID: organizationId,
// Name: organizationName,
// DefaultOrgID: "defaultOrgId",
// IAMProjectID: "iamProject",
// ConsoleClientID: "consoleCLient",
// ConsoleAppID: "consoleApp",
// DefaultLanguage: "defaultLanguage",
// }
// // create organization
// err := organizationRepo.Create(ctx, &inst)
// assert.NoError(t, err)
// organizations[i] = &inst
// }
// return organizations, nil, nil
// },
// conditionClauses: []database.Condition{organizationRepo.NameCondition(database.TextOperationEqual, organizationName)},
// }
// }(),
// }
// for _, tt := range tests {
// t.Run(tt.name, func(t *testing.T) {
// ctx := context.Background()
// var organizations []*domain.Organization
// pool := pool
// if tt.testFunc != nil {
// var stop func()
// var pool_ database.PoolTest
// organizations, pool_, stop = tt.testFunc()
// if pool_ != nil {
// pool = pool_
// defer stop()
// }
// }
// organizationRepo := repository.OrgRepository(pool)
// // check organization values
// returnedOrganizations, err := organizationRepo.List(ctx,
// tt.conditionClauses...,
// )
// assert.NoError(t, err)
// if tt.noOrganizationReturned {
// assert.Nil(t, returnedOrganizations)
// return
// }
// assert.Equal(t, len(organizations), len(returnedOrganizations))
// for i, organization := range organizations {
// assert.Equal(t, returnedOrganizations[i].ID, organization.ID)
// assert.Equal(t, returnedOrganizations[i].Name, organization.Name)
// assert.Equal(t, returnedOrganizations[i].DefaultOrgID, organization.DefaultOrgID)
// assert.Equal(t, returnedOrganizations[i].IAMProjectID, organization.IAMProjectID)
// assert.Equal(t, returnedOrganizations[i].ConsoleClientID, organization.ConsoleClientID)
// assert.Equal(t, returnedOrganizations[i].ConsoleAppID, organization.ConsoleAppID)
// assert.Equal(t, returnedOrganizations[i].DefaultLanguage, organization.DefaultLanguage)
// assert.NoError(t, err)
// }
// })
// }
// }
// func TestDeleteOrganization(t *testing.T) {
// type test struct {
// name string
// testFunc func()
// conditionClauses database.Condition
// }
// tests := []test{
// func() test {
// organizationRepo := repository.OrgRepository(pool)
// organizationId := gofakeit.Name()
// return test{
// name: "happy path delete single organization filter id",
// testFunc: func() {
// ctx := context.Background()
// noOfOrganizations := 1
// organizations := make([]*domain.Organization, noOfOrganizations)
// for i := range noOfOrganizations {
// organizationName := gofakeit.Name()
// inst := domain.Organization{
// ID: organizationId,
// Name: organizationName,
// DefaultOrgID: "defaultOrgId",
// IAMProjectID: "iamProject",
// ConsoleClientID: "consoleCLient",
// ConsoleAppID: "consoleApp",
// DefaultLanguage: "defaultLanguage",
// }
// // create organization
// err := organizationRepo.Create(ctx, &inst)
// assert.NoError(t, err)
// organizations[i] = &inst
// }
// },
// conditionClauses: organizationRepo.IDCondition(organizationId),
// }
// }(),
// func() test {
// organizationRepo := repository.OrgRepository(pool)
// organizationName := gofakeit.Name()
// return test{
// name: "happy path delete single organization filter name",
// testFunc: func() {
// ctx := context.Background()
// noOfOrganizations := 1
// organizations := make([]*domain.Organization, noOfOrganizations)
// for i := range noOfOrganizations {
// organizationId := gofakeit.Name()
// inst := domain.Organization{
// ID: organizationId,
// Name: organizationName,
// DefaultOrgID: "defaultOrgId",
// IAMProjectID: "iamProject",
// ConsoleClientID: "consoleCLient",
// ConsoleAppID: "consoleApp",
// DefaultLanguage: "defaultLanguage",
// }
// // create organization
// err := organizationRepo.Create(ctx, &inst)
// assert.NoError(t, err)
// organizations[i] = &inst
// }
// },
// conditionClauses: organizationRepo.NameCondition(database.TextOperationEqual, organizationName),
// }
// }(),
// func() test {
// organizationRepo := repository.OrgRepository(pool)
// non_existent_organization_name := gofakeit.Name()
// return test{
// name: "delete non existent organization",
// conditionClauses: organizationRepo.NameCondition(database.TextOperationEqual, non_existent_organization_name),
// }
// }(),
// func() test {
// organizationRepo := repository.OrgRepository(pool)
// organizationName := gofakeit.Name()
// return test{
// name: "multiple organization filter on name",
// testFunc: func() {
// ctx := context.Background()
// noOfOrganizations := 5
// organizations := make([]*domain.Organization, noOfOrganizations)
// for i := range noOfOrganizations {
// organizationId := gofakeit.Name()
// inst := domain.Organization{
// ID: organizationId,
// Name: organizationName,
// DefaultOrgID: "defaultOrgId",
// IAMProjectID: "iamProject",
// ConsoleClientID: "consoleCLient",
// ConsoleAppID: "consoleApp",
// DefaultLanguage: "defaultLanguage",
// }
// // create organization
// err := organizationRepo.Create(ctx, &inst)
// assert.NoError(t, err)
// organizations[i] = &inst
// }
// },
// conditionClauses: organizationRepo.NameCondition(database.TextOperationEqual, organizationName),
// }
// }(),
// func() test {
// organizationRepo := repository.OrgRepository(pool)
// organizationName := gofakeit.Name()
// return test{
// name: "deleted already deleted organization",
// testFunc: func() {
// ctx := context.Background()
// noOfOrganizations := 1
// organizations := make([]*domain.Organization, noOfOrganizations)
// for i := range noOfOrganizations {
// organizationId := gofakeit.Name()
// inst := domain.Organization{
// ID: organizationId,
// Name: organizationName,
// DefaultOrgID: "defaultOrgId",
// IAMProjectID: "iamProject",
// ConsoleClientID: "consoleCLient",
// ConsoleAppID: "consoleApp",
// DefaultLanguage: "defaultLanguage",
// }
// // create organization
// err := organizationRepo.Create(ctx, &inst)
// assert.NoError(t, err)
// organizations[i] = &inst
// }
// // delete organization
// err := organizationRepo.Delete(ctx,
// organizationRepo.NameCondition(database.TextOperationEqual, organizationName),
// )
// assert.NoError(t, err)
// },
// conditionClauses: organizationRepo.NameCondition(database.TextOperationEqual, organizationName),
// }
// }(),
// }
// for _, tt := range tests {
// t.Run(tt.name, func(t *testing.T) {
// ctx := context.Background()
// organizationRepo := repository.OrgRepository(pool)
// if tt.testFunc != nil {
// tt.testFunc()
// }
// // delete organization
// err := organizationRepo.Delete(ctx,
// tt.conditionClauses,
// )
// assert.NoError(t, err)
// // check organization was deleted
// organization, err := organizationRepo.Get(ctx,
// tt.conditionClauses,
// )
// assert.NoError(t, err)
// assert.Nil(t, organization)
// })
// }
// } // }

View File

@@ -96,16 +96,13 @@ func (p *orgRelationalProjection) reduceOrgRelationalAdded(event eventstore.Even
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-uYq5R", "reduce.wrong.event.type %s", org.OrgAddedEventType) return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-uYq5R", "reduce.wrong.event.type %s", org.OrgAddedEventType)
} }
// need to convert old state (int) to new state (enum)
state := repoDomain.State[domain.OrgStateActive-1]
return handler.NewCreateStatement( return handler.NewCreateStatement(
e, e,
[]handler.Column{ []handler.Column{
handler.NewCol(OrgColumnID, e.Aggregate().ID), handler.NewCol(OrgColumnID, e.Aggregate().ID),
handler.NewCol(OrgColumnName, e.Name), handler.NewCol(OrgColumnName, e.Name),
handler.NewCol(OrgColumnInstanceID, e.Aggregate().InstanceID), handler.NewCol(OrgColumnInstanceID, e.Aggregate().InstanceID),
handler.NewCol(State, state), handler.NewCol(State, repoDomain.Active),
handler.NewCol(CreatedAt, e.CreationDate()), handler.NewCol(CreatedAt, e.CreationDate()),
handler.NewCol(UpdatedAt, e.CreationDate()), handler.NewCol(UpdatedAt, e.CreationDate()),
}, },
@@ -139,12 +136,10 @@ func (p *orgRelationalProjection) reduceOrgRelationalDeactivated(event eventstor
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-BApK5", "reduce.wrong.event.type %s", org.OrgDeactivatedEventType) return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-BApK5", "reduce.wrong.event.type %s", org.OrgDeactivatedEventType)
} }
// need to convert old state (int) to new state (enum)
state := repoDomain.State[domain.OrgStateInactive-1]
return handler.NewUpdateStatement( return handler.NewUpdateStatement(
e, e,
[]handler.Column{ []handler.Column{
handler.NewCol(State, state), handler.NewCol(State, repoDomain.Inactive),
handler.NewCol(UpdatedAt, e.CreationDate()), handler.NewCol(UpdatedAt, e.CreationDate()),
}, },
[]handler.Condition{ []handler.Condition{