amazonka-core-1.0.0: test/Test/AWS/Sign/V4.hs
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeFamilies #-}
-- |
-- Module : Test.AWS.Sign.V$
-- Copyright : (c) 2013-2015 Brendan Hay
-- License : Mozilla Public License, v. 2.0.
-- Maintainer : Brendan Hay <brendan.g.hay@gmail.com>
-- Stability : experimental
-- Portability : non-portable (GHC extensions)
--
module Test.AWS.Sign.V4 (tests) where
import Control.Lens
import qualified Data.ByteString.Char8 as BS8
import qualified Data.Foldable as Fold
import Data.List (sort)
import Data.Monoid
import Data.String
import qualified Data.Text as Text
import qualified Data.Text.Encoding as Text
import Network.AWS.Prelude
import Network.AWS.Sign.V4
import Test.AWS.Arbitrary ()
import Test.QuickCheck.Property
import Test.Tasty
import Test.Tasty.QuickCheck
-- Write some V4 signing properties:
-- test canonical query
-- test query
-- test canonical headers
-- test signed headers
-- test time format
-- test host, x-amz-date, content-sha256 headers exist
-- test empty path
-- test empty query
tests :: TestTree
tests = testGroup "v4"
[ testGroup "canonical query"
[ testProperty "empty" $ queryEmpty
, testProperty "empty key values" $ queryEmptyKeyValues
]
]
queryEmpty :: Request () -> Signer -> Property
queryEmpty rq sg = property $
mempty == toBS (metaCanonicalQuery . sign sg $ rq & rqQuery .~ mempty)
queryEmptyKeyValues :: [NonEmptyList Char] -> Property
queryEmptyKeyValues xs = property $ do
rq <- arbitrary
sg <- arbitrary
let v4 = sign sg $ rq & rqQuery .~ Fold.foldMap (fromString . getNonEmpty) xs
e = sort $ map ((<> "=") . urlEncode True . BS8.pack . getNonEmpty) xs
a = BS8.split '&' . toBS $ metaCanonicalQuery v4
m = "Expected: " ++ show e ++ "\n" ++
"Actual: " ++ show a
return . counterexample m $ e == a
newtype Signer = Signer { sign :: Request () -> Meta V4 }
instance Show Signer where
show = const "V4"
instance Arbitrary Signer where
arbitrary = do
a <- arbitrary
reg <- arbitrary
ts <- arbitrary
return $ Signer (_sgMeta . signed auth reg ts (testV4 a))
auth :: AuthEnv
auth = AuthEnv "access-key" "super-secret-key" Nothing Nothing
data TestV4
instance AWSService TestV4 where
type Sg TestV4 = V4
service = error "service not defined for TestV4."
testV4 :: Abbrev -> Service TestV4
testV4 a = svc
where
svc = Service
{ _svcAbbrev = a
, _svcPrefix = Text.encodeUtf8 . Text.toLower $ toText a
, _svcVersion = "2012-01-01"
, _svcEndpoint = defaultEndpoint svc
, _svcTimeout = Nothing
, _svcStatus = const False
, _svcError = error "_svcError not defined."
, _svcRetry = error "_svcRetry not defined."
}