// 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 TestEllipticCurveAlgorithm(t *testing.T) {
	t.Parallel()
	t.Run(`Lookup the object`, func(t *testing.T) {
		t.Parallel()
		v, ok := jwa.LookupEllipticCurveAlgorithm("Ed25519")
		require.True(t, ok, `Lookup should succeed`)
		require.Equal(t, jwa.Ed25519(), v, `Lookup value should be equal to constant`)
	})
	t.Run(`Unmarshal the string Ed25519`, func(t *testing.T) {
		t.Parallel()
		var dst jwa.EllipticCurveAlgorithm
		require.NoError(t, json.Unmarshal([]byte(strconv.Quote("Ed25519")), &dst), `UnmarshalJSON is successful`)
		require.Equal(t, jwa.Ed25519(), dst, `unmarshaled value should be equal to constant`)
	})
	t.Run(`stringification for Ed25519`, func(t *testing.T) {
		t.Parallel()
		require.Equal(t, "Ed25519", jwa.Ed25519().String(), `stringified value matches`)
	})
	t.Run(`Lookup the object`, func(t *testing.T) {
		t.Parallel()
		v, ok := jwa.LookupEllipticCurveAlgorithm("Ed448")
		require.True(t, ok, `Lookup should succeed`)
		require.Equal(t, jwa.Ed448(), v, `Lookup value should be equal to constant`)
	})
	t.Run(`Unmarshal the string Ed448`, func(t *testing.T) {
		t.Parallel()
		var dst jwa.EllipticCurveAlgorithm
		require.NoError(t, json.Unmarshal([]byte(strconv.Quote("Ed448")), &dst), `UnmarshalJSON is successful`)
		require.Equal(t, jwa.Ed448(), dst, `unmarshaled value should be equal to constant`)
	})
	t.Run(`stringification for Ed448`, func(t *testing.T) {
		t.Parallel()
		require.Equal(t, "Ed448", jwa.Ed448().String(), `stringified value matches`)
	})
	t.Run(`Lookup the object`, func(t *testing.T) {
		t.Parallel()
		v, ok := jwa.LookupEllipticCurveAlgorithm("P-256")
		require.True(t, ok, `Lookup should succeed`)
		require.Equal(t, jwa.P256(), v, `Lookup value should be equal to constant`)
	})
	t.Run(`Unmarshal the string P-256`, func(t *testing.T) {
		t.Parallel()
		var dst jwa.EllipticCurveAlgorithm
		require.NoError(t, json.Unmarshal([]byte(strconv.Quote("P-256")), &dst), `UnmarshalJSON is successful`)
		require.Equal(t, jwa.P256(), dst, `unmarshaled value should be equal to constant`)
	})
	t.Run(`stringification for P-256`, func(t *testing.T) {
		t.Parallel()
		require.Equal(t, "P-256", jwa.P256().String(), `stringified value matches`)
	})
	t.Run(`Lookup the object`, func(t *testing.T) {
		t.Parallel()
		v, ok := jwa.LookupEllipticCurveAlgorithm("P-384")
		require.True(t, ok, `Lookup should succeed`)
		require.Equal(t, jwa.P384(), v, `Lookup value should be equal to constant`)
	})
	t.Run(`Unmarshal the string P-384`, func(t *testing.T) {
		t.Parallel()
		var dst jwa.EllipticCurveAlgorithm
		require.NoError(t, json.Unmarshal([]byte(strconv.Quote("P-384")), &dst), `UnmarshalJSON is successful`)
		require.Equal(t, jwa.P384(), dst, `unmarshaled value should be equal to constant`)
	})
	t.Run(`stringification for P-384`, func(t *testing.T) {
		t.Parallel()
		require.Equal(t, "P-384", jwa.P384().String(), `stringified value matches`)
	})
	t.Run(`Lookup the object`, func(t *testing.T) {
		t.Parallel()
		v, ok := jwa.LookupEllipticCurveAlgorithm("P-521")
		require.True(t, ok, `Lookup should succeed`)
		require.Equal(t, jwa.P521(), v, `Lookup value should be equal to constant`)
	})
	t.Run(`Unmarshal the string P-521`, func(t *testing.T) {
		t.Parallel()
		var dst jwa.EllipticCurveAlgorithm
		require.NoError(t, json.Unmarshal([]byte(strconv.Quote("P-521")), &dst), `UnmarshalJSON is successful`)
		require.Equal(t, jwa.P521(), dst, `unmarshaled value should be equal to constant`)
	})
	t.Run(`stringification for P-521`, func(t *testing.T) {
		t.Parallel()
		require.Equal(t, "P-521", jwa.P521().String(), `stringified value matches`)
	})
	t.Run(`Lookup the object`, func(t *testing.T) {
		t.Parallel()
		v, ok := jwa.LookupEllipticCurveAlgorithm("X25519")
		require.True(t, ok, `Lookup should succeed`)
		require.Equal(t, jwa.X25519(), v, `Lookup value should be equal to constant`)
	})
	t.Run(`Unmarshal the string X25519`, func(t *testing.T) {
		t.Parallel()
		var dst jwa.EllipticCurveAlgorithm
		require.NoError(t, json.Unmarshal([]byte(strconv.Quote("X25519")), &dst), `UnmarshalJSON is successful`)
		require.Equal(t, jwa.X25519(), dst, `unmarshaled value should be equal to constant`)
	})
	t.Run(`stringification for X25519`, func(t *testing.T) {
		t.Parallel()
		require.Equal(t, "X25519", jwa.X25519().String(), `stringified value matches`)
	})
	t.Run(`Lookup the object`, func(t *testing.T) {
		t.Parallel()
		v, ok := jwa.LookupEllipticCurveAlgorithm("X448")
		require.True(t, ok, `Lookup should succeed`)
		require.Equal(t, jwa.X448(), v, `Lookup value should be equal to constant`)
	})
	t.Run(`Unmarshal the string X448`, func(t *testing.T) {
		t.Parallel()
		var dst jwa.EllipticCurveAlgorithm
		require.NoError(t, json.Unmarshal([]byte(strconv.Quote("X448")), &dst), `UnmarshalJSON is successful`)
		require.Equal(t, jwa.X448(), dst, `unmarshaled value should be equal to constant`)
	})
	t.Run(`stringification for X448`, func(t *testing.T) {
		t.Parallel()
		require.Equal(t, "X448", jwa.X448().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.EllipticCurveAlgorithm
		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.EllipticCurveAlgorithm]struct{}{
			jwa.Ed25519(): {},
			jwa.Ed448():   {},
			jwa.P256():    {},
			jwa.P384():    {},
			jwa.P521():    {},
			jwa.X25519():  {},
			jwa.X448():    {},
		}
		for _, v := range jwa.EllipticCurveAlgorithms() {
			// There is no good way to detect from a test if es256k (secp256k1)
			// is supported, so just allow it
			if v.String() == `secp256k1` {
				continue
			}
			_, ok := expected[v]
			require.True(t, ok, `%q should be in the list for EllipticCurveAlgorithm`, 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 TestEllipticCurveAlgorithmCustomAlgorithm(t *testing.T) {
	// These subtests can NOT be run in parallel as options with global effect change.
	const customAlgorithmValue = `custom-algorithm`
	customAlgorithm := jwa.NewEllipticCurveAlgorithm(customAlgorithmValue)
	// Unregister the custom algorithm, in case tests fail.
	t.Cleanup(func() {
		jwa.UnregisterEllipticCurveAlgorithm(customAlgorithm)
	})
	t.Run(`with custom algorithm registered`, func(t *testing.T) {
		jwa.RegisterEllipticCurveAlgorithm(customAlgorithm)
		t.Run(`Lookup the object`, func(t *testing.T) {
			t.Parallel()
			v, ok := jwa.LookupEllipticCurveAlgorithm(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.EllipticCurveAlgorithm
			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.UnregisterEllipticCurveAlgorithm(customAlgorithm)
		t.Run(`Lookup the object`, func(t *testing.T) {
			t.Parallel()
			_, ok := jwa.LookupEllipticCurveAlgorithm(customAlgorithmValue)
			require.False(t, ok, `Lookup should fail`)
		})
		t.Run(`Unmarshal custom algorithm`, func(t *testing.T) {
			t.Parallel()
			var dst jwa.EllipticCurveAlgorithm
			require.Error(t, json.Unmarshal([]byte(customAlgorithmValue), &dst), `Unmarshal should fail`)
		})
	})
}
