snapshot of https://github.com/ory/kratos.git (master, 2026-09-15; blobs > 131072B omitted)
Some checks failed
CI / Run tests and lints (push) Failing after 29s
CI / Build CLI docs (push) Has been skipped
CI / Run Playwright end-to-end tests (mysql) (push) Failing after 3s
CI / Run Playwright end-to-end tests (postgres) (push) Failing after 2s
CI / Run Playwright end-to-end tests (sqlite) (push) Failing after 3s
CodeQL / Analyze (go) (push) Failing after 4s
CodeQL / Analyze (javascript) (push) Failing after 3s
Docker Image Scanners / scanners (push) Failing after 4s
Synchronize Issue Labels / Synchronize Issue Labels (push) Has been skipped
CI / Run end-to-end tests (postgres) (push) Failing after 19s
CI / Run end-to-end tests (sqlite) (push) Failing after 2s
CI / Run Playwright end-to-end tests (cockroach) (push) Failing after 2s
CI / Draft newsletter (push) Has been skipped
CI / Generate release (push) Has been skipped
CI / Pending approval Slack notification (push) Has been skipped
CI / Send newsletter (push) Has been skipped
Some checks failed
CI / Run tests and lints (push) Failing after 29s
CI / Build CLI docs (push) Has been skipped
CI / Run Playwright end-to-end tests (mysql) (push) Failing after 3s
CI / Run Playwright end-to-end tests (postgres) (push) Failing after 2s
CI / Run Playwright end-to-end tests (sqlite) (push) Failing after 3s
CodeQL / Analyze (go) (push) Failing after 4s
CodeQL / Analyze (javascript) (push) Failing after 3s
Docker Image Scanners / scanners (push) Failing after 4s
Synchronize Issue Labels / Synchronize Issue Labels (push) Has been skipped
CI / Run end-to-end tests (postgres) (push) Failing after 19s
CI / Run end-to-end tests (sqlite) (push) Failing after 2s
CI / Run Playwright end-to-end tests (cockroach) (push) Failing after 2s
CI / Draft newsletter (push) Has been skipped
CI / Generate release (push) Has been skipped
CI / Pending approval Slack notification (push) Has been skipped
CI / Send newsletter (push) Has been skipped
This commit is contained in:
240
persistence/sql/batch/create_test.go
Normal file
240
persistence/sql/batch/create_test.go
Normal file
@@ -0,0 +1,240 @@
|
||||
// Copyright © 2023 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package batch
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gofrs/uuid"
|
||||
"github.com/jmoiron/sqlx/reflectx"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/ory/kratos/identity"
|
||||
"github.com/ory/x/dbal"
|
||||
"github.com/ory/x/snapshotx"
|
||||
"github.com/ory/x/sqlxx"
|
||||
)
|
||||
|
||||
type (
|
||||
testModel struct {
|
||||
ID uuid.UUID `db:"id"`
|
||||
NID uuid.UUID `db:"nid"`
|
||||
String string `db:"string"`
|
||||
Int int `db:"int"`
|
||||
Traits identity.Traits `db:"traits"`
|
||||
NullTimePtr *sqlxx.NullTime `db:"null_time_ptr"`
|
||||
CreatedAt time.Time `json:"created_at" db:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at" db:"updated_at"`
|
||||
}
|
||||
testQuoter struct{}
|
||||
)
|
||||
|
||||
func (i testModel) TableName(ctx context.Context) string {
|
||||
return "test_models"
|
||||
}
|
||||
|
||||
func (tq testQuoter) Quote(s string) string { return fmt.Sprintf("%q", s) }
|
||||
|
||||
func makeModels[T any]() []*T {
|
||||
models := make([]*T, 10)
|
||||
for k := range models {
|
||||
models[k] = new(T)
|
||||
}
|
||||
return models
|
||||
}
|
||||
|
||||
func Test_buildInsertQueryArgs(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
t.Run("case=testModel", func(t *testing.T) {
|
||||
models := makeModels[testModel]()
|
||||
opts := &createOpts{
|
||||
dialect: "other",
|
||||
quoter: testQuoter{},
|
||||
mapper: reflectx.NewMapper("db"),
|
||||
}
|
||||
args := buildInsertQueryArgs(ctx, models, opts)
|
||||
snapshotx.SnapshotT(t, args)
|
||||
|
||||
query := fmt.Sprintf("INSERT INTO %s (%s) VALUES\n%s", args.TableName, args.ColumnsDecl, args.Placeholders)
|
||||
assert.Equal(t, `INSERT INTO "test_models" ("created_at", "id", "int", "nid", "null_time_ptr", "string", "traits", "updated_at") VALUES
|
||||
(?, ?, ?, ?, ?, ?, ?, ?),
|
||||
(?, ?, ?, ?, ?, ?, ?, ?),
|
||||
(?, ?, ?, ?, ?, ?, ?, ?),
|
||||
(?, ?, ?, ?, ?, ?, ?, ?),
|
||||
(?, ?, ?, ?, ?, ?, ?, ?),
|
||||
(?, ?, ?, ?, ?, ?, ?, ?),
|
||||
(?, ?, ?, ?, ?, ?, ?, ?),
|
||||
(?, ?, ?, ?, ?, ?, ?, ?),
|
||||
(?, ?, ?, ?, ?, ?, ?, ?),
|
||||
(?, ?, ?, ?, ?, ?, ?, ?)`, query)
|
||||
})
|
||||
|
||||
t.Run("case=Identities", func(t *testing.T) {
|
||||
models := makeModels[identity.Identity]()
|
||||
opts := &createOpts{
|
||||
dialect: "other",
|
||||
quoter: testQuoter{},
|
||||
mapper: reflectx.NewMapper("db"),
|
||||
}
|
||||
args := buildInsertQueryArgs(ctx, models, opts)
|
||||
snapshotx.SnapshotT(t, args)
|
||||
})
|
||||
|
||||
t.Run("case=RecoveryAddress", func(t *testing.T) {
|
||||
models := makeModels[identity.RecoveryAddress]()
|
||||
opts := &createOpts{
|
||||
dialect: "other",
|
||||
quoter: testQuoter{},
|
||||
mapper: reflectx.NewMapper("db"),
|
||||
}
|
||||
args := buildInsertQueryArgs(ctx, models, opts)
|
||||
snapshotx.SnapshotT(t, args)
|
||||
})
|
||||
|
||||
t.Run("case=RecoveryAddress", func(t *testing.T) {
|
||||
models := makeModels[identity.RecoveryAddress]()
|
||||
opts := &createOpts{
|
||||
dialect: "other",
|
||||
quoter: testQuoter{},
|
||||
mapper: reflectx.NewMapper("db"),
|
||||
}
|
||||
args := buildInsertQueryArgs(ctx, models, opts)
|
||||
snapshotx.SnapshotT(t, args)
|
||||
})
|
||||
|
||||
t.Run("case=cockroach", func(t *testing.T) {
|
||||
models := makeModels[testModel]()
|
||||
for k := range models {
|
||||
if k%3 == 0 {
|
||||
models[k].ID = uuid.FromStringOrNil(fmt.Sprintf("ae0125a9-2786-4ada-82d2-d169cf75047%d", k))
|
||||
}
|
||||
}
|
||||
opts := &createOpts{
|
||||
dialect: dbal.DriverCockroachDB,
|
||||
quoter: testQuoter{},
|
||||
mapper: reflectx.NewMapper("db"),
|
||||
}
|
||||
args := buildInsertQueryArgs(ctx, models, opts)
|
||||
snapshotx.SnapshotT(t, args)
|
||||
})
|
||||
|
||||
for _, dialect := range []string{dbal.DriverPostgreSQL, dbal.DriverCockroachDB, dbal.DriverYugabyteDB} {
|
||||
t.Run("case=database generated UUID/"+dialect, func(t *testing.T) {
|
||||
models := makeModels[testModel]()
|
||||
opts := &createOpts{
|
||||
dialect: dialect,
|
||||
quoter: testQuoter{},
|
||||
mapper: reflectx.NewMapper("db"),
|
||||
}
|
||||
args := buildInsertQueryArgs(ctx, models, opts)
|
||||
assert.Contains(t, args.Placeholders, "gen_random_uuid()")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_buildInsertQueryArgs_ExtraColumns(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
t.Run("case=testModel", func(t *testing.T) {
|
||||
models := makeModels[testModel]()
|
||||
opts := &createOpts{
|
||||
dialect: "other",
|
||||
quoter: testQuoter{},
|
||||
mapper: reflectx.NewMapper("db"),
|
||||
extraColumns: []identity.ExtraColumn{{K: "crdb_region", V: "gcp-europe-west3"}},
|
||||
}
|
||||
args := buildInsertQueryArgs(ctx, models, opts)
|
||||
snapshotx.SnapshotT(t, args)
|
||||
|
||||
assert.Contains(t, args.ColumnsDecl, `"crdb_region"`)
|
||||
assert.Contains(t, args.Placeholders, "?")
|
||||
})
|
||||
}
|
||||
|
||||
func Test_buildInsertQueryValues_ExtraColumns(t *testing.T) {
|
||||
t.Run("case=testModel", func(t *testing.T) {
|
||||
model := &testModel{
|
||||
String: "string",
|
||||
Int: 42,
|
||||
Traits: []byte(`{"foo": "bar"}`),
|
||||
}
|
||||
|
||||
frozenTime := time.Date(2023, 1, 1, 0, 0, 0, 0, time.UTC)
|
||||
opts := &createOpts{
|
||||
dialect: "other",
|
||||
mapper: reflectx.NewMapper("db"),
|
||||
quoter: testQuoter{},
|
||||
now: func() time.Time { return frozenTime },
|
||||
extraColumns: []identity.ExtraColumn{{K: "crdb_region", V: "gcp-europe-west3"}},
|
||||
}
|
||||
|
||||
// columns includes the extra column name, mirroring what buildInsertQueryArgs returns.
|
||||
values, err := buildInsertQueryValues(
|
||||
[]string{"created_at", "updated_at", "id", "string", "int", "null_time_ptr", "traits", "crdb_region"},
|
||||
[]*testModel{model},
|
||||
opts,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
// The last value should be the extra column value.
|
||||
// 7 model fields + 1 extra column = 8 total.
|
||||
require.Len(t, values, 8)
|
||||
assert.Equal(t, "gcp-europe-west3", values[len(values)-1])
|
||||
})
|
||||
}
|
||||
|
||||
func Test_buildInsertQueryValues(t *testing.T) {
|
||||
t.Run("case=testModel", func(t *testing.T) {
|
||||
model := &testModel{
|
||||
String: "string",
|
||||
Int: 42,
|
||||
Traits: []byte(`{"foo": "bar"}`),
|
||||
}
|
||||
|
||||
frozenTime := time.Date(2023, 1, 1, 0, 0, 0, 0, time.UTC)
|
||||
opts := &createOpts{
|
||||
mapper: reflectx.NewMapper("db"),
|
||||
quoter: testQuoter{},
|
||||
now: func() time.Time { return frozenTime },
|
||||
}
|
||||
|
||||
t.Run("case=cockroach", func(t *testing.T) {
|
||||
opts.dialect = dbal.DriverCockroachDB
|
||||
values, err := buildInsertQueryValues(
|
||||
[]string{"created_at", "updated_at", "id", "string", "int", "null_time_ptr", "traits"},
|
||||
[]*testModel{model},
|
||||
opts,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
snapshotx.SnapshotT(t, values)
|
||||
})
|
||||
|
||||
t.Run("case=others", func(t *testing.T) {
|
||||
opts.dialect = "other"
|
||||
values, err := buildInsertQueryValues(
|
||||
[]string{"created_at", "updated_at", "id", "string", "int", "null_time_ptr", "traits"},
|
||||
[]*testModel{model},
|
||||
opts,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, frozenTime, model.CreatedAt)
|
||||
assert.Equal(t, model.CreatedAt, values[0])
|
||||
|
||||
assert.Equal(t, frozenTime, model.UpdatedAt)
|
||||
assert.Equal(t, model.UpdatedAt, values[1])
|
||||
|
||||
assert.NotZero(t, model.ID)
|
||||
assert.Equal(t, model.ID, values[2])
|
||||
|
||||
assert.Equal(t, model.String, values[3])
|
||||
assert.Equal(t, model.Int, values[4])
|
||||
|
||||
assert.Nil(t, model.NullTimePtr)
|
||||
})
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user