toxcore-0.2.11: test/Network/Tox/Crypto/KeySpec.hs
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE Trustworthy #-}
module Network.Tox.Crypto.KeySpec where
import Test.Hspec
import Test.QuickCheck
import qualified Crypto.Saltine.Class as Sodium
import Data.Binary (Binary)
import Data.ByteString (ByteString)
import qualified Data.ByteString as ByteString
import Data.Proxy (Proxy (..))
import qualified Data.Result as R
import Data.Typeable (Typeable)
import qualified Network.Tox.Binary as Binary
import Network.Tox.Crypto.Key (Key (..))
import qualified Network.Tox.Crypto.Key as Key
import Network.Tox.EncodingSpec
import qualified Text.Read as Read
readMaybe :: String -> Maybe Key.PublicKey
readMaybe = Read.readMaybe
decodeM :: Monad m => ByteString -> m Key.PublicKey
decodeM = Key.decode
keyToInteger :: String -> Integer
keyToInteger string =
Key.keyToInteger (read string :: Key.PublicKey)
encodeDecodePublicKey :: Key.PublicKey -> Expectation
encodeDecodePublicKey key =
Sodium.decode (Sodium.encode key) `shouldBe` Just key
localEncodingSpec
:: (Typeable a, Read a, Show a, Binary a, Arbitrary a, Eq a)
=> Proxy a -> Spec
localEncodingSpec proxy =
describe (Binary.typeName proxy) $ do
binarySpec proxy
readShowSpec proxy
spec :: Spec
spec = do
-- PublicKey for RPC tests.
rpcSpec (Proxy :: Proxy Key.PublicKey)
-- All others only local tests.
localEncodingSpec (Proxy :: Proxy Key.CombinedKey)
localEncodingSpec (Proxy :: Proxy Key.Nonce)
localEncodingSpec (Proxy :: Proxy Key.PublicKey)
localEncodingSpec (Proxy :: Proxy Key.SecretKey)
describe "IsEncoding" $
it "decodes encoded public keys correctly" $
property encodeDecodePublicKey
describe "read" $ do
it "decodes valid hex string to PublicKey" $
let
actual = readMaybe "\"0100000000000000000000000000000000000000000000000000000000000010\""
Just expected = Sodium.decode $ ByteString.pack [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x10]
in
actual `shouldBe` Just (Key expected)
it "decodes empty string to Nothing" $ do
let actual = readMaybe ""
actual `shouldBe` Nothing
case decodeM ByteString.empty of
R.Failure msg -> msg `shouldStartWith` "unable to decode"
R.Success val -> expectationFailure $ "unexpected success: " ++ show val
it "decodes valid hex string of wrong length to Nothing" $
let actual = readMaybe "\"0110\"" in
actual `shouldBe` Nothing
describe "keyToInteger" $ do
it "converts keys to Integer in big endian" $ do
keyToInteger "\"fe00000000000000000000000000000000000000000000000000000000000000\""
`shouldBe` 0xfe00000000000000000000000000000000000000000000000000000000000000
keyToInteger "\"00000000000000000000000000000000000000000000000000000000000000fe\""
`shouldBe` 0x00000000000000000000000000000000000000000000000000000000000000fe
it "encodes all keys to positive Integers" $
property $ \key ->
Key.keyToInteger (key :: Key.PublicKey) `shouldSatisfy` (0 <=)