module Signet.Unstable.Type.SignaturesTest where import qualified Control.Monad.Catch as Exception import qualified Crypto.Error as Error import qualified Crypto.Hash as Hash import qualified Crypto.PubKey.Ed25519 as Ed25519 import qualified Data.ByteString as ByteString import qualified Data.ByteString.Char8 as Ascii import qualified Heck as Test import qualified Signet.Unstable.Exception.InvalidAsymmetricSignature as InvalidAsymmetricSignature import qualified Signet.Unstable.Exception.InvalidSignature as InvalidSignature import qualified Signet.Unstable.Exception.InvalidSymmetricSignature as InvalidSymmetricSignature import qualified Signet.Unstable.Exception.UnknownSignature as UnknownSignature import qualified Signet.Unstable.Extra.Either as Either import qualified Signet.Unstable.Type.AsymmetricSignature as AsymmetricSignature import qualified Signet.Unstable.Type.Signature as Signature import qualified Signet.Unstable.Type.Signatures as Signatures import qualified Signet.Unstable.Type.SymmetricSignature as SymmetricSignature spec :: (Exception.MonadThrow io, Monad tree) => Test.Test io tree -> tree () spec :: forall (io :: * -> *) (tree :: * -> *). (MonadThrow io, Monad tree) => Test io tree -> tree () spec Test io tree test = Test io tree -> String -> tree () -> tree () forall (m :: * -> *) (n :: * -> *). Test m n -> String -> n () -> n () Test.describe Test io tree test String "Signet.Unstable.Type.Signatures" (tree () -> tree ()) -> tree () -> tree () forall a b. (a -> b) -> a -> b $ do Test io tree -> String -> tree () -> tree () forall (m :: * -> *) (n :: * -> *). Test m n -> String -> n () -> n () Test.describe Test io tree test String "parse" (tree () -> tree ()) -> tree () -> tree () forall a b. (a -> b) -> a -> b $ do Test io tree -> String -> io () -> tree () forall (m :: * -> *) (n :: * -> *). Test m n -> String -> m () -> n () Test.it Test io tree test String "succeeds with no signatures" (io () -> tree ()) -> io () -> tree () forall a b. (a -> b) -> a -> b $ do Test io tree -> Either InvalidSignature ([UnknownSignature], Signatures) -> Either InvalidSignature ([UnknownSignature], Signatures) -> io () forall (m :: * -> *) a (n :: * -> *). (HasCallStack, Applicative m, Eq a, Show a) => Test m n -> a -> a -> m () Test.assertEq Test io tree test (ByteString -> Either InvalidSignature ([UnknownSignature], Signatures) Signatures.parse ByteString ByteString.empty) (([UnknownSignature], Signatures) -> Either InvalidSignature ([UnknownSignature], Signatures) forall a b. b -> Either a b Right ([], [Signature] -> Signatures Signatures.MkSignatures [])) Test io tree -> String -> io () -> tree () forall (m :: * -> *) (n :: * -> *). Test m n -> String -> m () -> n () Test.it Test io tree test String "succeeds with one signature" (io () -> tree ()) -> io () -> tree () forall a b. (a -> b) -> a -> b $ do let signature :: Signature signature = SymmetricSignature -> Signature Signature.Symmetric (SymmetricSignature -> Signature) -> (Digest SHA256 -> SymmetricSignature) -> Digest SHA256 -> Signature forall b c a. (b -> c) -> (a -> b) -> a -> c . Digest SHA256 -> SymmetricSignature SymmetricSignature.MkSymmetricSignature (Digest SHA256 -> Signature) -> Digest SHA256 -> Signature forall a b. (a -> b) -> a -> b $ ByteString -> Digest SHA256 forall ba a. (ByteArrayAccess ba, HashAlgorithm a) => ba -> Digest a Hash.hash ByteString ByteString.empty let byteString :: ByteString byteString = String -> ByteString Ascii.pack String "v1,47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=" Test io tree -> Either InvalidSignature ([UnknownSignature], Signatures) -> Either InvalidSignature ([UnknownSignature], Signatures) -> io () forall (m :: * -> *) a (n :: * -> *). (HasCallStack, Applicative m, Eq a, Show a) => Test m n -> a -> a -> m () Test.assertEq Test io tree test (ByteString -> Either InvalidSignature ([UnknownSignature], Signatures) Signatures.parse ByteString byteString) (([UnknownSignature], Signatures) -> Either InvalidSignature ([UnknownSignature], Signatures) forall a b. b -> Either a b Right ([], [Signature] -> Signatures Signatures.MkSignatures [Signature signature])) Test io tree -> String -> io () -> tree () forall (m :: * -> *) (n :: * -> *). Test m n -> String -> m () -> n () Test.it Test io tree test String "succeeds with many signatures" (io () -> tree ()) -> io () -> tree () forall a b. (a -> b) -> a -> b $ do let symmetricSignature :: SymmetricSignature symmetricSignature = Digest SHA256 -> SymmetricSignature SymmetricSignature.MkSymmetricSignature (Digest SHA256 -> SymmetricSignature) -> Digest SHA256 -> SymmetricSignature forall a b. (a -> b) -> a -> b $ ByteString -> Digest SHA256 forall ba a. (ByteArrayAccess ba, HashAlgorithm a) => ba -> Digest a Hash.hash ByteString ByteString.empty asymmetricSignature <- Either CryptoError AsymmetricSignature -> io AsymmetricSignature forall e (m :: * -> *) a. (Exception e, MonadThrow m) => Either e a -> m a Either.throw (Either CryptoError AsymmetricSignature -> io AsymmetricSignature) -> (ByteString -> Either CryptoError AsymmetricSignature) -> ByteString -> io AsymmetricSignature forall b c a. (b -> c) -> (a -> b) -> a -> c . (Signature -> AsymmetricSignature) -> Either CryptoError Signature -> Either CryptoError AsymmetricSignature forall a b. (a -> b) -> Either CryptoError a -> Either CryptoError b forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap Signature -> AsymmetricSignature AsymmetricSignature.MkAsymmetricSignature (Either CryptoError Signature -> Either CryptoError AsymmetricSignature) -> (ByteString -> Either CryptoError Signature) -> ByteString -> Either CryptoError AsymmetricSignature forall b c a. (b -> c) -> (a -> b) -> a -> c . CryptoFailable Signature -> Either CryptoError Signature forall a. CryptoFailable a -> Either CryptoError a Error.eitherCryptoError (CryptoFailable Signature -> Either CryptoError Signature) -> (ByteString -> CryptoFailable Signature) -> ByteString -> Either CryptoError Signature forall b c a. (b -> c) -> (a -> b) -> a -> c . ByteString -> CryptoFailable Signature forall ba. ByteArrayAccess ba => ba -> CryptoFailable Signature Ed25519.signature (ByteString -> io AsymmetricSignature) -> ByteString -> io AsymmetricSignature forall a b. (a -> b) -> a -> b $ String -> ByteString Ascii.pack String "ABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789-abcdefghijklmnopqrstuvqxyz" let byteString = String -> ByteString Ascii.pack String "v1,47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU= v1a,QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVotMDEyMzQ1Njc4OS1hYmNkZWZnaGlqa2xtbm9wcXJzdHV2cXh5eg==" let signatures = [Signature] -> Signatures Signatures.MkSignatures [ SymmetricSignature -> Signature Signature.Symmetric SymmetricSignature symmetricSignature, AsymmetricSignature -> Signature Signature.Asymmetric AsymmetricSignature asymmetricSignature ] Test.assertEq test (Signatures.parse byteString) (Right ([], signatures)) Test io tree -> String -> io () -> tree () forall (m :: * -> *) (n :: * -> *). Test m n -> String -> m () -> n () Test.it Test io tree test String "fails with an invalid symmetric signature" (io () -> tree ()) -> io () -> tree () forall a b. (a -> b) -> a -> b $ do let x :: ByteString x = String -> ByteString Ascii.pack String "invalid" let byteString :: ByteString byteString = String -> ByteString Ascii.pack String "v1," ByteString -> ByteString -> ByteString forall a. Semigroup a => a -> a -> a <> ByteString x Test io tree -> Either InvalidSignature ([UnknownSignature], Signatures) -> Either InvalidSignature ([UnknownSignature], Signatures) -> io () forall (m :: * -> *) a (n :: * -> *). (HasCallStack, Applicative m, Eq a, Show a) => Test m n -> a -> a -> m () Test.assertEq Test io tree test (ByteString -> Either InvalidSignature ([UnknownSignature], Signatures) Signatures.parse ByteString byteString) (InvalidSignature -> Either InvalidSignature ([UnknownSignature], Signatures) forall a b. a -> Either a b Left (InvalidSymmetricSignature -> InvalidSignature InvalidSignature.InvalidSymmetricSignature (InvalidSymmetricSignature -> InvalidSignature) -> InvalidSymmetricSignature -> InvalidSignature forall a b. (a -> b) -> a -> b $ ByteString -> InvalidSymmetricSignature InvalidSymmetricSignature.MkInvalidSymmetricSignature ByteString x)) Test io tree -> String -> io () -> tree () forall (m :: * -> *) (n :: * -> *). Test m n -> String -> m () -> n () Test.it Test io tree test String "fails with an invalid asymmetric signature" (io () -> tree ()) -> io () -> tree () forall a b. (a -> b) -> a -> b $ do let x :: ByteString x = String -> ByteString Ascii.pack String "invalid" let byteString :: ByteString byteString = String -> ByteString Ascii.pack String "v1a," ByteString -> ByteString -> ByteString forall a. Semigroup a => a -> a -> a <> ByteString x Test io tree -> Either InvalidSignature ([UnknownSignature], Signatures) -> Either InvalidSignature ([UnknownSignature], Signatures) -> io () forall (m :: * -> *) a (n :: * -> *). (HasCallStack, Applicative m, Eq a, Show a) => Test m n -> a -> a -> m () Test.assertEq Test io tree test (ByteString -> Either InvalidSignature ([UnknownSignature], Signatures) Signatures.parse ByteString byteString) (InvalidSignature -> Either InvalidSignature ([UnknownSignature], Signatures) forall a b. a -> Either a b Left (InvalidAsymmetricSignature -> InvalidSignature InvalidSignature.InvalidAsymmetricSignature (InvalidAsymmetricSignature -> InvalidSignature) -> InvalidAsymmetricSignature -> InvalidSignature forall a b. (a -> b) -> a -> b $ ByteString -> InvalidAsymmetricSignature InvalidAsymmetricSignature.MkInvalidAsymmetricSignature ByteString x)) Test io tree -> String -> io () -> tree () forall (m :: * -> *) (n :: * -> *). Test m n -> String -> m () -> n () Test.it Test io tree test String "succeeds with an unknown signature" (io () -> tree ()) -> io () -> tree () forall a b. (a -> b) -> a -> b $ do let byteString :: ByteString byteString = String -> ByteString Ascii.pack String "unknown" Test io tree -> Either InvalidSignature ([UnknownSignature], Signatures) -> Either InvalidSignature ([UnknownSignature], Signatures) -> io () forall (m :: * -> *) a (n :: * -> *). (HasCallStack, Applicative m, Eq a, Show a) => Test m n -> a -> a -> m () Test.assertEq Test io tree test (ByteString -> Either InvalidSignature ([UnknownSignature], Signatures) Signatures.parse ByteString byteString) (([UnknownSignature], Signatures) -> Either InvalidSignature ([UnknownSignature], Signatures) forall a b. b -> Either a b Right ([ByteString -> UnknownSignature UnknownSignature.MkUnknownSignature ByteString byteString], [Signature] -> Signatures Signatures.MkSignatures [])) Test io tree -> String -> tree () -> tree () forall (m :: * -> *) (n :: * -> *). Test m n -> String -> n () -> n () Test.describe Test io tree test String "render" (tree () -> tree ()) -> tree () -> tree () forall a b. (a -> b) -> a -> b $ do Test io tree -> String -> io () -> tree () forall (m :: * -> *) (n :: * -> *). Test m n -> String -> m () -> n () Test.it Test io tree test String "renders no signatures" (io () -> tree ()) -> io () -> tree () forall a b. (a -> b) -> a -> b $ do let signatures :: Signatures signatures = [Signature] -> Signatures Signatures.MkSignatures [] Test io tree -> ByteString -> ByteString -> io () forall (m :: * -> *) a (n :: * -> *). (HasCallStack, Applicative m, Eq a, Show a) => Test m n -> a -> a -> m () Test.assertEq Test io tree test (Signatures -> ByteString Signatures.render Signatures signatures) ByteString ByteString.empty Test io tree -> String -> io () -> tree () forall (m :: * -> *) (n :: * -> *). Test m n -> String -> m () -> n () Test.it Test io tree test String "renders one signature" (io () -> tree ()) -> io () -> tree () forall a b. (a -> b) -> a -> b $ do let signatures :: Signatures signatures = [Signature] -> Signatures Signatures.MkSignatures ([Signature] -> Signatures) -> (Digest SHA256 -> [Signature]) -> Digest SHA256 -> Signatures forall b c a. (b -> c) -> (a -> b) -> a -> c . Signature -> [Signature] forall a. a -> [a] forall (f :: * -> *) a. Applicative f => a -> f a pure (Signature -> [Signature]) -> (Digest SHA256 -> Signature) -> Digest SHA256 -> [Signature] forall b c a. (b -> c) -> (a -> b) -> a -> c . SymmetricSignature -> Signature Signature.Symmetric (SymmetricSignature -> Signature) -> (Digest SHA256 -> SymmetricSignature) -> Digest SHA256 -> Signature forall b c a. (b -> c) -> (a -> b) -> a -> c . Digest SHA256 -> SymmetricSignature SymmetricSignature.MkSymmetricSignature (Digest SHA256 -> Signatures) -> Digest SHA256 -> Signatures forall a b. (a -> b) -> a -> b $ ByteString -> Digest SHA256 forall ba a. (ByteArrayAccess ba, HashAlgorithm a) => ba -> Digest a Hash.hash ByteString ByteString.empty Test io tree -> ByteString -> ByteString -> io () forall (m :: * -> *) a (n :: * -> *). (HasCallStack, Applicative m, Eq a, Show a) => Test m n -> a -> a -> m () Test.assertEq Test io tree test (Signatures -> ByteString Signatures.render Signatures signatures) (String -> ByteString Ascii.pack String "v1,47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=") Test io tree -> String -> io () -> tree () forall (m :: * -> *) (n :: * -> *). Test m n -> String -> m () -> n () Test.it Test io tree test String "renders many signatures" (io () -> tree ()) -> io () -> tree () forall a b. (a -> b) -> a -> b $ do let symmetricSignature :: SymmetricSignature symmetricSignature = Digest SHA256 -> SymmetricSignature SymmetricSignature.MkSymmetricSignature (Digest SHA256 -> SymmetricSignature) -> Digest SHA256 -> SymmetricSignature forall a b. (a -> b) -> a -> b $ ByteString -> Digest SHA256 forall ba a. (ByteArrayAccess ba, HashAlgorithm a) => ba -> Digest a Hash.hash ByteString ByteString.empty asymmetricSignature <- Either CryptoError AsymmetricSignature -> io AsymmetricSignature forall e (m :: * -> *) a. (Exception e, MonadThrow m) => Either e a -> m a Either.throw (Either CryptoError AsymmetricSignature -> io AsymmetricSignature) -> (ByteString -> Either CryptoError AsymmetricSignature) -> ByteString -> io AsymmetricSignature forall b c a. (b -> c) -> (a -> b) -> a -> c . (Signature -> AsymmetricSignature) -> Either CryptoError Signature -> Either CryptoError AsymmetricSignature forall a b. (a -> b) -> Either CryptoError a -> Either CryptoError b forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap Signature -> AsymmetricSignature AsymmetricSignature.MkAsymmetricSignature (Either CryptoError Signature -> Either CryptoError AsymmetricSignature) -> (ByteString -> Either CryptoError Signature) -> ByteString -> Either CryptoError AsymmetricSignature forall b c a. (b -> c) -> (a -> b) -> a -> c . CryptoFailable Signature -> Either CryptoError Signature forall a. CryptoFailable a -> Either CryptoError a Error.eitherCryptoError (CryptoFailable Signature -> Either CryptoError Signature) -> (ByteString -> CryptoFailable Signature) -> ByteString -> Either CryptoError Signature forall b c a. (b -> c) -> (a -> b) -> a -> c . ByteString -> CryptoFailable Signature forall ba. ByteArrayAccess ba => ba -> CryptoFailable Signature Ed25519.signature (ByteString -> io AsymmetricSignature) -> ByteString -> io AsymmetricSignature forall a b. (a -> b) -> a -> b $ String -> ByteString Ascii.pack String "ABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789-abcdefghijklmnopqrstuvqxyz" let signatures = [Signature] -> Signatures Signatures.MkSignatures [ SymmetricSignature -> Signature Signature.Symmetric SymmetricSignature symmetricSignature, AsymmetricSignature -> Signature Signature.Asymmetric AsymmetricSignature asymmetricSignature ] Test.assertEq test (Signatures.render signatures) (Ascii.pack "v1,47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU= v1a,QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVotMDEyMzQ1Njc4OS1hYmNkZWZnaGlqa2xtbm9wcXJzdHV2cXh5eg==")