module Signet.Unstable.Type.SignerTest where

import qualified Control.Monad.Catch as Exception
import qualified Data.ByteString.Char8 as Ascii
import qualified Heck as Test
import qualified Signet.Unstable.Exception.InvalidSigner as InvalidSigner
import qualified Signet.Unstable.Extra.Either as Either
import qualified Signet.Unstable.Type.AsymmetricSignature as AsymmetricSignature
import qualified Signet.Unstable.Type.Message as Message
import qualified Signet.Unstable.Type.Secret as Secret
import qualified Signet.Unstable.Type.SecretKey as SecretKey
import qualified Signet.Unstable.Type.Signature as Signature
import qualified Signet.Unstable.Type.Signer as Signer
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.Signer" (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 a valid secret key" (io () -> tree ()) -> io () -> tree ()
forall a b. (a -> b) -> a -> b
$ do
      let byteString :: ByteString
byteString = String -> ByteString
Ascii.pack String
"whsk_QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU="
      let actual :: Either InvalidSigner Signer
actual = ByteString -> Either InvalidSigner Signer
Signer.parse ByteString
byteString
      secretKey <- Either InvalidSecretKey SecretKey -> io SecretKey
forall e (m :: * -> *) a.
(Exception e, MonadThrow m) =>
Either e a -> m a
Either.throw (Either InvalidSecretKey SecretKey -> io SecretKey)
-> Either InvalidSecretKey SecretKey -> io SecretKey
forall a b. (a -> b) -> a -> b
$ ByteString -> Either InvalidSecretKey SecretKey
SecretKey.parse ByteString
byteString
      Test.assertEq test actual (Right (Signer.Asymmetric secretKey))

    Test io tree -> String -> io () -> tree ()
forall (m :: * -> *) (n :: * -> *).
Test m n -> String -> m () -> n ()
Test.it Test io tree
test String
"succeeds with a valid secret" (io () -> tree ()) -> io () -> tree ()
forall a b. (a -> b) -> a -> b
$ do
      let byteString :: ByteString
byteString = String -> ByteString
Ascii.pack String
"whsec_bXlzZWNyZXRrZXkxMjM0NQ=="
      let actual :: Either InvalidSigner Signer
actual = ByteString -> Either InvalidSigner Signer
Signer.parse ByteString
byteString
      secret <- Either InvalidSecret Secret -> io Secret
forall e (m :: * -> *) a.
(Exception e, MonadThrow m) =>
Either e a -> m a
Either.throw (Either InvalidSecret Secret -> io Secret)
-> Either InvalidSecret Secret -> io Secret
forall a b. (a -> b) -> a -> b
$ ByteString -> Either InvalidSecret Secret
Secret.parse ByteString
byteString
      Test.assertEq test actual (Right (Signer.Symmetric secret))

    Test io tree -> String -> io () -> tree ()
forall (m :: * -> *) (n :: * -> *).
Test m n -> String -> m () -> n ()
Test.it Test io tree
test String
"fails with invalid input" (io () -> tree ()) -> io () -> tree ()
forall a b. (a -> b) -> a -> b
$ do
      let byteString :: ByteString
byteString = String -> ByteString
Ascii.pack String
"invalid"
      let actual :: Either InvalidSigner Signer
actual = ByteString -> Either InvalidSigner Signer
Signer.parse ByteString
byteString
      Test io tree
-> Either InvalidSigner Signer
-> Either InvalidSigner Signer
-> io ()
forall (m :: * -> *) a (n :: * -> *).
(HasCallStack, Applicative m, Eq a, Show a) =>
Test m n -> a -> a -> m ()
Test.assertEq Test io tree
test Either InvalidSigner Signer
actual (InvalidSigner -> Either InvalidSigner Signer
forall a b. a -> Either a b
Left (ByteString -> InvalidSigner
InvalidSigner.MkInvalidSigner ByteString
byteString))

  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
"works with a secret key" (io () -> tree ()) -> io () -> tree ()
forall a b. (a -> b) -> a -> b
$ do
      let byteString :: ByteString
byteString = String -> ByteString
Ascii.pack String
"whsk_QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU="
      secretKey <- Either InvalidSecretKey SecretKey -> io SecretKey
forall e (m :: * -> *) a.
(Exception e, MonadThrow m) =>
Either e a -> m a
Either.throw (Either InvalidSecretKey SecretKey -> io SecretKey)
-> (ByteString -> Either InvalidSecretKey SecretKey)
-> ByteString
-> io SecretKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Either InvalidSecretKey SecretKey
SecretKey.parse (ByteString -> io SecretKey) -> ByteString -> io SecretKey
forall a b. (a -> b) -> a -> b
$ ByteString
byteString
      Test.assertEq test (Signer.render (Signer.Asymmetric secretKey)) byteString

    Test io tree -> String -> io () -> tree ()
forall (m :: * -> *) (n :: * -> *).
Test m n -> String -> m () -> n ()
Test.it Test io tree
test String
"works with a secret" (io () -> tree ()) -> io () -> tree ()
forall a b. (a -> b) -> a -> b
$ do
      let byteString :: ByteString
byteString = String -> ByteString
Ascii.pack String
"whsec_bXlzZWNyZXRrZXkxMjM0NQ=="
      secret <- Either InvalidSecret Secret -> io Secret
forall e (m :: * -> *) a.
(Exception e, MonadThrow m) =>
Either e a -> m a
Either.throw (Either InvalidSecret Secret -> io Secret)
-> (ByteString -> Either InvalidSecret Secret)
-> ByteString
-> io Secret
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Either InvalidSecret Secret
Secret.parse (ByteString -> io Secret) -> ByteString -> io Secret
forall a b. (a -> b) -> a -> b
$ ByteString
byteString
      Test.assertEq test (Signer.render (Signer.Symmetric secret)) byteString

  Test io tree -> String -> tree () -> tree ()
forall (m :: * -> *) (n :: * -> *).
Test m n -> String -> n () -> n ()
Test.describe Test io tree
test String
"sign" (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
"works with asymmetric" (io () -> tree ()) -> io () -> tree ()
forall a b. (a -> b) -> a -> b
$ do
      signer <- Either InvalidSigner Signer -> io Signer
forall e (m :: * -> *) a.
(Exception e, MonadThrow m) =>
Either e a -> m a
Either.throw (Either InvalidSigner Signer -> io Signer)
-> (ByteString -> Either InvalidSigner Signer)
-> ByteString
-> io Signer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Either InvalidSigner Signer
Signer.parse (ByteString -> io Signer) -> ByteString -> io Signer
forall a b. (a -> b) -> a -> b
$ String -> ByteString
Ascii.pack String
"whsk_QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU="
      message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"
      let actual = Signer -> Message -> Signature
Signer.sign Signer
signer Message
message
      expected <- Either.throw =<< Either.throw (Signature.parse $ Ascii.pack "v1a,CV1O+PvrwXM42OMUX+tmm6bA3cS0tgLp0qo3YKuu0MGmBrsUhA0MHXF11HsEUJtPfTKs80WE7WUKVt9TueLDCQ==")
      Test.assertEq test actual expected

    Test io tree -> String -> io () -> tree ()
forall (m :: * -> *) (n :: * -> *).
Test m n -> String -> m () -> n ()
Test.it Test io tree
test String
"works with symmetric" (io () -> tree ()) -> io () -> tree ()
forall a b. (a -> b) -> a -> b
$ do
      signer <- Either InvalidSigner Signer -> io Signer
forall e (m :: * -> *) a.
(Exception e, MonadThrow m) =>
Either e a -> m a
Either.throw (Either InvalidSigner Signer -> io Signer)
-> (ByteString -> Either InvalidSigner Signer)
-> ByteString
-> io Signer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Either InvalidSigner Signer
Signer.parse (ByteString -> io Signer) -> ByteString -> io Signer
forall a b. (a -> b) -> a -> b
$ String -> ByteString
Ascii.pack String
"whsec_bXlzZWNyZXRrZXkxMjM0NQ=="
      message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"
      let actual = Signer -> Message -> Signature
Signer.sign Signer
signer Message
message
      expected <- Either.throw =<< Either.throw (Signature.parse $ Ascii.pack "v1,IywpE5NXy+JdAScgR7j5Pt59GjmazD7iJuVsQoRZFyw=")
      Test.assertEq test actual expected

  Test io tree -> String -> tree () -> tree ()
forall (m :: * -> *) (n :: * -> *).
Test m n -> String -> n () -> n ()
Test.describe Test io tree
test String
"asymmetric" (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
"creates correct asymmetric signature" (io () -> tree ()) -> io () -> tree ()
forall a b. (a -> b) -> a -> b
$ do
      secretKey <- Either InvalidSecretKey SecretKey -> io SecretKey
forall e (m :: * -> *) a.
(Exception e, MonadThrow m) =>
Either e a -> m a
Either.throw (Either InvalidSecretKey SecretKey -> io SecretKey)
-> (ByteString -> Either InvalidSecretKey SecretKey)
-> ByteString
-> io SecretKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Either InvalidSecretKey SecretKey
SecretKey.parse (ByteString -> io SecretKey) -> ByteString -> io SecretKey
forall a b. (a -> b) -> a -> b
$ String -> ByteString
Ascii.pack String
"whsk_QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU="
      message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"
      let actual = SecretKey -> Message -> AsymmetricSignature
Signer.asymmetric SecretKey
secretKey Message
message
      expected <- Either.throw . AsymmetricSignature.parse $ Ascii.pack "CV1O+PvrwXM42OMUX+tmm6bA3cS0tgLp0qo3YKuu0MGmBrsUhA0MHXF11HsEUJtPfTKs80WE7WUKVt9TueLDCQ=="
      Test.assertEq test actual expected

  Test io tree -> String -> tree () -> tree ()
forall (m :: * -> *) (n :: * -> *).
Test m n -> String -> n () -> n ()
Test.describe Test io tree
test String
"symmetric" (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
"creates correct symmetric signature" (io () -> tree ()) -> io () -> tree ()
forall a b. (a -> b) -> a -> b
$ do
      secret <- Either InvalidSecret Secret -> io Secret
forall e (m :: * -> *) a.
(Exception e, MonadThrow m) =>
Either e a -> m a
Either.throw (Either InvalidSecret Secret -> io Secret)
-> (ByteString -> Either InvalidSecret Secret)
-> ByteString
-> io Secret
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Either InvalidSecret Secret
Secret.parse (ByteString -> io Secret) -> ByteString -> io Secret
forall a b. (a -> b) -> a -> b
$ String -> ByteString
Ascii.pack String
"whsec_bXlzZWNyZXRrZXkxMjM0NQ=="
      message <- Either.throw . Message.parse $ Ascii.pack "i.0.Hello, world!"
      let actual = Secret -> Message -> SymmetricSignature
Signer.symmetric Secret
secret Message
message
      expected <- Either.throw . SymmetricSignature.parse $ Ascii.pack "IywpE5NXy+JdAScgR7j5Pt59GjmazD7iJuVsQoRZFyw="
      Test.assertEq test actual expected