// Code generated by tools/cmd/genjwa/main.go. DO NOT EDIT

package jwa_test

import (
	"encoding/json"
	"strconv"
	"testing"

	"github.com/lestrrat-go/jwx/v3/jwa"
	"github.com/stretchr/testify/require"
)

func TestKeyType(t *testing.T) {
	t.Parallel()
	t.Run(`Lookup the object`, func(t *testing.T) {
		t.Parallel()
		v, ok := jwa.LookupKeyType("EC")
		require.True(t, ok, `Lookup should succeed`)
		require.Equal(t, jwa.EC(), v, `Lookup value should be equal to constant`)
	})
	t.Run(`Unmarshal the string EC`, func(t *testing.T) {
		t.Parallel()
		var dst jwa.KeyType
		require.NoError(t, json.Unmarshal([]byte(strconv.Quote("EC")), &dst), `UnmarshalJSON is successful`)
		require.Equal(t, jwa.EC(), dst, `unmarshaled value should be equal to constant`)
	})
	t.Run(`stringification for EC`, func(t *testing.T) {
		t.Parallel()
		require.Equal(t, "EC", jwa.EC().String(), `stringified value matches`)
	})
	t.Run(`Lookup the object`, func(t *testing.T) {
		t.Parallel()
		v, ok := jwa.LookupKeyType("OKP")
		require.True(t, ok, `Lookup should succeed`)
		require.Equal(t, jwa.OKP(), v, `Lookup value should be equal to constant`)
	})
	t.Run(`Unmarshal the string OKP`, func(t *testing.T) {
		t.Parallel()
		var dst jwa.KeyType
		require.NoError(t, json.Unmarshal([]byte(strconv.Quote("OKP")), &dst), `UnmarshalJSON is successful`)
		require.Equal(t, jwa.OKP(), dst, `unmarshaled value should be equal to constant`)
	})
	t.Run(`stringification for OKP`, func(t *testing.T) {
		t.Parallel()
		require.Equal(t, "OKP", jwa.OKP().String(), `stringified value matches`)
	})
	t.Run(`Lookup the object`, func(t *testing.T) {
		t.Parallel()
		v, ok := jwa.LookupKeyType("oct")
		require.True(t, ok, `Lookup should succeed`)
		require.Equal(t, jwa.OctetSeq(), v, `Lookup value should be equal to constant`)
	})
	t.Run(`Unmarshal the string oct`, func(t *testing.T) {
		t.Parallel()
		var dst jwa.KeyType
		require.NoError(t, json.Unmarshal([]byte(strconv.Quote("oct")), &dst), `UnmarshalJSON is successful`)
		require.Equal(t, jwa.OctetSeq(), dst, `unmarshaled value should be equal to constant`)
	})
	t.Run(`stringification for oct`, func(t *testing.T) {
		t.Parallel()
		require.Equal(t, "oct", jwa.OctetSeq().String(), `stringified value matches`)
	})
	t.Run(`Lookup the object`, func(t *testing.T) {
		t.Parallel()
		v, ok := jwa.LookupKeyType("RSA")
		require.True(t, ok, `Lookup should succeed`)
		require.Equal(t, jwa.RSA(), v, `Lookup value should be equal to constant`)
	})
	t.Run(`Unmarshal the string RSA`, func(t *testing.T) {
		t.Parallel()
		var dst jwa.KeyType
		require.NoError(t, json.Unmarshal([]byte(strconv.Quote("RSA")), &dst), `UnmarshalJSON is successful`)
		require.Equal(t, jwa.RSA(), dst, `unmarshaled value should be equal to constant`)
	})
	t.Run(`stringification for RSA`, func(t *testing.T) {
		t.Parallel()
		require.Equal(t, "RSA", jwa.RSA().String(), `stringified value matches`)
	})
	t.Run(`Unmarshal should fail for invalid value (totally made up) string value`, func(t *testing.T) {
		t.Parallel()
		var dst jwa.KeyType
		require.Error(t, json.Unmarshal([]byte(`totallyInvalidValue`), &dst), `Unmarshal should fail`)
	})
	t.Run(`check list of elements`, func(t *testing.T) {
		t.Parallel()
		var expected = map[jwa.KeyType]struct{}{
			jwa.EC():       {},
			jwa.OKP():      {},
			jwa.OctetSeq(): {},
			jwa.RSA():      {},
		}
		for _, v := range jwa.KeyTypes() {
			_, ok := expected[v]
			require.True(t, ok, `%q should be in the list for KeyType`, v)
			delete(expected, v)
		}
		require.Len(t, expected, 0)
	})
}

// Note: this test can NOT be run in parallel as it uses options with global effect.
func TestKeyTypeCustomAlgorithm(t *testing.T) {
	// These subtests can NOT be run in parallel as options with global effect change.
	const customAlgorithmValue = `custom-algorithm`
	customAlgorithm := jwa.NewKeyType(customAlgorithmValue)
	// Unregister the custom algorithm, in case tests fail.
	t.Cleanup(func() {
		jwa.UnregisterKeyType(customAlgorithm)
	})
	t.Run(`with custom algorithm registered`, func(t *testing.T) {
		jwa.RegisterKeyType(customAlgorithm)
		t.Run(`Lookup the object`, func(t *testing.T) {
			t.Parallel()
			v, ok := jwa.LookupKeyType(customAlgorithmValue)
			require.True(t, ok, `Lookup should succeed`)
			require.Equal(t, customAlgorithm, v, `Lookup value should be equal to constant`)
		})
		t.Run(`Unmarshal custom algorithm`, func(t *testing.T) {
			t.Parallel()
			var dst jwa.KeyType
			require.NoError(t, json.Unmarshal([]byte(strconv.Quote(customAlgorithmValue)), &dst), `Unmarshal is successful`)
			require.Equal(t, customAlgorithm, dst, `accepted value should be equal to variable`)
		})
	})
	t.Run(`with custom algorithm deregistered`, func(t *testing.T) {
		jwa.UnregisterKeyType(customAlgorithm)
		t.Run(`Lookup the object`, func(t *testing.T) {
			t.Parallel()
			_, ok := jwa.LookupKeyType(customAlgorithmValue)
			require.False(t, ok, `Lookup should fail`)
		})
		t.Run(`Unmarshal custom algorithm`, func(t *testing.T) {
			t.Parallel()
			var dst jwa.KeyType
			require.Error(t, json.Unmarshal([]byte(customAlgorithmValue), &dst), `Unmarshal should fail`)
		})
	})
}
