mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-12 00:57:33 +00:00
tie loose ends, documentation
This commit is contained in:
@@ -13,13 +13,29 @@ type DetailsMsg interface {
|
||||
GetDetails() *object.Details
|
||||
}
|
||||
|
||||
// AssertDetails asserts values in a message's object Details,
|
||||
// if the object Details in expected is a non-nil value.
|
||||
// It targets API v2 messages that have the `GetDetails()` method.
|
||||
//
|
||||
// Dynamically generated values are not compared with expected.
|
||||
// Instead a sanity check is performed.
|
||||
// For the sequence a non-zero value is expected.
|
||||
// The change date has to be now, with a tollerance of 1 second.
|
||||
//
|
||||
// The resource owner is compared with expected and is
|
||||
// therefore the only value that has to be set.
|
||||
func AssertDetails[D DetailsMsg](t testing.TB, exptected, actual D) {
|
||||
wantDetails, gotDetails := exptected.GetDetails(), actual.GetDetails()
|
||||
|
||||
if wantDetails != nil {
|
||||
assert.NotZero(t, gotDetails.GetSequence())
|
||||
if wantDetails == nil {
|
||||
assert.Nil(t, gotDetails)
|
||||
return
|
||||
}
|
||||
wantCD, gotCD := wantDetails.GetChangeDate().AsTime(), gotDetails.GetChangeDate().AsTime()
|
||||
assert.WithinRange(t, gotCD, wantCD, wantCD.Add(time.Minute))
|
||||
|
||||
assert.NotZero(t, gotDetails.GetSequence())
|
||||
|
||||
gotCD := gotDetails.GetChangeDate().AsTime()
|
||||
now := time.Now()
|
||||
assert.WithinRange(t, gotCD, now.Add(-time.Second), now.Add(time.Second))
|
||||
|
||||
assert.Equal(t, wantDetails.GetResourceOwner(), gotDetails.GetResourceOwner())
|
||||
}
|
||||
|
51
internal/integration/assert_test.go
Normal file
51
internal/integration/assert_test.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package integration
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
|
||||
object "github.com/zitadel/zitadel/pkg/grpc/object/v2alpha"
|
||||
)
|
||||
|
||||
type myMsg struct {
|
||||
details *object.Details
|
||||
}
|
||||
|
||||
func (m myMsg) GetDetails() *object.Details {
|
||||
return m.details
|
||||
}
|
||||
|
||||
func TestAssertDetails(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
exptected myMsg
|
||||
actual myMsg
|
||||
}{
|
||||
{
|
||||
name: "nil",
|
||||
exptected: myMsg{},
|
||||
actual: myMsg{},
|
||||
},
|
||||
{
|
||||
name: "values",
|
||||
exptected: myMsg{
|
||||
details: &object.Details{
|
||||
ResourceOwner: "me",
|
||||
},
|
||||
},
|
||||
actual: myMsg{
|
||||
details: &object.Details{
|
||||
Sequence: 123,
|
||||
ChangeDate: timestamppb.Now(),
|
||||
ResourceOwner: "me",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
AssertDetails(t, tt.exptected, tt.actual)
|
||||
})
|
||||
}
|
||||
}
|
24
internal/integration/config/docker-compose.yaml
Normal file
24
internal/integration/config/docker-compose.yaml
Normal file
@@ -0,0 +1,24 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
cockroach:
|
||||
extends:
|
||||
file: '../../../e2e/config/localhost/docker-compose.yaml'
|
||||
service: 'db'
|
||||
|
||||
postgres:
|
||||
restart: 'always'
|
||||
image: 'postgres:15'
|
||||
environment:
|
||||
- POSTGRES_USER=zitadel
|
||||
- PGUSER=zitadel
|
||||
- POSTGRES_DB=zitadel
|
||||
- POSTGRES_HOST_AUTH_METHOD=trust
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready"]
|
||||
interval: '10s'
|
||||
timeout: '30s'
|
||||
retries: 5
|
||||
start_period: '20s'
|
||||
ports:
|
||||
- 5432:5432
|
@@ -41,6 +41,11 @@ var (
|
||||
postgresYAML []byte
|
||||
)
|
||||
|
||||
// UserType provides constants that give
|
||||
// a short explinanation with the purpose
|
||||
// a serverice user.
|
||||
// This allows to pre-create users with
|
||||
// different permissions and reuse them.
|
||||
type UserType int
|
||||
|
||||
//go:generate stringer -type=UserType
|
||||
@@ -49,11 +54,13 @@ const (
|
||||
OrgOwner
|
||||
)
|
||||
|
||||
// User information with a Personal Access Token.
|
||||
type User struct {
|
||||
*query.User
|
||||
Token string
|
||||
}
|
||||
|
||||
// Tester is a Zitadel server and client with all resources available for testing.
|
||||
type Tester struct {
|
||||
*start.Server
|
||||
|
||||
@@ -113,7 +120,7 @@ func (s *Tester) pollHealth(ctx context.Context) (err error) {
|
||||
}
|
||||
|
||||
const (
|
||||
SystemUser = "integration1"
|
||||
SystemUser = "integration"
|
||||
)
|
||||
|
||||
func (s *Tester) createSystemUser(ctx context.Context) {
|
||||
@@ -169,6 +176,7 @@ func (s *Tester) WithSystemAuthorization(ctx context.Context, u UserType) contex
|
||||
return metadata.AppendToOutgoingContext(ctx, "Authorization", fmt.Sprintf("Bearer %s", s.Users[u].Token))
|
||||
}
|
||||
|
||||
// Done send an interrupt signal to cleanly shutdown the server.
|
||||
func (s *Tester) Done() {
|
||||
err := s.GRPCClientConn.Close()
|
||||
logging.OnError(err).Error("integration tester client close")
|
||||
@@ -177,6 +185,20 @@ func (s *Tester) Done() {
|
||||
s.wg.Wait()
|
||||
}
|
||||
|
||||
// NewTester start a new Zitadel server by passing the default commandline.
|
||||
// The server will listen on the configured port.
|
||||
// The database configuration that will be used can be set by the
|
||||
// INTEGRATION_DB_FLAVOR environment variable and can have the values "cockroach"
|
||||
// or "postgres". Defaults to "cockroach".
|
||||
//
|
||||
// The deault Instance and Organisation are read from the DB and system
|
||||
// users are created as needed.
|
||||
//
|
||||
// After the server is started, a [grpc.ClientConn] will be created and
|
||||
// the server is polled for it's health status.
|
||||
//
|
||||
// Note: the database must already be setup and intialized before
|
||||
// using NewTester. See the CONTRIBUTING.md document for details.
|
||||
func NewTester(ctx context.Context) *Tester {
|
||||
args := strings.Split(commandLine, " ")
|
||||
|
||||
|
Reference in New Issue
Block a user