zitadel-oidc/pkg/oidc/util_test.go
Tim Möhlmann dea8bc96ea
refactor: use struct types for claim related types (#283)
* oidc: add regression tests for token claim json

this helps to verify that the same JSON is produced,
after these types are refactored.

* refactor: use struct types for claim related types

BREAKING CHANGE:
The following types are changed from interface to struct type:

- AccessTokenClaims
- IDTokenClaims
- IntrospectionResponse
- UserInfo and related types.

The following methods of OPStorage now take a pointer to a struct type,
instead of an interface:

- SetUserinfoFromScopes
- SetUserinfoFromToken
- SetIntrospectionFromToken

The following functions are now generic, so that type-safe extension
of Claims is now possible:

- op.VerifyIDTokenHint
- op.VerifyAccessToken
- rp.VerifyTokens
- rp.VerifyIDToken

- Changed UserInfoAddress to pointer in UserInfo and
IntrospectionResponse.
This was needed to make omitempty work correctly.
- Copy or merge maps in IntrospectionResponse and SetUserInfo

* op: add example for VerifyAccessToken

* fix: rp: wrong assignment in WithIssuedAtMaxAge

WithIssuedAtMaxAge assigned its value to v.maxAge, which was wrong.
This change fixes that by assiging the duration to v.maxAgeIAT.

* rp: add VerifyTokens example

* oidc: add standard references to:

- IDTokenClaims
- IntrospectionResponse
- UserInfo

* only count coverage for `./pkg/...`
2023-03-10 16:31:22 +02:00

147 lines
2.5 KiB
Go

package oidc
import (
"errors"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
type jsonErrorTest struct{}
func (jsonErrorTest) MarshalJSON() ([]byte, error) {
return nil, errors.New("test")
}
func Test_mergeAndMarshalClaims(t *testing.T) {
type args struct {
registered any
claims map[string]any
}
tests := []struct {
name string
args args
want string
wantErr bool
}{
{
name: "encoder error",
args: args{
registered: jsonErrorTest{},
},
wantErr: true,
},
{
name: "no claims",
args: args{
registered: struct {
Foo string `json:"foo,omitempty"`
}{
Foo: "bar",
},
},
want: "{\"foo\":\"bar\"}\n",
},
{
name: "with claims",
args: args{
registered: struct {
Foo string `json:"foo,omitempty"`
}{
Foo: "bar",
},
claims: map[string]any{
"bar": "foo",
},
},
want: "{\"bar\":\"foo\",\"foo\":\"bar\"}\n",
},
{
name: "registered overwrites custom",
args: args{
registered: struct {
Foo string `json:"foo,omitempty"`
}{
Foo: "bar",
},
claims: map[string]any{
"foo": "Hello, World!",
},
},
want: "{\"foo\":\"bar\"}\n",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := mergeAndMarshalClaims(tt.args.registered, tt.args.claims)
if tt.wantErr {
require.Error(t, err)
} else {
require.NoError(t, err)
}
assert.Equal(t, tt.want, string(got))
})
}
}
func Test_unmarshalJSONMulti(t *testing.T) {
type dst struct {
Foo string `json:"foo,omitempty"`
}
type args struct {
data string
destinations []any
}
tests := []struct {
name string
args args
want []any
wantErr bool
}{
{
name: "error",
args: args{
data: "~!~~",
destinations: []any{
&dst{},
&map[string]any{},
},
},
want: []any{
&dst{},
&map[string]any{},
},
wantErr: true,
},
{
name: "success",
args: args{
data: "{\"bar\":\"foo\",\"foo\":\"bar\"}\n",
destinations: []any{
&dst{},
&map[string]any{},
},
},
want: []any{
&dst{Foo: "bar"},
&map[string]any{
"foo": "bar",
"bar": "foo",
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := unmarshalJSONMulti([]byte(tt.args.data), tt.args.destinations...)
if tt.wantErr {
require.Error(t, err)
} else {
require.NoError(t, err)
}
assert.Equal(t, tt.want, tt.args.destinations)
})
}
}