module Hydra.NetworkVersionsSpec where

import Hydra.Prelude
import Test.Hydra.Prelude

import Data.Version (Version, makeVersion)
import Hydra.NetworkVersions (hydraNodeVersion, parseNetworkTxIds)
import Test.QuickCheck (Property, counterexample, forAll, property)

spec :: Spec
spec :: Spec
spec =
  String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"NetworkVersions" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
    String -> IO () -> SpecWith (Arg (IO ()))
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"parseNetworkTxIds produces list TxId" (IO () -> SpecWith (Arg (IO ())))
-> IO () -> SpecWith (Arg (IO ()))
forall a b. (a -> b) -> a -> b
$ do
      let networks :: [String]
networks = [String
"mainnet", String
"preview", String
"preprod"]
      let versions :: [Version]
versions = [Int] -> Version
makeVersion ([Int] -> Version) -> (Int -> [Int]) -> Int -> Version
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (\Int
v -> [Int
0, Int
v, Int
0]) (Int -> Version) -> [Int] -> [Version]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Int
13 .. Int
21]
      [String] -> (String -> IO ()) -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [String]
networks ((String -> IO ()) -> IO ()) -> (String -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \String
network ->
        [Version] -> (Version -> IO ()) -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [Version]
versions ((Version -> IO ()) -> IO ()) -> (Version -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Version
version -> do
          case Version -> String -> Either String [TxId]
forall (m :: * -> *). MonadFail m => Version -> String -> m [TxId]
parseNetworkTxIds Version
version String
network of
            Left String
err -> String -> IO ()
forall (m :: * -> *) a.
(HasCallStack, MonadThrow m) =>
String -> m a
failure (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"Failed to parse network tx ids: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
err
            Right [TxId]
txIds -> [TxId]
txIds [TxId] -> ([TxId] -> Bool) -> IO ()
forall a. (HasCallStack, Show a) => a -> (a -> Bool) -> IO ()
`shouldSatisfy` Bool -> Bool
not (Bool -> Bool) -> ([TxId] -> Bool) -> [TxId] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [TxId] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null

    String -> Property -> Spec
forall prop.
(HasCallStack, Testable prop) =>
String -> prop -> Spec
prop String
"parseNetworkTxIds works with expected versions and networks" (Property -> Spec) -> Property -> Spec
forall a b. (a -> b) -> a -> b
$
      Gen Version -> (Version -> Property) -> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> prop) -> Property
forAll Gen Version
forall a. Arbitrary a => Gen a
arbitrary ((Version -> Property) -> Property)
-> (Version -> Property) -> Property
forall a b. (a -> b) -> a -> b
$ \Version
version ->
        Gen String -> (String -> Property) -> Property
forall a prop.
(Show a, Testable prop) =>
Gen a -> (a -> prop) -> Property
forAll Gen String
forall a. Arbitrary a => Gen a
arbitrary ((String -> Property) -> Property)
-> (String -> Property) -> Property
forall a b. (a -> b) -> a -> b
$ \String
network ->
          Version -> String -> Property
propParseNetworkTxIds Version
version String
network

propParseNetworkTxIds :: Version -> String -> Property
propParseNetworkTxIds :: Version -> String -> Property
propParseNetworkTxIds Version
version String
network = do
  let varlidNetworks :: [String]
varlidNetworks = [String
"mainnet", String
"preview", String
"preprod"]
  let validVersions :: [Version]
validVersions = ([Int] -> Version
makeVersion ([Int] -> Version) -> (Int -> [Int]) -> Int -> Version
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (\Int
v -> [Int
0, Int
v, Int
0]) (Int -> Version) -> [Int] -> [Version]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Int
13 .. Int
21]) [Version] -> [Version] -> [Version]
forall a. Semigroup a => a -> a -> a
<> [Version
hydraNodeVersion]
  case Version -> String -> Either String [TxId]
forall (m :: * -> *). MonadFail m => Version -> String -> m [TxId]
parseNetworkTxIds Version
version String
network of
    Left String
err ->
      if String
network String -> [String] -> Bool
forall (f :: * -> *) a.
(Foldable f, DisallowElem f, Eq a) =>
a -> f a -> Bool
`elem` [String]
varlidNetworks Bool -> Bool -> Bool
&& Version
version Version -> [Version] -> Bool
forall (f :: * -> *) a.
(Foldable f, DisallowElem f, Eq a) =>
a -> f a -> Bool
`elem` [Version]
validVersions
        then Bool -> Property
forall prop. Testable prop => prop -> Property
property Bool
False Property -> (Property -> Property) -> Property
forall a b. a -> (a -> b) -> b
& String -> Property -> Property
forall prop. Testable prop => String -> prop -> Property
counterexample (String
"error: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
err)
        else Bool -> Property
forall prop. Testable prop => prop -> Property
property Bool
True
    Right [TxId]
txIds -> Bool -> Property
forall prop. Testable prop => prop -> Property
property (Bool -> Property) -> Bool -> Property
forall a b. (a -> b) -> a -> b
$ Bool -> Bool
not ([TxId] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [TxId]
txIds)