fixup! fixup! fixup! fixup! refactor(api): moving organization API resourced based

added ListOrganizations() tests incompletel
This commit is contained in:
Iraq Jaber
2025-04-29 13:43:37 +02:00
parent 6d73b8e3ad
commit 0121478b93
5 changed files with 339 additions and 21 deletions

View File

@@ -3,11 +3,13 @@ package org
import (
"time"
object "github.com/zitadel/zitadel/internal/api/grpc/object/v2beta"
v2beta_object "github.com/zitadel/zitadel/internal/api/grpc/object/v2beta"
"github.com/zitadel/zitadel/internal/command"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/query"
"github.com/zitadel/zitadel/internal/zerrors"
org "github.com/zitadel/zitadel/pkg/grpc/org/v2beta"
v2beta_org "github.com/zitadel/zitadel/pkg/grpc/org/v2beta"
v2beta "github.com/zitadel/zitadel/pkg/grpc/object/v2beta"
@@ -15,6 +17,27 @@ import (
"google.golang.org/protobuf/types/known/timestamppb"
)
// NOTE: most of this code is copied from `internal/api/grpc/admin/*`, as we will eventually axe the previous versons of the API,
// we will have code duplication until then
func listOrgRequestToModel(request *v2beta_org.ListOrganizationsRequest) (*query.OrgSearchQueries, error) {
offset, limit, asc := v2beta_object.ListQueryToModel(request.Query)
// queries, err := org_pb.OrgQueriesToModel(request.Queries)
queries, err := OrgQueriesToModel(request.Queries)
if err != nil {
return nil, err
}
return &query.OrgSearchQueries{
SearchRequest: query.SearchRequest{
Offset: offset,
Limit: limit,
SortingColumn: FieldNameToOrgColumn(request.SortingColumn),
Asc: asc,
},
Queries: queries,
}, nil
}
func OrganizationViewToPb(org *query.Org) *org_pb.Organization {
return &org_pb.Organization{
Id: org.ID,
@@ -70,8 +93,81 @@ func createdOrganizationToPb(createdOrg *command.CreatedOrg) (_ *org.CreateOrgan
}
}
return &org.CreateOrganizationResponse{
Details: object.DomainToDetailsPb(createdOrg.ObjectDetails),
Details: v2beta_object.DomainToDetailsPb(createdOrg.ObjectDetails),
OrganizationId: createdOrg.ObjectDetails.ResourceOwner,
CreatedAdmins: admins,
}, nil
}
func OrgViewsToPb(orgs []*query.Org) []*org_pb.Organization {
o := make([]*org_pb.Organization, len(orgs))
for i, org := range orgs {
o[i] = OrgViewToPb(org)
}
return o
}
func OrgQueriesToModel(queries []*org_pb.OrgQuery) (_ []query.SearchQuery, err error) {
q := make([]query.SearchQuery, len(queries))
for i, query := range queries {
q[i], err = OrgQueryToModel(query)
if err != nil {
return nil, err
}
}
return q, nil
}
func OrgQueryToModel(apiQuery *org_pb.OrgQuery) (query.SearchQuery, error) {
switch q := apiQuery.Query.(type) {
case *org_pb.OrgQuery_DomainQuery:
return query.NewOrgVerifiedDomainSearchQuery(v2beta_object.TextMethodToQuery(q.DomainQuery.Method), q.DomainQuery.Domain)
case *org_pb.OrgQuery_NameQuery:
return query.NewOrgNameSearchQuery(v2beta_object.TextMethodToQuery(q.NameQuery.Method), q.NameQuery.Name)
case *org_pb.OrgQuery_StateQuery:
return query.NewOrgStateSearchQuery(OrgStateToDomain(q.StateQuery.State))
case *org_pb.OrgQuery_IdQuery:
return query.NewOrgIDSearchQuery(q.IdQuery.Id)
default:
return nil, zerrors.ThrowInvalidArgument(nil, "ORG-vR9nC", "List.Query.Invalid")
}
}
func OrgStateToDomain(state org_pb.OrgState) domain.OrgState {
switch state {
case org_pb.OrgState_ORG_STATE_ACTIVE:
return domain.OrgStateActive
case org_pb.OrgState_ORG_STATE_INACTIVE:
return domain.OrgStateInactive
case org_pb.OrgState_ORG_STATE_UNSPECIFIED:
fallthrough
default:
return domain.OrgStateUnspecified
}
}
func FieldNameToOrgColumn(fieldName org_pb.OrgFieldName) query.Column {
switch fieldName {
case org_pb.OrgFieldName_ORG_FIELD_NAME_NAME:
return query.OrgColumnName
case org_pb.OrgFieldName_ORG_FIELD_NAME_UNSPECIFIED:
return query.Column{}
default:
return query.Column{}
}
}
func OrgViewToPb(org *query.Org) *org_pb.Organization {
return &org_pb.Organization{
Id: org.ID,
State: OrgStateToPb(org.State),
Name: org.Name,
PrimaryDomain: org.Domain,
Details: ToViewDetailsPb(
org.Sequence,
org.CreationDate,
org.ChangeDate,
org.ResourceOwner,
),
}
}

View File

@@ -4,6 +4,7 @@ package org_test
import (
"context"
"fmt"
"os"
"testing"
"time"
@@ -41,11 +42,12 @@ func TestMain(m *testing.M) {
}
func TestServer_GetOrganizationByID(t *testing.T) {
orgName := gofakeit.Name()
orgId, err := createOrg(orgName)
orgs, orgsName, err := createOrgs(1)
if err != nil {
assert.Fail(t, "unable to create org")
}
orgId := orgs[0].OrganizationId
orgName := orgsName[0]
tests := []struct {
name string
@@ -233,11 +235,12 @@ func TestServer_CreateOrganization(t *testing.T) {
}
func TestServer_UpdateOrganization(t *testing.T) {
orgName := gofakeit.Name()
orgId, err := createOrg(orgName)
orgs, orgsName, err := createOrgs(1)
if err != nil {
assert.Fail(t, "unable to create org")
}
orgId := orgs[0].OrganizationId
orgName := orgsName[0]
tests := []struct {
name string
@@ -291,17 +294,95 @@ func TestServer_UpdateOrganization(t *testing.T) {
}
}
func createOrg(orgName string) (string, error) {
org, err := Client.CreateOrganization(CTX,
&org.CreateOrganizationRequest{
Name: orgName,
},
)
// TODO: finish off qyery testing in ListOrganizations
func TestServer_ListOrganization(t *testing.T) {
noOfOrgs := 3
orgs, orgsName, err := createOrgs(noOfOrgs)
if err != nil {
return "", err
assert.Fail(t, "unable to create org")
}
return org.OrganizationId, nil
tests := []struct {
name string
ctx context.Context
req *org.ListOrganizationsRequest
want []*org.Organization
wantErr bool
}{
{
name: "update org with same name",
ctx: Instance.WithAuthorization(context.Background(), integration.UserTypeOrgOwner),
req: &org.ListOrganizationsRequest{},
want: []*org.Organization{
{
Id: orgs[0].OrganizationId,
Name: orgsName[0],
},
{
Id: orgs[1].OrganizationId,
Name: orgsName[1],
},
{
Id: orgs[2].OrganizationId,
Name: orgsName[2],
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
retryDuration, tick := integration.WaitForAndTickWithMaxDuration(context.Background(), 10*time.Minute)
require.EventuallyWithT(t, func(ttt *assert.CollectT) {
got, err := Client.ListOrganizations(tt.ctx, tt.req)
if tt.wantErr {
require.Error(t, err)
return
}
require.NoError(t, err)
// require.Equal(t, len(tt.want), len(got.Result))
// check details
// assert.NotZero(t, got.GetDetails().GetSequence())
// gotCD := got.GetDetails().GetChangeDate().AsTime()
// now := time.Now()
// assert.WithinRange(t, gotCD, now.Add(-time.Minute), now.Add(time.Minute))
// assert.NotEmpty(t, got.GetDetails().GetResourceOwner())
foundOrgs := 0
for _, got := range got.Result {
for _, org := range tt.want {
if org.Name == got.Name &&
org.Id == got.Id {
foundOrgs += 1
}
// require.Equal(t, org.do, got.Result[i].Name)
}
}
fmt.Printf("@@ >>>>>>>>>>>>>>>>>>>>>>>>>>>> foundOrgs = %+v\n", foundOrgs)
require.Equal(t, len(tt.want), foundOrgs)
}, retryDuration, tick, "timeout waiting for expected organizations being created")
})
}
}
func createOrgs(noOfOrgs int) ([]*org.CreateOrganizationResponse, []string, error) {
var err error
orgs := make([]*org.CreateOrganizationResponse, noOfOrgs)
orgsName := make([]string, noOfOrgs)
for i := range noOfOrgs {
orgName := gofakeit.Name()
orgsName[i] = orgName
orgs[i], err = Client.CreateOrganization(CTX,
&org.CreateOrganizationRequest{
Name: orgName,
},
)
if err != nil {
return nil, nil, err
}
}
return orgs, orgsName, nil
}
func assertCreatedAdmin(t *testing.T, expected, got *org.CreateOrganizationResponse_CreatedAdmin) {

View File

@@ -43,6 +43,21 @@ func (s *Server) GetOrganizationByID(ctx context.Context, request *v2beta_org.Ge
}, nil
}
func (s *Server) ListOrganizations(ctx context.Context, request *v2beta_org.ListOrganizationsRequest) (*v2beta_org.ListOrganizationsResponse, error) {
queries, err := listOrgRequestToModel(request)
if err != nil {
return nil, err
}
orgs, err := s.query.SearchOrgs(ctx, queries, nil)
if err != nil {
return nil, err
}
return &v2beta_org.ListOrganizationsResponse{
Result: OrgViewsToPb(orgs.Orgs),
Details: object.ToListDetails(orgs.SearchResponse),
}, nil
}
func createOrganizationRequestToCommand(request *v2beta_org.CreateOrganizationRequest) (*command.OrgSetup, error) {
admins, err := createOrganizationRequestAdminsToCommand(request.GetAdmins())
if err != nil {