Files
zitadel/internal/api/grpc/project/v2/integration_test/project_test.go
Livio Spring 32500e3b0c feat(api): move project service v2beta to GA (and deprecate v2beta) (#10844)
# Which Problems Are Solved

As part of our efforts to simplify the structure and versions of our
APIs, were moving all existing v2beta endpoints to v2 and deprecate
them. They will be removed in Zitadel V5.

# How the Problems Are Solved

- This PR moves project v2beta service and its endpoints to a
corresponding v2 version. The v2beta service and endpoints are
deprecated.
- The comments and have been improved and, where not already done, moved
from swagger annotations to proto.
- All required fields have been marked with `(google.api.field_behavior)
= REQUIRED` and validation rules have been added where missing.
- Name ID of the project always `project_id`
- `UpdateProjectRequest` has been updated to align with the creation and
retrieval of a project:
  - `project_role_check` has been renamed to `authorization_required`
  - `has_project_check` has been renamed to `project_access_required`
- `ListProjectRequest` has been changed:
- `project_grant_resource_owner_filter`,
`project_grant_resource_owner_filter` and
`project_organization_id_filter` have been removed and merged into a
single `organization_id_filter` where a `type` can optionally be
specified to select `owned`, `granted` or both project types within a
specified organization.
- `ListProjectGrantReques` has been changed:
- `project_resource_owner_filter` has been renamed to
`project_organization_id_filter`
- `grant_resource_owner_filter` has been renamed to
`granted_organization_id_filter`

# Additional Changes

Replaced deprecated `intergration.WithAuthorization` with
`integration.WithAuthorizationToken` in integration tests.

# Additional Context

- part of #10772 
- requires backport to v4.x
2025-10-28 12:28:45 +00:00

1155 lines
34 KiB
Go

//go:build integration
package project_test
import (
"context"
"testing"
"time"
"github.com/muhlemmer/gu"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/integration"
internal_permission_v2beta "github.com/zitadel/zitadel/pkg/grpc/internal_permission/v2beta"
"github.com/zitadel/zitadel/pkg/grpc/project/v2"
)
func TestServer_CreateProject(t *testing.T) {
t.Parallel()
iamOwnerCtx := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner)
orgResp := instance.CreateOrganization(iamOwnerCtx, integration.OrganizationName(), integration.Email())
alreadyExistingProjectName := integration.ProjectName()
instance.CreateProject(iamOwnerCtx, t, orgResp.GetOrganizationId(), alreadyExistingProjectName, false, false)
customID := integration.ID()
type want struct {
id func(id string)
creationDate bool
}
tests := []struct {
name string
ctx context.Context
req *project.CreateProjectRequest
want
wantErr bool
}{
{
name: "empty name",
ctx: iamOwnerCtx,
req: &project.CreateProjectRequest{
Name: "",
},
wantErr: true,
},
{
name: "empty organization",
ctx: iamOwnerCtx,
req: &project.CreateProjectRequest{
Name: integration.ProjectName(),
OrganizationId: "",
},
wantErr: true,
},
{
name: "already existing, error",
ctx: iamOwnerCtx,
req: &project.CreateProjectRequest{
Name: alreadyExistingProjectName,
OrganizationId: orgResp.GetOrganizationId(),
},
wantErr: true,
},
{
name: "empty, ok",
ctx: iamOwnerCtx,
req: &project.CreateProjectRequest{
Name: integration.ProjectName(),
OrganizationId: orgResp.GetOrganizationId(),
},
want: want{
id: func(id string) { assert.NotEmpty(t, id) },
creationDate: true,
},
},
{
name: "with custom id, ok",
ctx: iamOwnerCtx,
req: &project.CreateProjectRequest{
Name: integration.ProjectName(),
OrganizationId: orgResp.GetOrganizationId(),
ProjectId: gu.Ptr(customID),
},
want: want{
id: func(id string) { assert.Equal(t, customID, id) },
creationDate: true,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
creationDate := time.Now().UTC()
got, err := instance.Client.ProjectV2.CreateProject(tt.ctx, tt.req)
changeDate := time.Now().UTC()
if tt.wantErr {
assert.Error(t, err)
return
}
assert.NoError(t, err)
assertCreateProjectResponse(t, creationDate, changeDate, tt.want.creationDate, tt.want.id, got)
})
}
}
func TestServer_CreateProject_Permission(t *testing.T) {
t.Parallel()
iamOwnerCtx := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner)
orgResp := instance.CreateOrganization(iamOwnerCtx, integration.OrganizationName(), integration.Email())
type want struct {
id bool
creationDate bool
}
tests := []struct {
name string
ctx context.Context
req *project.CreateProjectRequest
want
wantErr bool
}{
{
name: "unauthenticated",
ctx: CTX,
req: &project.CreateProjectRequest{
Name: integration.ProjectName(),
OrganizationId: orgResp.GetOrganizationId(),
},
wantErr: true,
},
{
name: "missing permission",
ctx: instance.WithAuthorizationToken(CTX, integration.UserTypeNoPermission),
req: &project.CreateProjectRequest{
Name: integration.ProjectName(),
OrganizationId: orgResp.GetOrganizationId(),
},
wantErr: true,
},
{
name: "missing permission, other organization",
ctx: instance.WithAuthorizationToken(CTX, integration.UserTypeOrgOwner),
req: &project.CreateProjectRequest{
Name: integration.ProjectName(),
OrganizationId: orgResp.GetOrganizationId(),
},
wantErr: true,
},
{
name: "with ORG_PROJECT_CREATOR permission, same organization, ok",
ctx: integration.WithAuthorizationToken(CTX, getOrgProjectCreatorToken(t, iamOwnerCtx, orgResp.GetOrganizationId(), orgResp.GetOrganizationId())),
req: &project.CreateProjectRequest{
Name: integration.ProjectName(),
OrganizationId: orgResp.GetOrganizationId(),
},
want: want{
id: true,
creationDate: true,
},
},
{
name: "with ORG_PROJECT_CREATOR permission, other organization, ok",
ctx: integration.WithAuthorizationToken(CTX, getOrgProjectCreatorToken(t, iamOwnerCtx, orgResp.GetOrganizationId(), instance.DefaultOrg.GetId())),
req: &project.CreateProjectRequest{
Name: integration.ProjectName(),
OrganizationId: instance.DefaultOrg.GetId(),
},
want: want{
id: true,
creationDate: true,
},
},
{
name: "organization owner, ok",
ctx: instance.WithAuthorizationToken(CTX, integration.UserTypeOrgOwner),
req: &project.CreateProjectRequest{
Name: integration.ProjectName(),
OrganizationId: instance.DefaultOrg.GetId(),
},
want: want{
id: true,
creationDate: true,
},
},
{
name: "instance owner, ok",
ctx: iamOwnerCtx,
req: &project.CreateProjectRequest{
Name: integration.ProjectName(),
OrganizationId: orgResp.GetOrganizationId(),
},
want: want{
id: true,
creationDate: true,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
creationDate := time.Now().UTC()
got, err := instance.Client.ProjectV2.CreateProject(tt.ctx, tt.req)
changeDate := time.Now().UTC()
if tt.wantErr {
assert.Error(t, err)
return
}
assert.NoError(t, err)
id := func(id string) {
if tt.want.id {
assert.NotEmpty(t, id)
} else {
assert.Empty(t, id)
}
}
assertCreateProjectResponse(t, creationDate, changeDate, tt.want.creationDate, id, got)
})
}
}
func getOrgProjectCreatorToken(t *testing.T, ctx context.Context, orgId1, orgId2 string) string {
// create a machine user in Org 1
userResp := instance.CreateUserTypeMachine(ctx, orgId1)
// assign ORG_PROJECT_CREATOR role in Org 2
_, err := instance.Client.InternalPermissionv2Beta.CreateAdministrator(ctx, &internal_permission_v2beta.CreateAdministratorRequest{
Resource: &internal_permission_v2beta.ResourceType{
Resource: &internal_permission_v2beta.ResourceType_OrganizationId{OrganizationId: orgId2},
},
UserId: userResp.GetId(),
Roles: []string{domain.RoleOrgProjectCreator},
})
require.NoError(t, err)
return instance.CreatePersonalAccessToken(ctx, userResp.GetId()).Token
}
func assertCreateProjectResponse(t *testing.T, creationDate, changeDate time.Time, expectedCreationDate bool, assertID func(string), actualResp *project.CreateProjectResponse) {
if expectedCreationDate {
if !changeDate.IsZero() {
assert.WithinRange(t, actualResp.GetCreationDate().AsTime(), creationDate, changeDate)
} else {
assert.WithinRange(t, actualResp.GetCreationDate().AsTime(), creationDate, time.Now().UTC())
}
} else {
assert.Nil(t, actualResp.CreationDate)
}
assertID(actualResp.ProjectId)
}
func TestServer_UpdateProject(t *testing.T) {
t.Parallel()
iamOwnerCtx := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner)
orgResp := instance.CreateOrganization(iamOwnerCtx, integration.OrganizationName(), integration.Email())
type args struct {
ctx context.Context
req *project.UpdateProjectRequest
}
type want struct {
change bool
changeDate bool
}
tests := []struct {
name string
prepare func(request *project.UpdateProjectRequest)
args args
want want
wantErr bool
}{
{
name: "not existing",
prepare: func(request *project.UpdateProjectRequest) {
request.ProjectId = "notexisting"
},
args: args{
ctx: iamOwnerCtx,
req: &project.UpdateProjectRequest{
Name: gu.Ptr(integration.ProjectName()),
},
},
wantErr: true,
},
{
name: "no change, ok",
prepare: func(request *project.UpdateProjectRequest) {
name := integration.ProjectName()
projectID := instance.CreateProject(iamOwnerCtx, t, orgResp.GetOrganizationId(), name, false, false).GetId()
request.ProjectId = projectID
request.Name = gu.Ptr(name)
},
args: args{
ctx: iamOwnerCtx,
req: &project.UpdateProjectRequest{},
},
want: want{
change: false,
changeDate: true,
},
},
{
name: "change name, ok",
prepare: func(request *project.UpdateProjectRequest) {
projectID := instance.CreateProject(iamOwnerCtx, t, orgResp.GetOrganizationId(), integration.ProjectName(), false, false).GetId()
request.ProjectId = projectID
},
args: args{
ctx: iamOwnerCtx,
req: &project.UpdateProjectRequest{
Name: gu.Ptr(integration.ProjectName()),
},
},
want: want{
change: true,
changeDate: true,
},
},
{
name: "change full, ok",
prepare: func(request *project.UpdateProjectRequest) {
projectID := instance.CreateProject(iamOwnerCtx, t, orgResp.GetOrganizationId(), integration.ProjectName(), false, false).GetId()
request.ProjectId = projectID
},
args: args{
ctx: iamOwnerCtx,
req: &project.UpdateProjectRequest{
Name: gu.Ptr(integration.ProjectName()),
ProjectRoleAssertion: gu.Ptr(true),
AuthorizationRequired: gu.Ptr(true),
ProjectAccessRequired: gu.Ptr(true),
PrivateLabelingSetting: gu.Ptr(project.PrivateLabelingSetting_PRIVATE_LABELING_SETTING_ALLOW_LOGIN_USER_RESOURCE_OWNER_POLICY),
},
},
want: want{
change: true,
changeDate: true,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
creationDate := time.Now().UTC()
tt.prepare(tt.args.req)
got, err := instance.Client.ProjectV2.UpdateProject(tt.args.ctx, tt.args.req)
if tt.wantErr {
assert.Error(t, err)
return
}
changeDate := time.Time{}
if tt.want.change {
changeDate = time.Now().UTC()
}
assert.NoError(t, err)
assertUpdateProjectResponse(t, creationDate, changeDate, tt.want.changeDate, got)
})
}
}
func TestServer_UpdateProject_Permission(t *testing.T) {
t.Parallel()
iamOwnerCtx := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner)
orgResp := instance.CreateOrganization(iamOwnerCtx, integration.OrganizationName(), integration.Email())
userResp := instance.CreateMachineUser(iamOwnerCtx)
patResp := instance.CreatePersonalAccessToken(iamOwnerCtx, userResp.GetUserId())
projectID := instance.CreateProject(iamOwnerCtx, t, orgResp.GetOrganizationId(), integration.ProjectName(), false, false).GetId()
instance.CreateProjectMembership(t, iamOwnerCtx, projectID, userResp.GetUserId())
projectOwnerCtx := integration.WithAuthorizationToken(CTX, patResp.Token)
type args struct {
ctx context.Context
req *project.UpdateProjectRequest
}
type want struct {
change bool
changeDate bool
}
tests := []struct {
name string
prepare func(request *project.UpdateProjectRequest)
args args
want want
wantErr bool
}{
{
name: "unauthenticated",
prepare: func(request *project.UpdateProjectRequest) {
projectResp := instance.CreateProject(iamOwnerCtx, t, orgResp.GetOrganizationId(), integration.ProjectName(), false, false)
request.ProjectId = projectResp.GetId()
},
args: args{
ctx: CTX,
req: &project.UpdateProjectRequest{
Name: gu.Ptr(integration.ProjectName()),
},
},
wantErr: true,
},
{
name: "missing permission",
prepare: func(request *project.UpdateProjectRequest) {
projectResp := instance.CreateProject(iamOwnerCtx, t, orgResp.GetOrganizationId(), integration.ProjectName(), false, false)
request.ProjectId = projectResp.GetId()
},
args: args{
ctx: instance.WithAuthorizationToken(CTX, integration.UserTypeNoPermission),
req: &project.UpdateProjectRequest{
Name: gu.Ptr(integration.ProjectName()),
},
},
wantErr: true,
},
{
name: "project owner, no permission",
prepare: func(request *project.UpdateProjectRequest) {
projectID := instance.CreateProject(iamOwnerCtx, t, orgResp.GetOrganizationId(), integration.ProjectName(), false, false).GetId()
request.ProjectId = projectID
},
args: args{
ctx: projectOwnerCtx,
req: &project.UpdateProjectRequest{
Name: gu.Ptr(integration.ProjectName()),
},
},
wantErr: true,
},
{
name: " roject owner, ok",
prepare: func(request *project.UpdateProjectRequest) {
request.ProjectId = projectID
},
args: args{
ctx: projectOwnerCtx,
req: &project.UpdateProjectRequest{
Name: gu.Ptr(integration.ProjectName()),
},
},
want: want{
change: true,
changeDate: true,
},
},
{
name: "missing permission, other organization",
prepare: func(request *project.UpdateProjectRequest) {
projectResp := instance.CreateProject(iamOwnerCtx, t, orgResp.GetOrganizationId(), integration.ProjectName(), false, false)
request.ProjectId = projectResp.GetId()
},
args: args{
ctx: instance.WithAuthorizationToken(CTX, integration.UserTypeOrgOwner),
req: &project.UpdateProjectRequest{
Name: gu.Ptr(integration.ProjectName()),
},
},
wantErr: true,
},
{
name: "organization owner, ok",
prepare: func(request *project.UpdateProjectRequest) {
projectID := instance.CreateProject(iamOwnerCtx, t, instance.DefaultOrg.GetId(), integration.ProjectName(), false, false).GetId()
request.ProjectId = projectID
},
args: args{
ctx: instance.WithAuthorizationToken(CTX, integration.UserTypeOrgOwner),
req: &project.UpdateProjectRequest{
Name: gu.Ptr(integration.ProjectName()),
},
},
want: want{
change: true,
changeDate: true,
},
},
{
name: "instance owner, ok",
prepare: func(request *project.UpdateProjectRequest) {
projectID := instance.CreateProject(iamOwnerCtx, t, instance.DefaultOrg.GetId(), integration.ProjectName(), false, false).GetId()
request.ProjectId = projectID
},
args: args{
ctx: iamOwnerCtx,
req: &project.UpdateProjectRequest{
Name: gu.Ptr(integration.ProjectName()),
},
},
want: want{
change: true,
changeDate: true,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
creationDate := time.Now().UTC()
tt.prepare(tt.args.req)
got, err := instance.Client.ProjectV2.UpdateProject(tt.args.ctx, tt.args.req)
if tt.wantErr {
assert.Error(t, err)
return
}
changeDate := time.Time{}
if tt.want.change {
changeDate = time.Now().UTC()
}
assert.NoError(t, err)
assertUpdateProjectResponse(t, creationDate, changeDate, tt.want.changeDate, got)
})
}
}
func assertUpdateProjectResponse(t *testing.T, creationDate, changeDate time.Time, expectedChangeDate bool, actualResp *project.UpdateProjectResponse) {
if expectedChangeDate {
if !changeDate.IsZero() {
assert.WithinRange(t, actualResp.GetChangeDate().AsTime(), creationDate, changeDate)
} else {
assert.WithinRange(t, actualResp.GetChangeDate().AsTime(), creationDate, time.Now().UTC())
}
} else {
assert.Nil(t, actualResp.ChangeDate)
}
}
func TestServer_DeleteProject(t *testing.T) {
t.Parallel()
iamOwnerCtx := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner)
orgResp := instance.CreateOrganization(iamOwnerCtx, integration.OrganizationName(), integration.Email())
tests := []struct {
name string
ctx context.Context
prepare func(request *project.DeleteProjectRequest) (time.Time, time.Time)
req *project.DeleteProjectRequest
wantDeletionDate bool
wantErr bool
}{
{
name: "empty id",
ctx: iamOwnerCtx,
req: &project.DeleteProjectRequest{
ProjectId: "",
},
wantErr: true,
},
{
name: "delete, not existing",
ctx: iamOwnerCtx,
req: &project.DeleteProjectRequest{
ProjectId: "notexisting",
},
wantDeletionDate: false,
},
{
name: "delete",
ctx: iamOwnerCtx,
prepare: func(request *project.DeleteProjectRequest) (time.Time, time.Time) {
creationDate := time.Now().UTC()
projectID := instance.CreateProject(iamOwnerCtx, t, orgResp.GetOrganizationId(), integration.ProjectName(), false, false).GetId()
request.ProjectId = projectID
return creationDate, time.Time{}
},
req: &project.DeleteProjectRequest{},
wantDeletionDate: true,
},
{
name: "delete, already removed",
ctx: iamOwnerCtx,
prepare: func(request *project.DeleteProjectRequest) (time.Time, time.Time) {
creationDate := time.Now().UTC()
projectID := instance.CreateProject(iamOwnerCtx, t, orgResp.GetOrganizationId(), integration.ProjectName(), false, false).GetId()
request.ProjectId = projectID
instance.DeleteProject(iamOwnerCtx, t, projectID)
return creationDate, time.Now().UTC()
},
req: &project.DeleteProjectRequest{},
wantDeletionDate: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
var creationDate, deletionDate time.Time
if tt.prepare != nil {
creationDate, deletionDate = tt.prepare(tt.req)
}
got, err := instance.Client.ProjectV2.DeleteProject(tt.ctx, tt.req)
if tt.wantErr {
assert.Error(t, err)
return
}
assert.NoError(t, err)
assertDeleteProjectResponse(t, creationDate, deletionDate, tt.wantDeletionDate, got)
})
}
}
func TestServer_DeleteProject_Permission(t *testing.T) {
t.Parallel()
iamOwnerCtx := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner)
orgResp := instance.CreateOrganization(iamOwnerCtx, integration.OrganizationName(), integration.Email())
userResp := instance.CreateMachineUser(iamOwnerCtx)
patResp := instance.CreatePersonalAccessToken(iamOwnerCtx, userResp.GetUserId())
projectID := instance.CreateProject(iamOwnerCtx, t, orgResp.GetOrganizationId(), integration.ProjectName(), false, false).GetId()
instance.CreateProjectMembership(t, iamOwnerCtx, projectID, userResp.GetUserId())
projectOwnerCtx := integration.WithAuthorizationToken(CTX, patResp.Token)
tests := []struct {
name string
ctx context.Context
prepare func(request *project.DeleteProjectRequest) (time.Time, time.Time)
req *project.DeleteProjectRequest
wantDeletionDate bool
wantErr bool
}{
{
name: "unauthenticated",
ctx: CTX,
prepare: func(request *project.DeleteProjectRequest) (time.Time, time.Time) {
creationDate := time.Now().UTC()
projectID := instance.CreateProject(iamOwnerCtx, t, orgResp.GetOrganizationId(), integration.ProjectName(), false, false).GetId()
request.ProjectId = projectID
return creationDate, time.Time{}
},
req: &project.DeleteProjectRequest{},
wantErr: true,
},
{
name: "missing permission",
ctx: instance.WithAuthorizationToken(CTX, integration.UserTypeNoPermission),
prepare: func(request *project.DeleteProjectRequest) (time.Time, time.Time) {
creationDate := time.Now().UTC()
projectID := instance.CreateProject(iamOwnerCtx, t, orgResp.GetOrganizationId(), integration.ProjectName(), false, false).GetId()
request.ProjectId = projectID
return creationDate, time.Time{}
},
req: &project.DeleteProjectRequest{},
wantErr: true,
},
{
name: "project owner, no permission",
ctx: projectOwnerCtx,
prepare: func(request *project.DeleteProjectRequest) (time.Time, time.Time) {
creationDate := time.Now().UTC()
projectID := instance.CreateProject(iamOwnerCtx, t, orgResp.GetOrganizationId(), integration.ProjectName(), false, false).GetId()
request.ProjectId = projectID
return creationDate, time.Time{}
},
req: &project.DeleteProjectRequest{},
wantErr: true,
},
{
name: "project owner, ok",
ctx: projectOwnerCtx,
prepare: func(request *project.DeleteProjectRequest) (time.Time, time.Time) {
creationDate := time.Now().UTC()
request.ProjectId = projectID
return creationDate, time.Time{}
},
req: &project.DeleteProjectRequest{},
wantDeletionDate: true,
},
{
name: "organization owner, other org",
ctx: instance.WithAuthorizationToken(CTX, integration.UserTypeOrgOwner),
prepare: func(request *project.DeleteProjectRequest) (time.Time, time.Time) {
creationDate := time.Now().UTC()
projectID := instance.CreateProject(iamOwnerCtx, t, orgResp.GetOrganizationId(), integration.ProjectName(), false, false).GetId()
request.ProjectId = projectID
return creationDate, time.Time{}
},
req: &project.DeleteProjectRequest{},
wantErr: true,
},
{
name: "organization owner",
ctx: instance.WithAuthorizationToken(CTX, integration.UserTypeOrgOwner),
prepare: func(request *project.DeleteProjectRequest) (time.Time, time.Time) {
creationDate := time.Now().UTC()
projectID := instance.CreateProject(iamOwnerCtx, t, instance.DefaultOrg.GetId(), integration.ProjectName(), false, false).GetId()
request.ProjectId = projectID
return creationDate, time.Time{}
},
req: &project.DeleteProjectRequest{},
wantDeletionDate: true,
},
{
name: "instance owner",
ctx: iamOwnerCtx,
prepare: func(request *project.DeleteProjectRequest) (time.Time, time.Time) {
creationDate := time.Now().UTC()
projectID := instance.CreateProject(iamOwnerCtx, t, instance.DefaultOrg.GetId(), integration.ProjectName(), false, false).GetId()
request.ProjectId = projectID
return creationDate, time.Time{}
},
req: &project.DeleteProjectRequest{},
wantDeletionDate: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
var creationDate, deletionDate time.Time
if tt.prepare != nil {
creationDate, deletionDate = tt.prepare(tt.req)
}
got, err := instance.Client.ProjectV2.DeleteProject(tt.ctx, tt.req)
if tt.wantErr {
assert.Error(t, err)
return
}
assert.NoError(t, err)
assertDeleteProjectResponse(t, creationDate, deletionDate, tt.wantDeletionDate, got)
})
}
}
func assertDeleteProjectResponse(t *testing.T, creationDate, deletionDate time.Time, expectedDeletionDate bool, actualResp *project.DeleteProjectResponse) {
if expectedDeletionDate {
if !deletionDate.IsZero() {
assert.WithinRange(t, actualResp.GetDeletionDate().AsTime(), creationDate, deletionDate)
} else {
assert.WithinRange(t, actualResp.GetDeletionDate().AsTime(), creationDate, time.Now().UTC())
}
} else {
assert.Nil(t, actualResp.DeletionDate)
}
}
func TestServer_DeactivateProject(t *testing.T) {
t.Parallel()
iamOwnerCtx := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner)
orgResp := instance.CreateOrganization(iamOwnerCtx, integration.OrganizationName(), integration.Email())
type args struct {
ctx context.Context
req *project.DeactivateProjectRequest
}
type want struct {
change bool
changeDate bool
}
tests := []struct {
name string
prepare func(request *project.DeactivateProjectRequest)
args args
want want
wantErr bool
}{
{
name: "not existing",
prepare: func(request *project.DeactivateProjectRequest) {
request.ProjectId = "notexisting"
},
args: args{
ctx: iamOwnerCtx,
req: &project.DeactivateProjectRequest{},
},
wantErr: true,
},
{
name: "no change, ok",
prepare: func(request *project.DeactivateProjectRequest) {
projectID := instance.CreateProject(iamOwnerCtx, t, orgResp.GetOrganizationId(), integration.ProjectName(), false, false).GetId()
request.ProjectId = projectID
instance.DeactivateProject(iamOwnerCtx, t, projectID)
},
args: args{
ctx: iamOwnerCtx,
req: &project.DeactivateProjectRequest{},
},
wantErr: true,
},
{
name: "change, ok",
prepare: func(request *project.DeactivateProjectRequest) {
projectID := instance.CreateProject(iamOwnerCtx, t, orgResp.GetOrganizationId(), integration.ProjectName(), false, false).GetId()
request.ProjectId = projectID
},
args: args{
ctx: iamOwnerCtx,
req: &project.DeactivateProjectRequest{},
},
want: want{
change: true,
changeDate: true,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
creationDate := time.Now().UTC()
tt.prepare(tt.args.req)
got, err := instance.Client.ProjectV2.DeactivateProject(tt.args.ctx, tt.args.req)
if tt.wantErr {
assert.Error(t, err)
return
}
changeDate := time.Time{}
if tt.want.change {
changeDate = time.Now().UTC()
}
assert.NoError(t, err)
assertDeactivateProjectResponse(t, creationDate, changeDate, tt.want.changeDate, got)
})
}
}
func TestServer_DeactivateProject_Permission(t *testing.T) {
t.Parallel()
iamOwnerCtx := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner)
orgResp := instance.CreateOrganization(iamOwnerCtx, integration.OrganizationName(), integration.Email())
type args struct {
ctx context.Context
req *project.DeactivateProjectRequest
}
type want struct {
change bool
changeDate bool
}
tests := []struct {
name string
prepare func(request *project.DeactivateProjectRequest)
args args
want want
wantErr bool
}{
{
name: "unauthenticated",
prepare: func(request *project.DeactivateProjectRequest) {
projectResp := instance.CreateProject(iamOwnerCtx, t, orgResp.GetOrganizationId(), integration.ProjectName(), false, false)
request.ProjectId = projectResp.GetId()
},
args: args{
ctx: CTX,
req: &project.DeactivateProjectRequest{},
},
wantErr: true,
},
{
name: "missing permission",
prepare: func(request *project.DeactivateProjectRequest) {
projectResp := instance.CreateProject(iamOwnerCtx, t, orgResp.GetOrganizationId(), integration.ProjectName(), false, false)
request.ProjectId = projectResp.GetId()
},
args: args{
ctx: instance.WithAuthorizationToken(CTX, integration.UserTypeNoPermission),
req: &project.DeactivateProjectRequest{},
},
wantErr: true,
},
{
name: "organization owner, other org",
prepare: func(request *project.DeactivateProjectRequest) {
projectResp := instance.CreateProject(iamOwnerCtx, t, orgResp.GetOrganizationId(), integration.ProjectName(), false, false)
request.ProjectId = projectResp.GetId()
},
args: args{
ctx: instance.WithAuthorizationToken(CTX, integration.UserTypeOrgOwner),
req: &project.DeactivateProjectRequest{},
},
wantErr: true,
},
{
name: "organization owner",
prepare: func(request *project.DeactivateProjectRequest) {
projectResp := instance.CreateProject(iamOwnerCtx, t, instance.DefaultOrg.GetId(), integration.ProjectName(), false, false)
request.ProjectId = projectResp.GetId()
},
args: args{
ctx: instance.WithAuthorizationToken(CTX, integration.UserTypeOrgOwner),
req: &project.DeactivateProjectRequest{},
},
want: want{
change: true,
changeDate: true,
},
},
{
name: "instance owner",
prepare: func(request *project.DeactivateProjectRequest) {
projectResp := instance.CreateProject(iamOwnerCtx, t, orgResp.GetOrganizationId(), integration.ProjectName(), false, false)
request.ProjectId = projectResp.GetId()
},
args: args{
ctx: iamOwnerCtx,
req: &project.DeactivateProjectRequest{},
},
want: want{
change: true,
changeDate: true,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
creationDate := time.Now().UTC()
tt.prepare(tt.args.req)
got, err := instance.Client.ProjectV2.DeactivateProject(tt.args.ctx, tt.args.req)
if tt.wantErr {
assert.Error(t, err)
return
}
changeDate := time.Time{}
if tt.want.change {
changeDate = time.Now().UTC()
}
assert.NoError(t, err)
assertDeactivateProjectResponse(t, creationDate, changeDate, tt.want.changeDate, got)
})
}
}
func assertDeactivateProjectResponse(t *testing.T, creationDate, changeDate time.Time, expectedChangeDate bool, actualResp *project.DeactivateProjectResponse) {
if expectedChangeDate {
if !changeDate.IsZero() {
assert.WithinRange(t, actualResp.GetChangeDate().AsTime(), creationDate, changeDate)
} else {
assert.WithinRange(t, actualResp.GetChangeDate().AsTime(), creationDate, time.Now().UTC())
}
} else {
assert.Nil(t, actualResp.ChangeDate)
}
}
func TestServer_ActivateProject(t *testing.T) {
t.Parallel()
iamOwnerCtx := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner)
orgResp := instance.CreateOrganization(iamOwnerCtx, integration.OrganizationName(), integration.Email())
type args struct {
ctx context.Context
req *project.ActivateProjectRequest
}
type want struct {
change bool
changeDate bool
}
tests := []struct {
name string
prepare func(request *project.ActivateProjectRequest)
args args
want want
wantErr bool
}{
{
name: "missing permission",
prepare: func(request *project.ActivateProjectRequest) {
projectResp := instance.CreateProject(iamOwnerCtx, t, orgResp.GetOrganizationId(), integration.ProjectName(), false, false)
request.ProjectId = projectResp.GetId()
},
args: args{
ctx: instance.WithAuthorizationToken(CTX, integration.UserTypeNoPermission),
req: &project.ActivateProjectRequest{},
},
wantErr: true,
},
{
name: "not existing",
prepare: func(request *project.ActivateProjectRequest) {
request.ProjectId = "notexisting"
return
},
args: args{
ctx: iamOwnerCtx,
req: &project.ActivateProjectRequest{},
},
wantErr: true,
},
{
name: "no change, ok",
prepare: func(request *project.ActivateProjectRequest) {
projectID := instance.CreateProject(iamOwnerCtx, t, orgResp.GetOrganizationId(), integration.ProjectName(), false, false).GetId()
request.ProjectId = projectID
},
args: args{
ctx: iamOwnerCtx,
req: &project.ActivateProjectRequest{},
},
wantErr: true,
},
{
name: "change, ok",
prepare: func(request *project.ActivateProjectRequest) {
projectID := instance.CreateProject(iamOwnerCtx, t, orgResp.GetOrganizationId(), integration.ProjectName(), false, false).GetId()
request.ProjectId = projectID
instance.DeactivateProject(iamOwnerCtx, t, projectID)
},
args: args{
ctx: iamOwnerCtx,
req: &project.ActivateProjectRequest{},
},
want: want{
change: true,
changeDate: true,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
creationDate := time.Now().UTC()
tt.prepare(tt.args.req)
got, err := instance.Client.ProjectV2.ActivateProject(tt.args.ctx, tt.args.req)
if tt.wantErr {
assert.Error(t, err)
return
}
changeDate := time.Time{}
if tt.want.change {
changeDate = time.Now().UTC()
}
assert.NoError(t, err)
assertActivateProjectResponse(t, creationDate, changeDate, tt.want.changeDate, got)
})
}
}
func TestServer_ActivateProject_Permission(t *testing.T) {
t.Parallel()
iamOwnerCtx := instance.WithAuthorizationToken(CTX, integration.UserTypeIAMOwner)
orgResp := instance.CreateOrganization(iamOwnerCtx, integration.OrganizationName(), integration.Email())
type args struct {
ctx context.Context
req *project.ActivateProjectRequest
}
type want struct {
change bool
changeDate bool
}
tests := []struct {
name string
prepare func(request *project.ActivateProjectRequest)
args args
want want
wantErr bool
}{
{
name: "unauthenticated",
prepare: func(request *project.ActivateProjectRequest) {
projectResp := instance.CreateProject(iamOwnerCtx, t, orgResp.GetOrganizationId(), integration.ProjectName(), false, false)
request.ProjectId = projectResp.GetId()
instance.DeactivateProject(iamOwnerCtx, t, projectResp.GetId())
},
args: args{
ctx: CTX,
req: &project.ActivateProjectRequest{},
},
wantErr: true,
},
{
name: "missing permission",
prepare: func(request *project.ActivateProjectRequest) {
projectResp := instance.CreateProject(iamOwnerCtx, t, orgResp.GetOrganizationId(), integration.ProjectName(), false, false)
request.ProjectId = projectResp.GetId()
instance.DeactivateProject(iamOwnerCtx, t, projectResp.GetId())
},
args: args{
ctx: instance.WithAuthorizationToken(CTX, integration.UserTypeNoPermission),
req: &project.ActivateProjectRequest{},
},
wantErr: true,
},
{
name: "organization owner, other org",
prepare: func(request *project.ActivateProjectRequest) {
projectResp := instance.CreateProject(iamOwnerCtx, t, orgResp.GetOrganizationId(), integration.ProjectName(), false, false)
request.ProjectId = projectResp.GetId()
instance.DeactivateProject(iamOwnerCtx, t, projectResp.GetId())
},
args: args{
ctx: instance.WithAuthorizationToken(CTX, integration.UserTypeOrgOwner),
req: &project.ActivateProjectRequest{},
},
wantErr: true,
},
{
name: "organization owner",
prepare: func(request *project.ActivateProjectRequest) {
projectResp := instance.CreateProject(iamOwnerCtx, t, instance.DefaultOrg.GetId(), integration.ProjectName(), false, false)
request.ProjectId = projectResp.GetId()
instance.DeactivateProject(iamOwnerCtx, t, projectResp.GetId())
},
args: args{
ctx: instance.WithAuthorizationToken(CTX, integration.UserTypeOrgOwner),
req: &project.ActivateProjectRequest{},
},
want: want{
change: true,
changeDate: true,
},
},
{
name: "instance owner",
prepare: func(request *project.ActivateProjectRequest) {
projectResp := instance.CreateProject(iamOwnerCtx, t, orgResp.GetOrganizationId(), integration.ProjectName(), false, false)
request.ProjectId = projectResp.GetId()
instance.DeactivateProject(iamOwnerCtx, t, projectResp.GetId())
},
args: args{
ctx: iamOwnerCtx,
req: &project.ActivateProjectRequest{},
},
want: want{
change: true,
changeDate: true,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
creationDate := time.Now().UTC()
tt.prepare(tt.args.req)
got, err := instance.Client.ProjectV2.ActivateProject(tt.args.ctx, tt.args.req)
if tt.wantErr {
assert.Error(t, err)
return
}
changeDate := time.Time{}
if tt.want.change {
changeDate = time.Now().UTC()
}
assert.NoError(t, err)
assertActivateProjectResponse(t, creationDate, changeDate, tt.want.changeDate, got)
})
}
}
func assertActivateProjectResponse(t *testing.T, creationDate, changeDate time.Time, expectedChangeDate bool, actualResp *project.ActivateProjectResponse) {
if expectedChangeDate {
if !changeDate.IsZero() {
assert.WithinRange(t, actualResp.GetChangeDate().AsTime(), creationDate, changeDate)
} else {
assert.WithinRange(t, actualResp.GetChangeDate().AsTime(), creationDate, time.Now().UTC())
}
} else {
assert.Nil(t, actualResp.ChangeDate)
}
}