module Signet.Unstable.Type.SignerTest where

import qualified Data.ByteString.Char8 as Ascii
import qualified Signet.Unstable.Exception.InvalidSigner as InvalidSigner
import qualified Signet.Unstable.Extra.Either as Either
import qualified Signet.Unstable.Extra.Tasty as Tasty
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
import Test.Tasty.HUnit ((@?=))

spec :: Tasty.Spec
spec :: Spec
spec = TestName -> Spec -> Spec
Tasty.describe TestName
"Signet.Unstable.Type.Signer" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
  TestName -> Spec -> Spec
Tasty.describe TestName
"parse" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
    TestName -> Assertion -> Spec
Tasty.it TestName
"succeeds with a valid secret key" (Assertion -> Spec) -> Assertion -> Spec
forall a b. (a -> b) -> a -> b
$ do
      let byteString :: ByteString
byteString = TestName -> ByteString
Ascii.pack TestName
"whsk_QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU="
      let actual :: Either InvalidSigner Signer
actual = ByteString -> Either InvalidSigner Signer
Signer.parse ByteString
byteString
      SecretKey
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
      Either InvalidSigner Signer
actual Either InvalidSigner Signer
-> Either InvalidSigner Signer -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= Signer -> Either InvalidSigner Signer
forall a b. b -> Either a b
Right (SecretKey -> Signer
Signer.Asymmetric SecretKey
secretKey)

    TestName -> Assertion -> Spec
Tasty.it TestName
"succeeds with a valid secret" (Assertion -> Spec) -> Assertion -> Spec
forall a b. (a -> b) -> a -> b
$ do
      let byteString :: ByteString
byteString = TestName -> ByteString
Ascii.pack TestName
"whsec_bXlzZWNyZXRrZXkxMjM0NQ=="
      let actual :: Either InvalidSigner Signer
actual = ByteString -> Either InvalidSigner Signer
Signer.parse ByteString
byteString
      Secret
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
      Either InvalidSigner Signer
actual Either InvalidSigner Signer
-> Either InvalidSigner Signer -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= Signer -> Either InvalidSigner Signer
forall a b. b -> Either a b
Right (Secret -> Signer
Signer.Symmetric Secret
secret)

    TestName -> Assertion -> Spec
Tasty.it TestName
"fails with invalid input" (Assertion -> Spec) -> Assertion -> Spec
forall a b. (a -> b) -> a -> b
$ do
      let byteString :: ByteString
byteString = TestName -> ByteString
Ascii.pack TestName
"invalid"
      let actual :: Either InvalidSigner Signer
actual = ByteString -> Either InvalidSigner Signer
Signer.parse ByteString
byteString
      Either InvalidSigner Signer
actual Either InvalidSigner Signer
-> Either InvalidSigner Signer -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= InvalidSigner -> Either InvalidSigner Signer
forall a b. a -> Either a b
Left (ByteString -> InvalidSigner
InvalidSigner.MkInvalidSigner ByteString
byteString)

  TestName -> Spec -> Spec
Tasty.describe TestName
"render" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
    TestName -> Assertion -> Spec
Tasty.it TestName
"works with a secret key" (Assertion -> Spec) -> Assertion -> Spec
forall a b. (a -> b) -> a -> b
$ do
      let byteString :: ByteString
byteString = TestName -> ByteString
Ascii.pack TestName
"whsk_QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU="
      SecretKey
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
      Signer -> ByteString
Signer.render (SecretKey -> Signer
Signer.Asymmetric SecretKey
secretKey) ByteString -> ByteString -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= ByteString
byteString

    TestName -> Assertion -> Spec
Tasty.it TestName
"works with a secret" (Assertion -> Spec) -> Assertion -> Spec
forall a b. (a -> b) -> a -> b
$ do
      let byteString :: ByteString
byteString = TestName -> ByteString
Ascii.pack TestName
"whsec_bXlzZWNyZXRrZXkxMjM0NQ=="
      Secret
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
      Signer -> ByteString
Signer.render (Secret -> Signer
Signer.Symmetric Secret
secret) ByteString -> ByteString -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= ByteString
byteString

  TestName -> Spec -> Spec
Tasty.describe TestName
"sign" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
    TestName -> Assertion -> Spec
Tasty.it TestName
"works with asymmetric" (Assertion -> Spec) -> Assertion -> Spec
forall a b. (a -> b) -> a -> b
$ do
      Signer
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
$ TestName -> ByteString
Ascii.pack TestName
"whsk_QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU="
      Message
message <- Either InvalidMessage Message -> IO Message
forall e (m :: * -> *) a.
(Exception e, MonadThrow m) =>
Either e a -> m a
Either.throw (Either InvalidMessage Message -> IO Message)
-> (ByteString -> Either InvalidMessage Message)
-> ByteString
-> IO Message
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Either InvalidMessage Message
Message.parse (ByteString -> IO Message) -> ByteString -> IO Message
forall a b. (a -> b) -> a -> b
$ TestName -> ByteString
Ascii.pack TestName
"i.0.Hello, world!"
      let actual :: Signature
actual = Signer -> Message -> Signature
Signer.sign Signer
signer Message
message
      Right Signature
expected <- Either InvalidSignature (Either UnknownSignature Signature)
-> IO (Either UnknownSignature Signature)
forall e (m :: * -> *) a.
(Exception e, MonadThrow m) =>
Either e a -> m a
Either.throw (Either InvalidSignature (Either UnknownSignature Signature)
 -> IO (Either UnknownSignature Signature))
-> (ByteString
    -> Either InvalidSignature (Either UnknownSignature Signature))
-> ByteString
-> IO (Either UnknownSignature Signature)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString
-> Either InvalidSignature (Either UnknownSignature Signature)
Signature.parse (ByteString -> IO (Either UnknownSignature Signature))
-> ByteString -> IO (Either UnknownSignature Signature)
forall a b. (a -> b) -> a -> b
$ TestName -> ByteString
Ascii.pack TestName
"v1a,CV1O+PvrwXM42OMUX+tmm6bA3cS0tgLp0qo3YKuu0MGmBrsUhA0MHXF11HsEUJtPfTKs80WE7WUKVt9TueLDCQ=="
      Signature
actual Signature -> Signature -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= Signature
expected

    TestName -> Assertion -> Spec
Tasty.it TestName
"works with symmetric" (Assertion -> Spec) -> Assertion -> Spec
forall a b. (a -> b) -> a -> b
$ do
      Signer
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
$ TestName -> ByteString
Ascii.pack TestName
"whsec_bXlzZWNyZXRrZXkxMjM0NQ=="
      Message
message <- Either InvalidMessage Message -> IO Message
forall e (m :: * -> *) a.
(Exception e, MonadThrow m) =>
Either e a -> m a
Either.throw (Either InvalidMessage Message -> IO Message)
-> (ByteString -> Either InvalidMessage Message)
-> ByteString
-> IO Message
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Either InvalidMessage Message
Message.parse (ByteString -> IO Message) -> ByteString -> IO Message
forall a b. (a -> b) -> a -> b
$ TestName -> ByteString
Ascii.pack TestName
"i.0.Hello, world!"
      let actual :: Signature
actual = Signer -> Message -> Signature
Signer.sign Signer
signer Message
message
      Right Signature
expected <- Either InvalidSignature (Either UnknownSignature Signature)
-> IO (Either UnknownSignature Signature)
forall e (m :: * -> *) a.
(Exception e, MonadThrow m) =>
Either e a -> m a
Either.throw (Either InvalidSignature (Either UnknownSignature Signature)
 -> IO (Either UnknownSignature Signature))
-> (ByteString
    -> Either InvalidSignature (Either UnknownSignature Signature))
-> ByteString
-> IO (Either UnknownSignature Signature)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString
-> Either InvalidSignature (Either UnknownSignature Signature)
Signature.parse (ByteString -> IO (Either UnknownSignature Signature))
-> ByteString -> IO (Either UnknownSignature Signature)
forall a b. (a -> b) -> a -> b
$ TestName -> ByteString
Ascii.pack TestName
"v1,IywpE5NXy+JdAScgR7j5Pt59GjmazD7iJuVsQoRZFyw="
      Signature
actual Signature -> Signature -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= Signature
expected

  TestName -> Spec -> Spec
Tasty.describe TestName
"asymmetric" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
    TestName -> Assertion -> Spec
Tasty.it TestName
"creates correct asymmetric signature" (Assertion -> Spec) -> Assertion -> Spec
forall a b. (a -> b) -> a -> b
$ do
      SecretKey
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
$ TestName -> ByteString
Ascii.pack TestName
"whsk_QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU="
      Message
message <- Either InvalidMessage Message -> IO Message
forall e (m :: * -> *) a.
(Exception e, MonadThrow m) =>
Either e a -> m a
Either.throw (Either InvalidMessage Message -> IO Message)
-> (ByteString -> Either InvalidMessage Message)
-> ByteString
-> IO Message
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Either InvalidMessage Message
Message.parse (ByteString -> IO Message) -> ByteString -> IO Message
forall a b. (a -> b) -> a -> b
$ TestName -> ByteString
Ascii.pack TestName
"i.0.Hello, world!"
      let actual :: AsymmetricSignature
actual = SecretKey -> Message -> AsymmetricSignature
Signer.asymmetric SecretKey
secretKey Message
message
      AsymmetricSignature
expected <- Either InvalidAsymmetricSignature AsymmetricSignature
-> IO AsymmetricSignature
forall e (m :: * -> *) a.
(Exception e, MonadThrow m) =>
Either e a -> m a
Either.throw (Either InvalidAsymmetricSignature AsymmetricSignature
 -> IO AsymmetricSignature)
-> (ByteString
    -> Either InvalidAsymmetricSignature AsymmetricSignature)
-> ByteString
-> IO AsymmetricSignature
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Either InvalidAsymmetricSignature AsymmetricSignature
AsymmetricSignature.parse (ByteString -> IO AsymmetricSignature)
-> ByteString -> IO AsymmetricSignature
forall a b. (a -> b) -> a -> b
$ TestName -> ByteString
Ascii.pack TestName
"CV1O+PvrwXM42OMUX+tmm6bA3cS0tgLp0qo3YKuu0MGmBrsUhA0MHXF11HsEUJtPfTKs80WE7WUKVt9TueLDCQ=="
      AsymmetricSignature
actual AsymmetricSignature -> AsymmetricSignature -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= AsymmetricSignature
expected

  TestName -> Spec -> Spec
Tasty.describe TestName
"symmetric" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
    TestName -> Assertion -> Spec
Tasty.it TestName
"creates correct symmetric signature" (Assertion -> Spec) -> Assertion -> Spec
forall a b. (a -> b) -> a -> b
$ do
      Secret
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
$ TestName -> ByteString
Ascii.pack TestName
"whsec_bXlzZWNyZXRrZXkxMjM0NQ=="
      Message
message <- Either InvalidMessage Message -> IO Message
forall e (m :: * -> *) a.
(Exception e, MonadThrow m) =>
Either e a -> m a
Either.throw (Either InvalidMessage Message -> IO Message)
-> (ByteString -> Either InvalidMessage Message)
-> ByteString
-> IO Message
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Either InvalidMessage Message
Message.parse (ByteString -> IO Message) -> ByteString -> IO Message
forall a b. (a -> b) -> a -> b
$ TestName -> ByteString
Ascii.pack TestName
"i.0.Hello, world!"
      let actual :: SymmetricSignature
actual = Secret -> Message -> SymmetricSignature
Signer.symmetric Secret
secret Message
message
      SymmetricSignature
expected <- Either InvalidSymmetricSignature SymmetricSignature
-> IO SymmetricSignature
forall e (m :: * -> *) a.
(Exception e, MonadThrow m) =>
Either e a -> m a
Either.throw (Either InvalidSymmetricSignature SymmetricSignature
 -> IO SymmetricSignature)
-> (ByteString
    -> Either InvalidSymmetricSignature SymmetricSignature)
-> ByteString
-> IO SymmetricSignature
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Either InvalidSymmetricSignature SymmetricSignature
SymmetricSignature.parse (ByteString -> IO SymmetricSignature)
-> ByteString -> IO SymmetricSignature
forall a b. (a -> b) -> a -> b
$ TestName -> ByteString
Ascii.pack TestName
"IywpE5NXy+JdAScgR7j5Pt59GjmazD7iJuVsQoRZFyw="
      SymmetricSignature
actual SymmetricSignature -> SymmetricSignature -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= SymmetricSignature
expected