{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE EmptyDataDecls #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TypeFamilies #-} module UserSpec ( spec, -- just supressing warning UserStorageId, ) where import Data.Coerce (coerce) import Data.Encryptable import Database.Persist.TH import Test.Hspec import Test.QuickCheck import Test.QuickCheck.Arbitrary.Generic import Test.QuickCheck.Instances () import TestEnv import Universum data User = User {login :: Login, address :: Address} deriving (Eq, Generic, Show) instance Arbitrary User where arbitrary = genericArbitrary shrink = genericShrink share [mkPersist sqlSettings] [persistLowerCase| UserStorage login Login address (Encrypted ByteString UnicodeException Address) UniqueUserStorage login |] instance Encryptable UserStorage UnicodeException User where encrypt c i x = Encrypted $ UserStorage (login x) $ encrypt c i (address x) decrypt c i x0 = do let x = coerce x0 a <- decrypt c i $ userStorageAddress x return $ User (userStorageLogin x) a spec :: Spec spec = before newEnv $ it "UserStorage/User" $ \env -> property $ \x -> do let c = cipher env let i = iv env decrypt c i (encrypt c i x :: Encrypted UserStorage UnicodeException User) `shouldBe` Right x