mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-23 15:28:21 +00:00
Merge branch 'instance_table_2' into org_table
This commit is contained in:
@@ -20,7 +20,7 @@ func (a *and) Write(builder *StatementBuilder) {
|
||||
if i > 0 {
|
||||
builder.WriteString(" AND ")
|
||||
}
|
||||
condition.(Condition).Write(builder)
|
||||
condition.Write(builder)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ func (o *or) Write(builder *StatementBuilder) {
|
||||
if i > 0 {
|
||||
builder.WriteString(" OR ")
|
||||
}
|
||||
condition.(Condition).Write(builder)
|
||||
condition.Write(builder)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ func (i *isNotNull) Write(builder *StatementBuilder) {
|
||||
|
||||
// IsNotNull creates a condition that checks if a column is NOT NULL.
|
||||
func IsNotNull(column Column) *isNotNull {
|
||||
return &isNotNull{column: column.(Column)}
|
||||
return &isNotNull{column: column}
|
||||
}
|
||||
|
||||
var _ Condition = (*isNotNull)(nil)
|
||||
|
@@ -16,6 +16,7 @@ type Pool interface {
|
||||
|
||||
type PoolTest interface {
|
||||
Pool
|
||||
// MigrateTest is the same as [Migrator] but executes the migrations multiple times instead of only once.
|
||||
MigrateTest(ctx context.Context) error
|
||||
}
|
||||
|
||||
@@ -35,6 +36,7 @@ type Querier interface {
|
||||
}
|
||||
|
||||
// Executor is a database client that can execute statements.
|
||||
// It returns the number of rows affected or an error
|
||||
type Executor interface {
|
||||
Exec(ctx context.Context, stmt string, args ...any) (int64, error)
|
||||
}
|
||||
|
@@ -34,7 +34,7 @@ type Config struct {
|
||||
// // The value will be taken as is. Multiple options are space separated.
|
||||
// Options string
|
||||
|
||||
configuredFields []string
|
||||
// configuredFields []string
|
||||
}
|
||||
|
||||
// Connect implements [database.Connector].
|
||||
|
@@ -10,3 +10,17 @@ CREATE TABLE IF NOT EXISTS zitadel.instances(
|
||||
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
deleted_at TIMESTAMPTZ DEFAULT NULL
|
||||
);
|
||||
|
||||
CREATE OR REPLACE FUNCTION zitadel.set_updated_at()
|
||||
RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
NEW.updated_at := NOW();
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE TRIGGER trigger_set_updated_at
|
||||
BEFORE UPDATE ON zitadel.instances
|
||||
FOR EACH ROW
|
||||
WHEN (OLD.updated_at IS NOT DISTINCT FROM NEW.updated_at)
|
||||
EXECUTE FUNCTION zitadel.set_updated_at();
|
||||
|
@@ -83,11 +83,6 @@ func (c *pgxPool) Migrate(ctx context.Context) error {
|
||||
|
||||
// Migrate implements [database.PoolTest].
|
||||
func (c *pgxPool) MigrateTest(ctx context.Context) error {
|
||||
// allow multiple migrations
|
||||
// if isMigrated {
|
||||
// return nil
|
||||
// }
|
||||
|
||||
client, err := c.Pool.Acquire(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@@ -2,6 +2,7 @@ package postgres
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
|
||||
@@ -25,7 +26,10 @@ func (tx *pgxTx) Rollback(ctx context.Context) error {
|
||||
// End implements [database.Transaction].
|
||||
func (tx *pgxTx) End(ctx context.Context, err error) error {
|
||||
if err != nil {
|
||||
tx.Rollback(ctx)
|
||||
rollbackErr := tx.Rollback(ctx)
|
||||
if rollbackErr != nil {
|
||||
err = errors.Join(err, rollbackErr)
|
||||
}
|
||||
return err
|
||||
}
|
||||
return tx.Commit(ctx)
|
||||
|
@@ -105,14 +105,25 @@ func TestServer_TestInstanceDeleteReduces(t *testing.T) {
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
instanceRepo := repository.InstanceRepository(pool)
|
||||
|
||||
// check instance exists
|
||||
retryDuration, tick := integration.WaitForAndTickWithMaxDuration(CTX, time.Minute)
|
||||
assert.EventuallyWithT(t, func(ttt *assert.CollectT) {
|
||||
instance, err := instanceRepo.Get(CTX,
|
||||
instanceRepo.NameCondition(database.TextOperationEqual, instanceName),
|
||||
)
|
||||
require.NoError(ttt, err)
|
||||
require.Equal(ttt, instanceName, instance.Name)
|
||||
}, retryDuration, tick)
|
||||
|
||||
_, err = SystemClient.RemoveInstance(CTX, &system.RemoveInstanceRequest{
|
||||
InstanceId: res.InstanceId,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
instanceRepo := repository.InstanceRepository(pool)
|
||||
retryDuration, tick := integration.WaitForAndTickWithMaxDuration(CTX, time.Minute)
|
||||
assert.EventuallyWithT(t, func(t *assert.CollectT) {
|
||||
retryDuration, tick = integration.WaitForAndTickWithMaxDuration(CTX, time.Minute)
|
||||
assert.EventuallyWithT(t, func(ttt *assert.CollectT) {
|
||||
instance, err := instanceRepo.Get(CTX,
|
||||
instanceRepo.NameCondition(database.TextOperationEqual, instanceName),
|
||||
)
|
||||
|
@@ -46,7 +46,7 @@ func (opts *QueryOpts) WriteOrderBy(builder *StatementBuilder) {
|
||||
return
|
||||
}
|
||||
builder.WriteString(" ORDER BY ")
|
||||
Columns(opts.OrderBy).Write(builder)
|
||||
opts.OrderBy.Write(builder)
|
||||
}
|
||||
|
||||
func (opts *QueryOpts) WriteLimit(builder *StatementBuilder) {
|
||||
|
@@ -6,6 +6,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgconn"
|
||||
|
||||
"github.com/zitadel/zitadel/backend/v3/domain"
|
||||
"github.com/zitadel/zitadel/backend/v3/storage/database"
|
||||
)
|
||||
@@ -33,28 +34,27 @@ const queryInstanceStmt = `SELECT id, name, default_org_id, iam_project_id, cons
|
||||
|
||||
// Get implements [domain.InstanceRepository].
|
||||
func (i *instance) Get(ctx context.Context, opts ...database.Condition) (*domain.Instance, error) {
|
||||
builder := database.StatementBuilder{}
|
||||
var builder database.StatementBuilder
|
||||
|
||||
builder.WriteString(queryInstanceStmt)
|
||||
|
||||
// return only non deleted isntances
|
||||
// return only non deleted instances
|
||||
opts = append(opts, database.IsNull(i.DeletedAtColumn()))
|
||||
andCondition := database.And(opts...)
|
||||
i.writeCondition(&builder, andCondition)
|
||||
i.writeCondition(&builder, database.And(opts...))
|
||||
|
||||
return scanInstance(ctx, i.client, &builder)
|
||||
}
|
||||
|
||||
// List implements [domain.InstanceRepository].
|
||||
func (i *instance) List(ctx context.Context, opts ...database.Condition) ([]*domain.Instance, error) {
|
||||
builder := database.StatementBuilder{}
|
||||
var builder database.StatementBuilder
|
||||
|
||||
builder.WriteString(queryInstanceStmt)
|
||||
|
||||
// return only non deleted isntances
|
||||
// return only non deleted instances
|
||||
opts = append(opts, database.IsNull(i.DeletedAtColumn()))
|
||||
andCondition := database.And(opts...)
|
||||
i.writeCondition(&builder, andCondition)
|
||||
notDeletedCondition := database.And(opts...)
|
||||
i.writeCondition(&builder, notDeletedCondition)
|
||||
|
||||
return scanInstances(ctx, i.client, &builder)
|
||||
}
|
||||
@@ -65,7 +65,8 @@ const createInstanceStmt = `INSERT INTO zitadel.instances (id, name, default_org
|
||||
|
||||
// Create implements [domain.InstanceRepository].
|
||||
func (i *instance) Create(ctx context.Context, instance *domain.Instance) error {
|
||||
builder := database.StatementBuilder{}
|
||||
var builder database.StatementBuilder
|
||||
|
||||
builder.AppendArgs(instance.ID, instance.Name, instance.DefaultOrgID, instance.IAMProjectID, instance.ConsoleClientID, instance.ConsoleAppID, instance.DefaultLanguage)
|
||||
builder.WriteString(createInstanceStmt)
|
||||
|
||||
@@ -95,10 +96,14 @@ func (i *instance) Create(ctx context.Context, instance *domain.Instance) error
|
||||
|
||||
// Update implements [domain.InstanceRepository].
|
||||
func (i instance) Update(ctx context.Context, condition database.Condition, changes ...database.Change) (int64, error) {
|
||||
builder := database.StatementBuilder{}
|
||||
var builder database.StatementBuilder
|
||||
|
||||
builder.WriteString(`UPDATE zitadel.instances SET `)
|
||||
|
||||
// don't update deleted instances
|
||||
conditions := []database.Condition{condition, database.IsNull(i.DeletedAtColumn())}
|
||||
database.Changes(changes).Write(&builder)
|
||||
i.writeCondition(&builder, condition)
|
||||
i.writeCondition(&builder, database.And(conditions...))
|
||||
|
||||
stmt := builder.String()
|
||||
|
||||
@@ -111,7 +116,8 @@ func (i instance) Delete(ctx context.Context, condition database.Condition) erro
|
||||
if condition == nil {
|
||||
return errors.New("Delete must contain a condition") // (otherwise ALL instances will be deleted)
|
||||
}
|
||||
builder := database.StatementBuilder{}
|
||||
var builder database.StatementBuilder
|
||||
|
||||
builder.WriteString(`UPDATE zitadel.instances SET deleted_at = $1`)
|
||||
builder.AppendArgs(time.Now())
|
||||
|
||||
|
@@ -7,7 +7,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/brianvoe/gofakeit/v6"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/zitadel/zitadel/backend/v3/domain"
|
||||
"github.com/zitadel/zitadel/backend/v3/storage/database"
|
||||
@@ -17,7 +17,7 @@ import (
|
||||
func TestCreateInstance(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
testFunc func() *domain.Instance
|
||||
testFunc func(ctx context.Context, t *testing.T) *domain.Instance
|
||||
instance domain.Instance
|
||||
err error
|
||||
}{
|
||||
@@ -39,7 +39,7 @@ func TestCreateInstance(t *testing.T) {
|
||||
}(),
|
||||
},
|
||||
{
|
||||
name: "create instance wihtout name",
|
||||
name: "create instance without name",
|
||||
instance: func() domain.Instance {
|
||||
instanceId := gofakeit.Name()
|
||||
// instanceName := gofakeit.Name()
|
||||
@@ -58,12 +58,11 @@ func TestCreateInstance(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "adding same instance twice",
|
||||
testFunc: func() *domain.Instance {
|
||||
testFunc: func(ctx context.Context, t *testing.T) *domain.Instance {
|
||||
instanceRepo := repository.InstanceRepository(pool)
|
||||
instanceId := gofakeit.Name()
|
||||
instanceName := gofakeit.Name()
|
||||
|
||||
ctx := context.Background()
|
||||
inst := domain.Instance{
|
||||
ID: instanceId,
|
||||
Name: instanceName,
|
||||
@@ -75,7 +74,7 @@ func TestCreateInstance(t *testing.T) {
|
||||
}
|
||||
|
||||
err := instanceRepo.Create(ctx, &inst)
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
return &inst
|
||||
},
|
||||
err: errors.New("instance id already exists"),
|
||||
@@ -105,7 +104,7 @@ func TestCreateInstance(t *testing.T) {
|
||||
|
||||
var instance *domain.Instance
|
||||
if tt.testFunc != nil {
|
||||
instance = tt.testFunc()
|
||||
instance = tt.testFunc(ctx, t)
|
||||
} else {
|
||||
instance = &tt.instance
|
||||
}
|
||||
@@ -114,7 +113,7 @@ func TestCreateInstance(t *testing.T) {
|
||||
// create instance
|
||||
beforeCreate := time.Now()
|
||||
err := instanceRepo.Create(ctx, instance)
|
||||
assert.Equal(t, tt.err, err)
|
||||
require.Equal(t, tt.err, err)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -124,17 +123,18 @@ func TestCreateInstance(t *testing.T) {
|
||||
instance, err = instanceRepo.Get(ctx,
|
||||
instanceRepo.NameCondition(database.TextOperationEqual, instance.Name),
|
||||
)
|
||||
assert.Equal(t, tt.instance.ID, instance.ID)
|
||||
assert.Equal(t, tt.instance.Name, instance.Name)
|
||||
assert.Equal(t, tt.instance.DefaultOrgID, instance.DefaultOrgID)
|
||||
assert.Equal(t, tt.instance.IAMProjectID, instance.IAMProjectID)
|
||||
assert.Equal(t, tt.instance.ConsoleClientID, instance.ConsoleClientID)
|
||||
assert.Equal(t, tt.instance.ConsoleAppID, instance.ConsoleAppID)
|
||||
assert.Equal(t, tt.instance.DefaultLanguage, instance.DefaultLanguage)
|
||||
assert.WithinRange(t, instance.CreatedAt, beforeCreate, afterCreate)
|
||||
assert.WithinRange(t, instance.UpdatedAt, beforeCreate, afterCreate)
|
||||
assert.Nil(t, instance.DeletedAt)
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, tt.instance.ID, instance.ID)
|
||||
require.Equal(t, tt.instance.Name, instance.Name)
|
||||
require.Equal(t, tt.instance.DefaultOrgID, instance.DefaultOrgID)
|
||||
require.Equal(t, tt.instance.IAMProjectID, instance.IAMProjectID)
|
||||
require.Equal(t, tt.instance.ConsoleClientID, instance.ConsoleClientID)
|
||||
require.Equal(t, tt.instance.ConsoleAppID, instance.ConsoleAppID)
|
||||
require.Equal(t, tt.instance.DefaultLanguage, instance.DefaultLanguage)
|
||||
require.WithinRange(t, instance.CreatedAt, beforeCreate, afterCreate)
|
||||
require.WithinRange(t, instance.UpdatedAt, beforeCreate, afterCreate)
|
||||
require.Nil(t, instance.DeletedAt)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -142,17 +142,16 @@ func TestCreateInstance(t *testing.T) {
|
||||
func TestUpdateInstance(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
testFunc func() *domain.Instance
|
||||
testFunc func(ctx context.Context, t *testing.T) *domain.Instance
|
||||
rowsAffected int64
|
||||
}{
|
||||
{
|
||||
name: "happy path",
|
||||
testFunc: func() *domain.Instance {
|
||||
testFunc: func(ctx context.Context, t *testing.T) *domain.Instance {
|
||||
instanceRepo := repository.InstanceRepository(pool)
|
||||
instanceId := gofakeit.Name()
|
||||
instanceName := gofakeit.Name()
|
||||
|
||||
ctx := context.Background()
|
||||
inst := domain.Instance{
|
||||
ID: instanceId,
|
||||
Name: instanceName,
|
||||
@@ -165,14 +164,45 @@ func TestUpdateInstance(t *testing.T) {
|
||||
|
||||
// create instance
|
||||
err := instanceRepo.Create(ctx, &inst)
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
return &inst
|
||||
},
|
||||
rowsAffected: 1,
|
||||
},
|
||||
{
|
||||
name: "update deleted instance",
|
||||
testFunc: func(ctx context.Context, t *testing.T) *domain.Instance {
|
||||
instanceRepo := repository.InstanceRepository(pool)
|
||||
instanceId := gofakeit.Name()
|
||||
instanceName := gofakeit.Name()
|
||||
|
||||
inst := domain.Instance{
|
||||
ID: instanceId,
|
||||
Name: instanceName,
|
||||
DefaultOrgID: "defaultOrgId",
|
||||
IAMProjectID: "iamProject",
|
||||
ConsoleClientID: "consoleCLient",
|
||||
ConsoleAppID: "consoleApp",
|
||||
DefaultLanguage: "defaultLanguage",
|
||||
}
|
||||
|
||||
// create instance
|
||||
err := instanceRepo.Create(ctx, &inst)
|
||||
require.NoError(t, err)
|
||||
|
||||
// delete instance
|
||||
err = instanceRepo.Delete(ctx,
|
||||
instanceRepo.IDCondition(inst.ID),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
return &inst
|
||||
},
|
||||
rowsAffected: 0,
|
||||
},
|
||||
{
|
||||
name: "update non existent instance",
|
||||
testFunc: func() *domain.Instance {
|
||||
testFunc: func(ctx context.Context, t *testing.T) *domain.Instance {
|
||||
instanceId := gofakeit.Name()
|
||||
|
||||
inst := domain.Instance{
|
||||
@@ -185,13 +215,12 @@ func TestUpdateInstance(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
beforeUpdate := time.Now()
|
||||
|
||||
ctx := context.Background()
|
||||
instanceRepo := repository.InstanceRepository(pool)
|
||||
|
||||
instance := tt.testFunc()
|
||||
instance := tt.testFunc(ctx, t)
|
||||
|
||||
beforeUpdate := time.Now()
|
||||
// update name
|
||||
newName := "new_" + instance.Name
|
||||
rowsAffected, err := instanceRepo.Update(ctx,
|
||||
@@ -199,9 +228,9 @@ func TestUpdateInstance(t *testing.T) {
|
||||
instanceRepo.SetName(newName),
|
||||
)
|
||||
afterUpdate := time.Now()
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, tt.rowsAffected, rowsAffected)
|
||||
require.Equal(t, tt.rowsAffected, rowsAffected)
|
||||
|
||||
if rowsAffected == 0 {
|
||||
return
|
||||
@@ -211,11 +240,11 @@ func TestUpdateInstance(t *testing.T) {
|
||||
instance, err = instanceRepo.Get(ctx,
|
||||
instanceRepo.IDCondition(instance.ID),
|
||||
)
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, newName, instance.Name)
|
||||
assert.WithinRange(t, instance.UpdatedAt, beforeUpdate, afterUpdate)
|
||||
assert.Nil(t, instance.DeletedAt)
|
||||
require.Equal(t, newName, instance.Name)
|
||||
require.WithinRange(t, instance.UpdatedAt, beforeUpdate, afterUpdate)
|
||||
require.Nil(t, instance.DeletedAt)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -223,10 +252,9 @@ func TestUpdateInstance(t *testing.T) {
|
||||
func TestGetInstance(t *testing.T) {
|
||||
instanceRepo := repository.InstanceRepository(pool)
|
||||
type test struct {
|
||||
name string
|
||||
testFunc func() *domain.Instance
|
||||
conditionClauses []database.Condition
|
||||
noInstanceReturned bool
|
||||
name string
|
||||
testFunc func(ctx context.Context, t *testing.T) *domain.Instance
|
||||
conditionClauses []database.Condition
|
||||
}
|
||||
|
||||
tests := []test{
|
||||
@@ -234,10 +262,9 @@ func TestGetInstance(t *testing.T) {
|
||||
instanceId := gofakeit.Name()
|
||||
return test{
|
||||
name: "happy path get using id",
|
||||
testFunc: func() *domain.Instance {
|
||||
testFunc: func(ctx context.Context, t *testing.T) *domain.Instance {
|
||||
instanceName := gofakeit.Name()
|
||||
|
||||
ctx := context.Background()
|
||||
inst := domain.Instance{
|
||||
ID: instanceId,
|
||||
Name: instanceName,
|
||||
@@ -250,7 +277,7 @@ func TestGetInstance(t *testing.T) {
|
||||
|
||||
// create instance
|
||||
err := instanceRepo.Create(ctx, &inst)
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
return &inst
|
||||
},
|
||||
conditionClauses: []database.Condition{instanceRepo.IDCondition(instanceId)},
|
||||
@@ -260,10 +287,9 @@ func TestGetInstance(t *testing.T) {
|
||||
instanceName := gofakeit.Name()
|
||||
return test{
|
||||
name: "happy path get using name",
|
||||
testFunc: func() *domain.Instance {
|
||||
testFunc: func(ctx context.Context, t *testing.T) *domain.Instance {
|
||||
instanceId := gofakeit.Name()
|
||||
|
||||
ctx := context.Background()
|
||||
inst := domain.Instance{
|
||||
ID: instanceId,
|
||||
Name: instanceName,
|
||||
@@ -276,7 +302,7 @@ func TestGetInstance(t *testing.T) {
|
||||
|
||||
// create instance
|
||||
err := instanceRepo.Create(ctx, &inst)
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
return &inst
|
||||
},
|
||||
conditionClauses: []database.Condition{instanceRepo.NameCondition(database.TextOperationEqual, instanceName)},
|
||||
@@ -284,16 +310,15 @@ func TestGetInstance(t *testing.T) {
|
||||
}(),
|
||||
{
|
||||
name: "get non existent instance",
|
||||
testFunc: func() *domain.Instance {
|
||||
testFunc: func(ctx context.Context, t *testing.T) *domain.Instance {
|
||||
instanceId := gofakeit.Name()
|
||||
|
||||
inst := domain.Instance{
|
||||
_ = domain.Instance{
|
||||
ID: instanceId,
|
||||
}
|
||||
return &inst
|
||||
return nil
|
||||
},
|
||||
conditionClauses: []database.Condition{instanceRepo.NameCondition(database.TextOperationEqual, "non-existent-instance-name")},
|
||||
noInstanceReturned: true,
|
||||
conditionClauses: []database.Condition{instanceRepo.NameCondition(database.TextOperationEqual, "non-existent-instance-name")},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
@@ -303,58 +328,55 @@ func TestGetInstance(t *testing.T) {
|
||||
|
||||
var instance *domain.Instance
|
||||
if tt.testFunc != nil {
|
||||
instance = tt.testFunc()
|
||||
instance = tt.testFunc(ctx, t)
|
||||
}
|
||||
|
||||
// check instance values
|
||||
returnedInstance, err := instanceRepo.Get(ctx,
|
||||
tt.conditionClauses...,
|
||||
)
|
||||
assert.NoError(t, err)
|
||||
if tt.noInstanceReturned {
|
||||
assert.Nil(t, returnedInstance)
|
||||
require.NoError(t, err)
|
||||
if instance == nil {
|
||||
require.Nil(t, instance, returnedInstance)
|
||||
return
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, returnedInstance.ID, instance.ID)
|
||||
assert.Equal(t, returnedInstance.Name, instance.Name)
|
||||
assert.Equal(t, returnedInstance.DefaultOrgID, instance.DefaultOrgID)
|
||||
assert.Equal(t, returnedInstance.IAMProjectID, instance.IAMProjectID)
|
||||
assert.Equal(t, returnedInstance.ConsoleClientID, instance.ConsoleClientID)
|
||||
assert.Equal(t, returnedInstance.ConsoleAppID, instance.ConsoleAppID)
|
||||
assert.Equal(t, returnedInstance.DefaultLanguage, instance.DefaultLanguage)
|
||||
assert.NoError(t, err)
|
||||
require.Equal(t, returnedInstance.ID, instance.ID)
|
||||
require.Equal(t, returnedInstance.Name, instance.Name)
|
||||
require.Equal(t, returnedInstance.DefaultOrgID, instance.DefaultOrgID)
|
||||
require.Equal(t, returnedInstance.IAMProjectID, instance.IAMProjectID)
|
||||
require.Equal(t, returnedInstance.ConsoleClientID, instance.ConsoleClientID)
|
||||
require.Equal(t, returnedInstance.ConsoleAppID, instance.ConsoleAppID)
|
||||
require.Equal(t, returnedInstance.DefaultLanguage, instance.DefaultLanguage)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestListInstance(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
pool, stop, err := newEmbeddedDB(ctx)
|
||||
require.NoError(t, err)
|
||||
defer stop()
|
||||
|
||||
type test struct {
|
||||
name string
|
||||
testFunc func() ([]*domain.Instance, database.PoolTest, func())
|
||||
testFunc func(ctx context.Context, t *testing.T) []*domain.Instance
|
||||
conditionClauses []database.Condition
|
||||
noInstanceReturned bool
|
||||
}
|
||||
tests := []test{
|
||||
{
|
||||
name: "happy path single instance no filter",
|
||||
testFunc: func() ([]*domain.Instance, database.PoolTest, func()) {
|
||||
ctx := context.Background()
|
||||
// create new db to make sure no instances exist
|
||||
pool, stop, err := newEmbeededDB()
|
||||
assert.NoError(t, err)
|
||||
|
||||
testFunc: func(ctx context.Context, t *testing.T) []*domain.Instance {
|
||||
instanceRepo := repository.InstanceRepository(pool)
|
||||
noOfInstances := 1
|
||||
instances := make([]*domain.Instance, noOfInstances)
|
||||
for i := range noOfInstances {
|
||||
|
||||
instanceId := gofakeit.Name()
|
||||
instanceName := gofakeit.Name()
|
||||
|
||||
inst := domain.Instance{
|
||||
ID: instanceId,
|
||||
Name: instanceName,
|
||||
ID: gofakeit.Name(),
|
||||
Name: gofakeit.Name(),
|
||||
DefaultOrgID: "defaultOrgId",
|
||||
IAMProjectID: "iamProject",
|
||||
ConsoleClientID: "consoleCLient",
|
||||
@@ -364,33 +386,25 @@ func TestListInstance(t *testing.T) {
|
||||
|
||||
// create instance
|
||||
err := instanceRepo.Create(ctx, &inst)
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
|
||||
instances[i] = &inst
|
||||
}
|
||||
|
||||
return instances, pool, stop
|
||||
return instances
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "happy path multiple instance no filter",
|
||||
testFunc: func() ([]*domain.Instance, database.PoolTest, func()) {
|
||||
ctx := context.Background()
|
||||
// create new db to make sure no instances exist
|
||||
pool, stop, err := newEmbeededDB()
|
||||
assert.NoError(t, err)
|
||||
|
||||
testFunc: func(ctx context.Context, t *testing.T) []*domain.Instance {
|
||||
instanceRepo := repository.InstanceRepository(pool)
|
||||
noOfInstances := 5
|
||||
instances := make([]*domain.Instance, noOfInstances)
|
||||
for i := range noOfInstances {
|
||||
|
||||
instanceId := gofakeit.Name()
|
||||
instanceName := gofakeit.Name()
|
||||
|
||||
inst := domain.Instance{
|
||||
ID: instanceId,
|
||||
Name: instanceName,
|
||||
ID: gofakeit.Name(),
|
||||
Name: gofakeit.Name(),
|
||||
DefaultOrgID: "defaultOrgId",
|
||||
IAMProjectID: "iamProject",
|
||||
ConsoleClientID: "consoleCLient",
|
||||
@@ -400,12 +414,12 @@ func TestListInstance(t *testing.T) {
|
||||
|
||||
// create instance
|
||||
err := instanceRepo.Create(ctx, &inst)
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
|
||||
instances[i] = &inst
|
||||
}
|
||||
|
||||
return instances, pool, stop
|
||||
return instances
|
||||
},
|
||||
},
|
||||
func() test {
|
||||
@@ -413,18 +427,14 @@ func TestListInstance(t *testing.T) {
|
||||
instanceId := gofakeit.Name()
|
||||
return test{
|
||||
name: "instance filter on id",
|
||||
testFunc: func() ([]*domain.Instance, database.PoolTest, func()) {
|
||||
ctx := context.Background()
|
||||
|
||||
testFunc: func(ctx context.Context, t *testing.T) []*domain.Instance {
|
||||
noOfInstances := 1
|
||||
instances := make([]*domain.Instance, noOfInstances)
|
||||
for i := range noOfInstances {
|
||||
|
||||
instanceName := gofakeit.Name()
|
||||
|
||||
inst := domain.Instance{
|
||||
ID: instanceId,
|
||||
Name: instanceName,
|
||||
Name: gofakeit.Name(),
|
||||
DefaultOrgID: "defaultOrgId",
|
||||
IAMProjectID: "iamProject",
|
||||
ConsoleClientID: "consoleCLient",
|
||||
@@ -434,12 +444,12 @@ func TestListInstance(t *testing.T) {
|
||||
|
||||
// create instance
|
||||
err := instanceRepo.Create(ctx, &inst)
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
|
||||
instances[i] = &inst
|
||||
}
|
||||
|
||||
return instances, nil, nil
|
||||
return instances
|
||||
},
|
||||
conditionClauses: []database.Condition{instanceRepo.IDCondition(instanceId)},
|
||||
}
|
||||
@@ -449,17 +459,13 @@ func TestListInstance(t *testing.T) {
|
||||
instanceName := gofakeit.Name()
|
||||
return test{
|
||||
name: "multiple instance filter on name",
|
||||
testFunc: func() ([]*domain.Instance, database.PoolTest, func()) {
|
||||
ctx := context.Background()
|
||||
|
||||
testFunc: func(ctx context.Context, t *testing.T) []*domain.Instance {
|
||||
noOfInstances := 5
|
||||
instances := make([]*domain.Instance, noOfInstances)
|
||||
for i := range noOfInstances {
|
||||
|
||||
instanceId := gofakeit.Name()
|
||||
|
||||
inst := domain.Instance{
|
||||
ID: instanceId,
|
||||
ID: gofakeit.Name(),
|
||||
Name: instanceName,
|
||||
DefaultOrgID: "defaultOrgId",
|
||||
IAMProjectID: "iamProject",
|
||||
@@ -470,12 +476,12 @@ func TestListInstance(t *testing.T) {
|
||||
|
||||
// create instance
|
||||
err := instanceRepo.Create(ctx, &inst)
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
|
||||
instances[i] = &inst
|
||||
}
|
||||
|
||||
return instances, nil, nil
|
||||
return instances
|
||||
},
|
||||
conditionClauses: []database.Condition{instanceRepo.NameCondition(database.TextOperationEqual, instanceName)},
|
||||
}
|
||||
@@ -483,42 +489,34 @@ func TestListInstance(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
t.Cleanup(func() {
|
||||
_, err := pool.Exec(ctx, "DELETE FROM zitadel.instances")
|
||||
require.NoError(t, err)
|
||||
})
|
||||
|
||||
var instances []*domain.Instance
|
||||
instances := tt.testFunc(ctx, t)
|
||||
|
||||
pool := pool
|
||||
if tt.testFunc != nil {
|
||||
var stop func()
|
||||
var pool_ database.PoolTest
|
||||
instances, pool_, stop = tt.testFunc()
|
||||
if pool_ != nil {
|
||||
pool = pool_
|
||||
defer stop()
|
||||
}
|
||||
}
|
||||
instanceRepo := repository.InstanceRepository(pool)
|
||||
|
||||
// check instance values
|
||||
returnedInstances, err := instanceRepo.List(ctx,
|
||||
tt.conditionClauses...,
|
||||
)
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
if tt.noInstanceReturned {
|
||||
assert.Nil(t, returnedInstances)
|
||||
require.Nil(t, returnedInstances)
|
||||
return
|
||||
}
|
||||
|
||||
assert.Equal(t, len(instances), len(returnedInstances))
|
||||
require.Equal(t, len(instances), len(returnedInstances))
|
||||
for i, instance := range instances {
|
||||
assert.Equal(t, returnedInstances[i].ID, instance.ID)
|
||||
assert.Equal(t, returnedInstances[i].Name, instance.Name)
|
||||
assert.Equal(t, returnedInstances[i].DefaultOrgID, instance.DefaultOrgID)
|
||||
assert.Equal(t, returnedInstances[i].IAMProjectID, instance.IAMProjectID)
|
||||
assert.Equal(t, returnedInstances[i].ConsoleClientID, instance.ConsoleClientID)
|
||||
assert.Equal(t, returnedInstances[i].ConsoleAppID, instance.ConsoleAppID)
|
||||
assert.Equal(t, returnedInstances[i].DefaultLanguage, instance.DefaultLanguage)
|
||||
assert.NoError(t, err)
|
||||
require.Equal(t, returnedInstances[i].ID, instance.ID)
|
||||
require.Equal(t, returnedInstances[i].Name, instance.Name)
|
||||
require.Equal(t, returnedInstances[i].DefaultOrgID, instance.DefaultOrgID)
|
||||
require.Equal(t, returnedInstances[i].IAMProjectID, instance.IAMProjectID)
|
||||
require.Equal(t, returnedInstances[i].ConsoleClientID, instance.ConsoleClientID)
|
||||
require.Equal(t, returnedInstances[i].ConsoleAppID, instance.ConsoleAppID)
|
||||
require.Equal(t, returnedInstances[i].DefaultLanguage, instance.DefaultLanguage)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -527,7 +525,7 @@ func TestListInstance(t *testing.T) {
|
||||
func TestDeleteInstance(t *testing.T) {
|
||||
type test struct {
|
||||
name string
|
||||
testFunc func()
|
||||
testFunc func(ctx context.Context, t *testing.T)
|
||||
conditionClauses database.Condition
|
||||
}
|
||||
tests := []test{
|
||||
@@ -536,18 +534,14 @@ func TestDeleteInstance(t *testing.T) {
|
||||
instanceId := gofakeit.Name()
|
||||
return test{
|
||||
name: "happy path delete single instance filter id",
|
||||
testFunc: func() {
|
||||
ctx := context.Background()
|
||||
|
||||
testFunc: func(ctx context.Context, t *testing.T) {
|
||||
noOfInstances := 1
|
||||
instances := make([]*domain.Instance, noOfInstances)
|
||||
for i := range noOfInstances {
|
||||
|
||||
instanceName := gofakeit.Name()
|
||||
|
||||
inst := domain.Instance{
|
||||
ID: instanceId,
|
||||
Name: instanceName,
|
||||
Name: gofakeit.Name(),
|
||||
DefaultOrgID: "defaultOrgId",
|
||||
IAMProjectID: "iamProject",
|
||||
ConsoleClientID: "consoleCLient",
|
||||
@@ -557,7 +551,7 @@ func TestDeleteInstance(t *testing.T) {
|
||||
|
||||
// create instance
|
||||
err := instanceRepo.Create(ctx, &inst)
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
|
||||
instances[i] = &inst
|
||||
}
|
||||
@@ -570,17 +564,13 @@ func TestDeleteInstance(t *testing.T) {
|
||||
instanceName := gofakeit.Name()
|
||||
return test{
|
||||
name: "happy path delete single instance filter name",
|
||||
testFunc: func() {
|
||||
ctx := context.Background()
|
||||
|
||||
testFunc: func(ctx context.Context, t *testing.T) {
|
||||
noOfInstances := 1
|
||||
instances := make([]*domain.Instance, noOfInstances)
|
||||
for i := range noOfInstances {
|
||||
|
||||
instanceId := gofakeit.Name()
|
||||
|
||||
inst := domain.Instance{
|
||||
ID: instanceId,
|
||||
ID: gofakeit.Name(),
|
||||
Name: instanceName,
|
||||
DefaultOrgID: "defaultOrgId",
|
||||
IAMProjectID: "iamProject",
|
||||
@@ -591,7 +581,7 @@ func TestDeleteInstance(t *testing.T) {
|
||||
|
||||
// create instance
|
||||
err := instanceRepo.Create(ctx, &inst)
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
|
||||
instances[i] = &inst
|
||||
}
|
||||
@@ -612,17 +602,13 @@ func TestDeleteInstance(t *testing.T) {
|
||||
instanceName := gofakeit.Name()
|
||||
return test{
|
||||
name: "multiple instance filter on name",
|
||||
testFunc: func() {
|
||||
ctx := context.Background()
|
||||
|
||||
testFunc: func(ctx context.Context, t *testing.T) {
|
||||
noOfInstances := 5
|
||||
instances := make([]*domain.Instance, noOfInstances)
|
||||
for i := range noOfInstances {
|
||||
|
||||
instanceId := gofakeit.Name()
|
||||
|
||||
inst := domain.Instance{
|
||||
ID: instanceId,
|
||||
ID: gofakeit.Name(),
|
||||
Name: instanceName,
|
||||
DefaultOrgID: "defaultOrgId",
|
||||
IAMProjectID: "iamProject",
|
||||
@@ -633,7 +619,7 @@ func TestDeleteInstance(t *testing.T) {
|
||||
|
||||
// create instance
|
||||
err := instanceRepo.Create(ctx, &inst)
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
|
||||
instances[i] = &inst
|
||||
}
|
||||
@@ -646,17 +632,13 @@ func TestDeleteInstance(t *testing.T) {
|
||||
instanceName := gofakeit.Name()
|
||||
return test{
|
||||
name: "deleted already deleted instance",
|
||||
testFunc: func() {
|
||||
ctx := context.Background()
|
||||
|
||||
testFunc: func(ctx context.Context, t *testing.T) {
|
||||
noOfInstances := 1
|
||||
instances := make([]*domain.Instance, noOfInstances)
|
||||
for i := range noOfInstances {
|
||||
|
||||
instanceId := gofakeit.Name()
|
||||
|
||||
inst := domain.Instance{
|
||||
ID: instanceId,
|
||||
ID: gofakeit.Name(),
|
||||
Name: instanceName,
|
||||
DefaultOrgID: "defaultOrgId",
|
||||
IAMProjectID: "iamProject",
|
||||
@@ -667,7 +649,7 @@ func TestDeleteInstance(t *testing.T) {
|
||||
|
||||
// create instance
|
||||
err := instanceRepo.Create(ctx, &inst)
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
|
||||
instances[i] = &inst
|
||||
}
|
||||
@@ -676,7 +658,7 @@ func TestDeleteInstance(t *testing.T) {
|
||||
err := instanceRepo.Delete(ctx,
|
||||
instanceRepo.NameCondition(database.TextOperationEqual, instanceName),
|
||||
)
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
},
|
||||
conditionClauses: instanceRepo.NameCondition(database.TextOperationEqual, instanceName),
|
||||
}
|
||||
@@ -688,21 +670,21 @@ func TestDeleteInstance(t *testing.T) {
|
||||
instanceRepo := repository.InstanceRepository(pool)
|
||||
|
||||
if tt.testFunc != nil {
|
||||
tt.testFunc()
|
||||
tt.testFunc(ctx, t)
|
||||
}
|
||||
|
||||
// delete instance
|
||||
err := instanceRepo.Delete(ctx,
|
||||
tt.conditionClauses,
|
||||
)
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
|
||||
// check instance was deleted
|
||||
instance, err := instanceRepo.Get(ctx,
|
||||
tt.conditionClauses,
|
||||
)
|
||||
assert.NoError(t, err)
|
||||
assert.Nil(t, instance)
|
||||
require.NoError(t, err)
|
||||
require.Nil(t, instance)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@@ -3,6 +3,5 @@ package repository
|
||||
import "github.com/zitadel/zitadel/backend/v3/storage/database"
|
||||
|
||||
type repository struct {
|
||||
// builder database.StatementBuilder
|
||||
client database.QueryExecutor
|
||||
}
|
||||
|
@@ -20,9 +20,10 @@ var pool database.PoolTest
|
||||
func runTests(m *testing.M) int {
|
||||
var stop func()
|
||||
var err error
|
||||
pool, stop, err = newEmbeededDB()
|
||||
ctx := context.Background()
|
||||
pool, stop, err = newEmbeddedDB(ctx)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
log.Printf("error with embedded postgres database: %v", err)
|
||||
return 1
|
||||
}
|
||||
defer stop()
|
||||
@@ -30,24 +31,21 @@ func runTests(m *testing.M) int {
|
||||
return m.Run()
|
||||
}
|
||||
|
||||
func newEmbeededDB() (pool database.PoolTest, stop func(), err error) {
|
||||
var connector database.Connector
|
||||
connector, stop, err = embedded.StartEmbedded()
|
||||
func newEmbeddedDB(ctx context.Context) (pool database.PoolTest, stop func(), err error) {
|
||||
connector, stop, err := embedded.StartEmbedded()
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("unable to start embedded postgres: %v", err)
|
||||
return nil, nil, fmt.Errorf("unable to start embedded postgres: %w", err)
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
pool_, err := connector.Connect(ctx)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("unable to connect to embedded postgres: %v", err)
|
||||
return nil, nil, fmt.Errorf("unable to connect to embedded postgres: %w", err)
|
||||
}
|
||||
pool = pool_.(database.PoolTest)
|
||||
|
||||
err = pool.MigrateTest(ctx)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("unable to migrate database: %v", err)
|
||||
return nil, nil, fmt.Errorf("unable to migrate database: %w", err)
|
||||
}
|
||||
return pool, stop, err
|
||||
}
|
||||
|
@@ -191,18 +191,18 @@ func (h userHuman) PhoneVerifiedAtColumn() database.Column {
|
||||
return database.NewColumn("phone_verified_at")
|
||||
}
|
||||
|
||||
func (h userHuman) columns() database.Columns {
|
||||
return append(h.user.columns(),
|
||||
h.FirstNameColumn(),
|
||||
h.LastNameColumn(),
|
||||
h.EmailAddressColumn(),
|
||||
h.EmailVerifiedAtColumn(),
|
||||
h.PhoneNumberColumn(),
|
||||
h.PhoneVerifiedAtColumn(),
|
||||
)
|
||||
}
|
||||
// func (h userHuman) columns() database.Columns {
|
||||
// return append(h.user.columns(),
|
||||
// h.FirstNameColumn(),
|
||||
// h.LastNameColumn(),
|
||||
// h.EmailAddressColumn(),
|
||||
// h.EmailVerifiedAtColumn(),
|
||||
// h.PhoneNumberColumn(),
|
||||
// h.PhoneVerifiedAtColumn(),
|
||||
// )
|
||||
// }
|
||||
|
||||
func (h userHuman) writeReturning(builder *database.StatementBuilder) {
|
||||
builder.WriteString(" RETURNING ")
|
||||
h.columns().Write(builder)
|
||||
}
|
||||
// func (h userHuman) writeReturning(builder *database.StatementBuilder) {
|
||||
// builder.WriteString(" RETURNING ")
|
||||
// h.columns().Write(builder)
|
||||
// }
|
||||
|
@@ -5,11 +5,10 @@ package repository_test
|
||||
// "testing"
|
||||
|
||||
// "github.com/stretchr/testify/assert"
|
||||
// "go.uber.org/mock/gomock"
|
||||
|
||||
// "github.com/zitadel/zitadel/backend/v3/storage/database"
|
||||
// "github.com/zitadel/zitadel/backend/v3/storage/database/dbmock"
|
||||
// "github.com/zitadel/zitadel/backend/v3/storage/database/repository"
|
||||
// "go.uber.org/mock/gomock"
|
||||
// )
|
||||
|
||||
// func TestQueryUser(t *testing.T) {
|
||||
@@ -75,3 +74,4 @@ package repository_test
|
||||
// user.Human().Update(context.Background(), user.IDCondition("test"), user.SetUsername("test"))
|
||||
// })
|
||||
// }
|
||||
|
||||
|
Reference in New Issue
Block a user