module Signet.Unstable.Type.PublicKeyTest where

import qualified Crypto.Error as Error
import qualified Crypto.PubKey.Ed25519 as Ed25519
import qualified Data.ByteString.Char8 as Ascii
import qualified Signet.Unstable.Exception.InvalidPublicKey as InvalidPublicKey
import qualified Signet.Unstable.Extra.Tasty as Tasty
import qualified Signet.Unstable.Type.PublicKey as PublicKey
import Test.Tasty.HUnit ((@?=))

spec :: Tasty.Spec
spec :: Spec
spec = TestName -> Spec -> Spec
Tasty.describe TestName
"Signet.Unstable.Type.PublicKey" (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
"fails with invalid prefix" (Assertion -> Spec) -> Assertion -> Spec
forall a b. (a -> b) -> a -> b
$ do
      let byteString :: ByteString
byteString = TestName -> ByteString
Ascii.pack TestName
"invalid"
      let result :: Either InvalidPublicKey PublicKey
result = ByteString -> Either InvalidPublicKey PublicKey
PublicKey.parse ByteString
byteString
      Either InvalidPublicKey PublicKey
result Either InvalidPublicKey PublicKey
-> Either InvalidPublicKey PublicKey -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= InvalidPublicKey -> Either InvalidPublicKey PublicKey
forall a b. a -> Either a b
Left (ByteString -> InvalidPublicKey
InvalidPublicKey.MkInvalidPublicKey ByteString
byteString)

    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
"whpk_invalid"
      let result :: Either InvalidPublicKey PublicKey
result = ByteString -> Either InvalidPublicKey PublicKey
PublicKey.parse ByteString
byteString
      Either InvalidPublicKey PublicKey
result Either InvalidPublicKey PublicKey
-> Either InvalidPublicKey PublicKey -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= InvalidPublicKey -> Either InvalidPublicKey PublicKey
forall a b. a -> Either a b
Left (ByteString -> InvalidPublicKey
InvalidPublicKey.MkInvalidPublicKey ByteString
byteString)

    TestName -> Assertion -> Spec
Tasty.it TestName
"succeeds with valid input" (Assertion -> Spec) -> Assertion -> Spec
forall a b. (a -> b) -> a -> b
$ do
      let result :: Either InvalidPublicKey PublicKey
result = ByteString -> Either InvalidPublicKey PublicKey
PublicKey.parse (ByteString -> Either InvalidPublicKey PublicKey)
-> ByteString -> Either InvalidPublicKey PublicKey
forall a b. (a -> b) -> a -> b
$ TestName -> ByteString
Ascii.pack TestName
"whpk_QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU="
      PublicKey
publicKey <- (PublicKey -> PublicKey) -> IO PublicKey -> IO PublicKey
forall a b. (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap PublicKey -> PublicKey
PublicKey.MkPublicKey (IO PublicKey -> IO PublicKey)
-> (ByteString -> IO PublicKey) -> ByteString -> IO PublicKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CryptoFailable PublicKey -> IO PublicKey
forall a. CryptoFailable a -> IO a
Error.throwCryptoErrorIO (CryptoFailable PublicKey -> IO PublicKey)
-> (ByteString -> CryptoFailable PublicKey)
-> ByteString
-> IO PublicKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> CryptoFailable PublicKey
forall ba. ByteArrayAccess ba => ba -> CryptoFailable PublicKey
Ed25519.publicKey (ByteString -> IO PublicKey) -> ByteString -> IO PublicKey
forall a b. (a -> b) -> a -> b
$ TestName -> ByteString
Ascii.pack TestName
"ABCDEFGHIJKLMNOPQRSTUVWXYZ012345"
      Either InvalidPublicKey PublicKey
result Either InvalidPublicKey PublicKey
-> Either InvalidPublicKey PublicKey -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= PublicKey -> Either InvalidPublicKey PublicKey
forall a b. b -> Either a b
Right PublicKey
publicKey

  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" (Assertion -> Spec) -> Assertion -> Spec
forall a b. (a -> b) -> a -> b
$ do
      PublicKey
publicKey <- (PublicKey -> PublicKey) -> IO PublicKey -> IO PublicKey
forall a b. (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap PublicKey -> PublicKey
PublicKey.MkPublicKey (IO PublicKey -> IO PublicKey)
-> (ByteString -> IO PublicKey) -> ByteString -> IO PublicKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CryptoFailable PublicKey -> IO PublicKey
forall a. CryptoFailable a -> IO a
Error.throwCryptoErrorIO (CryptoFailable PublicKey -> IO PublicKey)
-> (ByteString -> CryptoFailable PublicKey)
-> ByteString
-> IO PublicKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> CryptoFailable PublicKey
forall ba. ByteArrayAccess ba => ba -> CryptoFailable PublicKey
Ed25519.publicKey (ByteString -> IO PublicKey) -> ByteString -> IO PublicKey
forall a b. (a -> b) -> a -> b
$ TestName -> ByteString
Ascii.pack TestName
"ABCDEFGHIJKLMNOPQRSTUVWXYZ012345"
      PublicKey -> ByteString
PublicKey.render PublicKey
publicKey ByteString -> ByteString -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= TestName -> ByteString
Ascii.pack TestName
"whpk_QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVowMTIzNDU="