// 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 TestSignatureAlgorithm(t *testing.T) {
	t.Parallel()
	t.Run(`Lookup the object`, func(t *testing.T) {
		t.Parallel()
		v, ok := jwa.LookupSignatureAlgorithm("ES256")
		require.True(t, ok, `Lookup should succeed`)
		require.Equal(t, jwa.ES256(), v, `Lookup value should be equal to constant`)
	})
	t.Run(`Unmarshal the string ES256`, func(t *testing.T) {
		t.Parallel()
		var dst jwa.SignatureAlgorithm
		require.NoError(t, json.Unmarshal([]byte(strconv.Quote("ES256")), &dst), `UnmarshalJSON is successful`)
		require.Equal(t, jwa.ES256(), dst, `unmarshaled value should be equal to constant`)
	})
	t.Run(`stringification for ES256`, func(t *testing.T) {
		t.Parallel()
		require.Equal(t, "ES256", jwa.ES256().String(), `stringified value matches`)
	})
	t.Run(`Lookup the object`, func(t *testing.T) {
		t.Parallel()
		v, ok := jwa.LookupSignatureAlgorithm("ES256K")
		require.True(t, ok, `Lookup should succeed`)
		require.Equal(t, jwa.ES256K(), v, `Lookup value should be equal to constant`)
	})
	t.Run(`Unmarshal the string ES256K`, func(t *testing.T) {
		t.Parallel()
		var dst jwa.SignatureAlgorithm
		require.NoError(t, json.Unmarshal([]byte(strconv.Quote("ES256K")), &dst), `UnmarshalJSON is successful`)
		require.Equal(t, jwa.ES256K(), dst, `unmarshaled value should be equal to constant`)
	})
	t.Run(`stringification for ES256K`, func(t *testing.T) {
		t.Parallel()
		require.Equal(t, "ES256K", jwa.ES256K().String(), `stringified value matches`)
	})
	t.Run(`Lookup the object`, func(t *testing.T) {
		t.Parallel()
		v, ok := jwa.LookupSignatureAlgorithm("ES384")
		require.True(t, ok, `Lookup should succeed`)
		require.Equal(t, jwa.ES384(), v, `Lookup value should be equal to constant`)
	})
	t.Run(`Unmarshal the string ES384`, func(t *testing.T) {
		t.Parallel()
		var dst jwa.SignatureAlgorithm
		require.NoError(t, json.Unmarshal([]byte(strconv.Quote("ES384")), &dst), `UnmarshalJSON is successful`)
		require.Equal(t, jwa.ES384(), dst, `unmarshaled value should be equal to constant`)
	})
	t.Run(`stringification for ES384`, func(t *testing.T) {
		t.Parallel()
		require.Equal(t, "ES384", jwa.ES384().String(), `stringified value matches`)
	})
	t.Run(`Lookup the object`, func(t *testing.T) {
		t.Parallel()
		v, ok := jwa.LookupSignatureAlgorithm("ES512")
		require.True(t, ok, `Lookup should succeed`)
		require.Equal(t, jwa.ES512(), v, `Lookup value should be equal to constant`)
	})
	t.Run(`Unmarshal the string ES512`, func(t *testing.T) {
		t.Parallel()
		var dst jwa.SignatureAlgorithm
		require.NoError(t, json.Unmarshal([]byte(strconv.Quote("ES512")), &dst), `UnmarshalJSON is successful`)
		require.Equal(t, jwa.ES512(), dst, `unmarshaled value should be equal to constant`)
	})
	t.Run(`stringification for ES512`, func(t *testing.T) {
		t.Parallel()
		require.Equal(t, "ES512", jwa.ES512().String(), `stringified value matches`)
	})
	t.Run(`Lookup the object`, func(t *testing.T) {
		t.Parallel()
		v, ok := jwa.LookupSignatureAlgorithm("EdDSA")
		require.True(t, ok, `Lookup should succeed`)
		require.Equal(t, jwa.EdDSA(), v, `Lookup value should be equal to constant`)
	})
	t.Run(`Unmarshal the string EdDSA`, func(t *testing.T) {
		t.Parallel()
		var dst jwa.SignatureAlgorithm
		require.NoError(t, json.Unmarshal([]byte(strconv.Quote("EdDSA")), &dst), `UnmarshalJSON is successful`)
		require.Equal(t, jwa.EdDSA(), dst, `unmarshaled value should be equal to constant`)
	})
	t.Run(`stringification for EdDSA`, func(t *testing.T) {
		t.Parallel()
		require.Equal(t, "EdDSA", jwa.EdDSA().String(), `stringified value matches`)
	})
	t.Run(`Lookup the object`, func(t *testing.T) {
		t.Parallel()
		v, ok := jwa.LookupSignatureAlgorithm("HS256")
		require.True(t, ok, `Lookup should succeed`)
		require.Equal(t, jwa.HS256(), v, `Lookup value should be equal to constant`)
	})
	t.Run(`Unmarshal the string HS256`, func(t *testing.T) {
		t.Parallel()
		var dst jwa.SignatureAlgorithm
		require.NoError(t, json.Unmarshal([]byte(strconv.Quote("HS256")), &dst), `UnmarshalJSON is successful`)
		require.Equal(t, jwa.HS256(), dst, `unmarshaled value should be equal to constant`)
	})
	t.Run(`stringification for HS256`, func(t *testing.T) {
		t.Parallel()
		require.Equal(t, "HS256", jwa.HS256().String(), `stringified value matches`)
	})
	t.Run(`Lookup the object`, func(t *testing.T) {
		t.Parallel()
		v, ok := jwa.LookupSignatureAlgorithm("HS384")
		require.True(t, ok, `Lookup should succeed`)
		require.Equal(t, jwa.HS384(), v, `Lookup value should be equal to constant`)
	})
	t.Run(`Unmarshal the string HS384`, func(t *testing.T) {
		t.Parallel()
		var dst jwa.SignatureAlgorithm
		require.NoError(t, json.Unmarshal([]byte(strconv.Quote("HS384")), &dst), `UnmarshalJSON is successful`)
		require.Equal(t, jwa.HS384(), dst, `unmarshaled value should be equal to constant`)
	})
	t.Run(`stringification for HS384`, func(t *testing.T) {
		t.Parallel()
		require.Equal(t, "HS384", jwa.HS384().String(), `stringified value matches`)
	})
	t.Run(`Lookup the object`, func(t *testing.T) {
		t.Parallel()
		v, ok := jwa.LookupSignatureAlgorithm("HS512")
		require.True(t, ok, `Lookup should succeed`)
		require.Equal(t, jwa.HS512(), v, `Lookup value should be equal to constant`)
	})
	t.Run(`Unmarshal the string HS512`, func(t *testing.T) {
		t.Parallel()
		var dst jwa.SignatureAlgorithm
		require.NoError(t, json.Unmarshal([]byte(strconv.Quote("HS512")), &dst), `UnmarshalJSON is successful`)
		require.Equal(t, jwa.HS512(), dst, `unmarshaled value should be equal to constant`)
	})
	t.Run(`stringification for HS512`, func(t *testing.T) {
		t.Parallel()
		require.Equal(t, "HS512", jwa.HS512().String(), `stringified value matches`)
	})
	t.Run(`Lookup the object`, func(t *testing.T) {
		t.Parallel()
		v, ok := jwa.LookupSignatureAlgorithm("none")
		require.True(t, ok, `Lookup should succeed`)
		require.Equal(t, jwa.NoSignature(), v, `Lookup value should be equal to constant`)
	})
	t.Run(`Unmarshal the string none`, func(t *testing.T) {
		t.Parallel()
		var dst jwa.SignatureAlgorithm
		require.NoError(t, json.Unmarshal([]byte(strconv.Quote("none")), &dst), `UnmarshalJSON is successful`)
		require.Equal(t, jwa.NoSignature(), dst, `unmarshaled value should be equal to constant`)
	})
	t.Run(`stringification for none`, func(t *testing.T) {
		t.Parallel()
		require.Equal(t, "none", jwa.NoSignature().String(), `stringified value matches`)
	})
	t.Run(`Lookup the object`, func(t *testing.T) {
		t.Parallel()
		v, ok := jwa.LookupSignatureAlgorithm("PS256")
		require.True(t, ok, `Lookup should succeed`)
		require.Equal(t, jwa.PS256(), v, `Lookup value should be equal to constant`)
	})
	t.Run(`Unmarshal the string PS256`, func(t *testing.T) {
		t.Parallel()
		var dst jwa.SignatureAlgorithm
		require.NoError(t, json.Unmarshal([]byte(strconv.Quote("PS256")), &dst), `UnmarshalJSON is successful`)
		require.Equal(t, jwa.PS256(), dst, `unmarshaled value should be equal to constant`)
	})
	t.Run(`stringification for PS256`, func(t *testing.T) {
		t.Parallel()
		require.Equal(t, "PS256", jwa.PS256().String(), `stringified value matches`)
	})
	t.Run(`Lookup the object`, func(t *testing.T) {
		t.Parallel()
		v, ok := jwa.LookupSignatureAlgorithm("PS384")
		require.True(t, ok, `Lookup should succeed`)
		require.Equal(t, jwa.PS384(), v, `Lookup value should be equal to constant`)
	})
	t.Run(`Unmarshal the string PS384`, func(t *testing.T) {
		t.Parallel()
		var dst jwa.SignatureAlgorithm
		require.NoError(t, json.Unmarshal([]byte(strconv.Quote("PS384")), &dst), `UnmarshalJSON is successful`)
		require.Equal(t, jwa.PS384(), dst, `unmarshaled value should be equal to constant`)
	})
	t.Run(`stringification for PS384`, func(t *testing.T) {
		t.Parallel()
		require.Equal(t, "PS384", jwa.PS384().String(), `stringified value matches`)
	})
	t.Run(`Lookup the object`, func(t *testing.T) {
		t.Parallel()
		v, ok := jwa.LookupSignatureAlgorithm("PS512")
		require.True(t, ok, `Lookup should succeed`)
		require.Equal(t, jwa.PS512(), v, `Lookup value should be equal to constant`)
	})
	t.Run(`Unmarshal the string PS512`, func(t *testing.T) {
		t.Parallel()
		var dst jwa.SignatureAlgorithm
		require.NoError(t, json.Unmarshal([]byte(strconv.Quote("PS512")), &dst), `UnmarshalJSON is successful`)
		require.Equal(t, jwa.PS512(), dst, `unmarshaled value should be equal to constant`)
	})
	t.Run(`stringification for PS512`, func(t *testing.T) {
		t.Parallel()
		require.Equal(t, "PS512", jwa.PS512().String(), `stringified value matches`)
	})
	t.Run(`Lookup the object`, func(t *testing.T) {
		t.Parallel()
		v, ok := jwa.LookupSignatureAlgorithm("RS256")
		require.True(t, ok, `Lookup should succeed`)
		require.Equal(t, jwa.RS256(), v, `Lookup value should be equal to constant`)
	})
	t.Run(`Unmarshal the string RS256`, func(t *testing.T) {
		t.Parallel()
		var dst jwa.SignatureAlgorithm
		require.NoError(t, json.Unmarshal([]byte(strconv.Quote("RS256")), &dst), `UnmarshalJSON is successful`)
		require.Equal(t, jwa.RS256(), dst, `unmarshaled value should be equal to constant`)
	})
	t.Run(`stringification for RS256`, func(t *testing.T) {
		t.Parallel()
		require.Equal(t, "RS256", jwa.RS256().String(), `stringified value matches`)
	})
	t.Run(`Lookup the object`, func(t *testing.T) {
		t.Parallel()
		v, ok := jwa.LookupSignatureAlgorithm("RS384")
		require.True(t, ok, `Lookup should succeed`)
		require.Equal(t, jwa.RS384(), v, `Lookup value should be equal to constant`)
	})
	t.Run(`Unmarshal the string RS384`, func(t *testing.T) {
		t.Parallel()
		var dst jwa.SignatureAlgorithm
		require.NoError(t, json.Unmarshal([]byte(strconv.Quote("RS384")), &dst), `UnmarshalJSON is successful`)
		require.Equal(t, jwa.RS384(), dst, `unmarshaled value should be equal to constant`)
	})
	t.Run(`stringification for RS384`, func(t *testing.T) {
		t.Parallel()
		require.Equal(t, "RS384", jwa.RS384().String(), `stringified value matches`)
	})
	t.Run(`Lookup the object`, func(t *testing.T) {
		t.Parallel()
		v, ok := jwa.LookupSignatureAlgorithm("RS512")
		require.True(t, ok, `Lookup should succeed`)
		require.Equal(t, jwa.RS512(), v, `Lookup value should be equal to constant`)
	})
	t.Run(`Unmarshal the string RS512`, func(t *testing.T) {
		t.Parallel()
		var dst jwa.SignatureAlgorithm
		require.NoError(t, json.Unmarshal([]byte(strconv.Quote("RS512")), &dst), `UnmarshalJSON is successful`)
		require.Equal(t, jwa.RS512(), dst, `unmarshaled value should be equal to constant`)
	})
	t.Run(`stringification for RS512`, func(t *testing.T) {
		t.Parallel()
		require.Equal(t, "RS512", jwa.RS512().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.SignatureAlgorithm
		require.Error(t, json.Unmarshal([]byte(`totallyInvalidValue`), &dst), `Unmarshal should fail`)
	})
	t.Run(`check symmetric values`, func(t *testing.T) {
		t.Parallel()
		t.Run(`ES256`, func(t *testing.T) {
			require.False(t, jwa.ES256().IsSymmetric(), `jwa.ES256 returns expected value`)
		})
		t.Run(`ES256K`, func(t *testing.T) {
			require.False(t, jwa.ES256K().IsSymmetric(), `jwa.ES256K returns expected value`)
		})
		t.Run(`ES384`, func(t *testing.T) {
			require.False(t, jwa.ES384().IsSymmetric(), `jwa.ES384 returns expected value`)
		})
		t.Run(`ES512`, func(t *testing.T) {
			require.False(t, jwa.ES512().IsSymmetric(), `jwa.ES512 returns expected value`)
		})
		t.Run(`EdDSA`, func(t *testing.T) {
			require.False(t, jwa.EdDSA().IsSymmetric(), `jwa.EdDSA returns expected value`)
		})
		t.Run(`HS256`, func(t *testing.T) {
			require.True(t, jwa.HS256().IsSymmetric(), `jwa.HS256 returns expected value`)
		})
		t.Run(`HS384`, func(t *testing.T) {
			require.True(t, jwa.HS384().IsSymmetric(), `jwa.HS384 returns expected value`)
		})
		t.Run(`HS512`, func(t *testing.T) {
			require.True(t, jwa.HS512().IsSymmetric(), `jwa.HS512 returns expected value`)
		})
		t.Run(`NoSignature`, func(t *testing.T) {
			require.False(t, jwa.NoSignature().IsSymmetric(), `jwa.NoSignature returns expected value`)
		})
		t.Run(`PS256`, func(t *testing.T) {
			require.False(t, jwa.PS256().IsSymmetric(), `jwa.PS256 returns expected value`)
		})
		t.Run(`PS384`, func(t *testing.T) {
			require.False(t, jwa.PS384().IsSymmetric(), `jwa.PS384 returns expected value`)
		})
		t.Run(`PS512`, func(t *testing.T) {
			require.False(t, jwa.PS512().IsSymmetric(), `jwa.PS512 returns expected value`)
		})
		t.Run(`RS256`, func(t *testing.T) {
			require.False(t, jwa.RS256().IsSymmetric(), `jwa.RS256 returns expected value`)
		})
		t.Run(`RS384`, func(t *testing.T) {
			require.False(t, jwa.RS384().IsSymmetric(), `jwa.RS384 returns expected value`)
		})
		t.Run(`RS512`, func(t *testing.T) {
			require.False(t, jwa.RS512().IsSymmetric(), `jwa.RS512 returns expected value`)
		})
	})
	t.Run(`check list of elements`, func(t *testing.T) {
		t.Parallel()
		var expected = map[jwa.SignatureAlgorithm]struct{}{
			jwa.ES256():       {},
			jwa.ES256K():      {},
			jwa.ES384():       {},
			jwa.ES512():       {},
			jwa.EdDSA():       {},
			jwa.HS256():       {},
			jwa.HS384():       {},
			jwa.HS512():       {},
			jwa.NoSignature(): {},
			jwa.PS256():       {},
			jwa.PS384():       {},
			jwa.PS512():       {},
			jwa.RS256():       {},
			jwa.RS384():       {},
			jwa.RS512():       {},
		}
		for _, v := range jwa.SignatureAlgorithms() {
			_, ok := expected[v]
			require.True(t, ok, `%q should be in the list for SignatureAlgorithm`, 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 TestSignatureAlgorithmCustomAlgorithm(t *testing.T) {
	// These subtests can NOT be run in parallel as options with global effect change.
	const customAlgorithmValue = `custom-algorithm`
	for _, symmetric := range []bool{true, false} {
		customAlgorithm := jwa.NewSignatureAlgorithm(customAlgorithmValue, jwa.WithIsSymmetric(symmetric))
		// Unregister the custom algorithm, in case tests fail.
		t.Cleanup(func() {
			jwa.UnregisterSignatureAlgorithm(customAlgorithm)
		})
		t.Run(`with custom algorithm registered`, func(t *testing.T) {
			jwa.RegisterSignatureAlgorithm(customAlgorithm)
			t.Run(`Lookup the object`, func(t *testing.T) {
				t.Parallel()
				v, ok := jwa.LookupSignatureAlgorithm(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.SignatureAlgorithm
				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(`check symmetric`, func(t *testing.T) {
				t.Parallel()
				require.Equal(t, symmetric, customAlgorithm.IsSymmetric(), `custom algorithm's symmetric attribute should match`)
			})
		})
		t.Run(`with custom algorithm deregistered`, func(t *testing.T) {
			jwa.UnregisterSignatureAlgorithm(customAlgorithm)
			t.Run(`Lookup the object`, func(t *testing.T) {
				t.Parallel()
				_, ok := jwa.LookupSignatureAlgorithm(customAlgorithmValue)
				require.False(t, ok, `Lookup should fail`)
			})
			t.Run(`Unmarshal custom algorithm`, func(t *testing.T) {
				t.Parallel()
				var dst jwa.SignatureAlgorithm
				require.Error(t, json.Unmarshal([]byte(customAlgorithmValue), &dst), `Unmarshal should fail`)
			})
		})
	}
}
