Files
zitadel/internal/command/project_application_secret_test.go

207 lines
4.9 KiB
Go
Raw Normal View History

feat(api): move application service v2beta to GA (and deprecate v2beta) (#10846) # 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 app v2beta service and its endpoints to a corresponding to application 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 application always `application_id`, previously was also `id` and `app_id`. - Get rid of all `app` abbreviations and name it `application` including the service name, `AppState` -> `ApplicationState` and `AppSorting` -> `ApplicationSorting` - Updated `CreateApplicationRequest`: - renamed `creation_request_type` to `application_type` and all its options to `XY_configuration` instead of `XY_request` - `RegenerateClientSecret` - renamed method to `GenerateClientSecret` - removed `app_type` from request - `ListApplicationRequest`: - removed required `project_id` and provided it as a filter - Type `ApplicationNameQuery` has been renamed to `ApplicationNameFilter` as its usage in the request - Renamed all fields and types from `config` to `configuration` - Updated `DeleteApplicationKeyRequest` - removed `organization_id` - Updated `GetApplicationKeyRequest`: - removed `project_id`, `application_id` and `organization_id`` - Updated `ListApplicationKeysRequest`: - removed oneOf `resource_id` and moved the options into filters - Name ID of the application key always `key_id`. - removed unnecessary package prefixed (`zitadel.application.v2`) - formatted using `buf` # Additional Changes None # Additional Context - part of https://github.com/zitadel/zitadel/issues/10772 - requires backport to v4.x (cherry picked from commit 0281670030b3491929d2eb4a24f4a616273d8fb2)
2025-10-17 10:12:20 +02:00
package command
import (
"context"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/repository/project"
"github.com/zitadel/zitadel/internal/zerrors"
)
func TestCommandSide_ChangeApplicationSecret(t *testing.T) {
t.Parallel()
type fields struct {
eventstore func(*testing.T) *eventstore.Eventstore
}
type args struct {
ctx context.Context
appID string
projectID string
resourceOwner string
}
type res struct {
wantSecret string
wantChangeDate time.Time
err error
}
tests := []struct {
name string
fields fields
args args
res res
}{
{
name: "no projectid, invalid argument error",
fields: fields{
eventstore: expectEventstore(),
},
args: args{
ctx: context.Background(),
appID: "app1",
resourceOwner: "org1",
},
res: res{
err: zerrors.ThrowInvalidArgument(nil, "COMMAND-KJ29c", "Errors.IDMissing"),
},
},
{
name: "no appid, invalid argument error",
fields: fields{
eventstore: expectEventstore(),
},
args: args{
ctx: context.Background(),
projectID: "project1",
appID: "",
resourceOwner: "org1",
},
res: res{
err: zerrors.ThrowInvalidArgumentf(nil, "COMMAND-KJ29c", "Errors.IDMissing"),
},
},
{
name: "app not existing, not found error",
fields: fields{
eventstore: expectEventstore(
expectFilter(),
),
},
args: args{
ctx: context.Background(),
projectID: "project1",
appID: "app1",
resourceOwner: "org1",
},
res: res{
err: zerrors.ThrowNotFound(nil, "COMMAND-Kd92s", "Errors.Project.App.NotExisting"),
},
},
{
name: "change secret (OIDC), ok",
fields: fields{
eventstore: expectEventstore(
expectFilter(
eventFromEventPusher(
project.NewApplicationAddedEvent(context.Background(),
&project.NewAggregate("project1", "org1").Aggregate,
"app1",
"app",
),
),
eventFromEventPusher(
project.NewOIDCConfigAddedEvent(context.Background(),
&project.NewAggregate("project1", "org1").Aggregate,
domain.OIDCVersionV1,
"app1",
"client1@project",
"secret",
[]string{"https://test.ch"},
[]domain.OIDCResponseType{domain.OIDCResponseTypeCode},
[]domain.OIDCGrantType{domain.OIDCGrantTypeAuthorizationCode},
domain.OIDCApplicationTypeWeb,
domain.OIDCAuthMethodTypePost,
[]string{"https://test.ch/logout"},
true,
domain.OIDCTokenTypeBearer,
true,
true,
true,
time.Second*1,
[]string{"https://sub.test.ch"},
false,
"",
domain.LoginVersionUnspecified,
"",
),
),
),
expectPush(
project.NewOIDCConfigSecretChangedEvent(context.Background(),
&project.NewAggregate("project1", "org1").Aggregate,
"app1",
"secret",
),
),
),
},
args: args{
ctx: context.Background(),
projectID: "project1",
appID: "app1",
resourceOwner: "org1",
},
res: res{
wantSecret: "secret",
},
},
{
name: "change secret (API), ok",
fields: fields{
eventstore: expectEventstore(
expectFilter(
eventFromEventPusher(
project.NewApplicationAddedEvent(context.Background(),
&project.NewAggregate("project1", "org1").Aggregate,
"app1",
"app",
),
),
eventFromEventPusher(
project.NewAPIConfigAddedEvent(context.Background(),
&project.NewAggregate("project1", "org1").Aggregate,
"app1",
"client1@project",
"secret",
domain.APIAuthMethodTypeBasic,
),
),
),
expectPush(
project.NewAPIConfigSecretChangedEvent(context.Background(),
&project.NewAggregate("project1", "org1").Aggregate,
"app1",
"secret",
),
),
),
},
args: args{
ctx: context.Background(),
projectID: "project1",
appID: "app1",
resourceOwner: "org1",
},
res: res{
wantSecret: "secret",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
r := &Commands{
eventstore: tt.fields.eventstore(t),
newHashedSecret: mockHashedSecret("secret"),
defaultSecretGenerators: &SecretGenerators{
ClientSecret: emptyConfig,
},
checkPermission: newMockPermissionCheckAllowed(),
}
now := time.Now()
gotSecret, gotChangeDate, err := r.ChangeApplicationSecret(tt.args.ctx, tt.args.projectID, tt.args.appID, tt.args.resourceOwner)
assert.ErrorIs(t, err, tt.res.err)
assert.Equal(t, tt.res.wantSecret, gotSecret)
if tt.res.wantChangeDate != (time.Time{}) {
assert.WithinRange(t, gotChangeDate, now, time.Now())
}
})
}
}