amazonka-core-1.6.0: test/Test/AWS/Sign/V4/Chunked.hs
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TypeFamilies #-}
-- |
-- Module : Test.AWS.Sign.V$
-- Copyright : (c) 2013-2018 Brendan Hay
-- License : Mozilla Public License, v. 2.0.
-- Maintainer : Brendan Hay <brendan.g.hay+amazonka@gmail.com>
-- Stability : experimental
-- Portability : non-portable (GHC extensions)
--
module Test.AWS.Sign.V4.Chunked (tests) where
import Prelude hiding (elem)
import Data.List (sort)
import Data.Monoid
import Data.String
import Network.AWS.Lens ((%~), (&), (.~))
import Network.AWS.Prelude
import Network.AWS.Sign.V4
import Numeric (showHex)
import Test.AWS.Arbitrary ()
import Test.QuickCheck.Property ()
import Test.Tasty
import Test.Tasty.QuickCheck
import qualified Data.ByteString.Char8 as BS8
import qualified Data.Conduit.List as Conduit
import qualified Data.Foldable as Fold
import qualified Data.Text as Text
import qualified Data.Text.Encoding as Text
import qualified Network.HTTP.Conduit as Client
import qualified Test.QuickCheck as QC
tests :: TestTree
tests = testGroup "headers"
[ testProperty "empty body" testEmptyBody
, testProperty "1 chunk body" testOneChunkBody
, testProperty "2 chunks body" testTwoChunksBody
]
testEmptyBody :: Property
testEmptyBody =
QC.forAll (mkSigned []) $ \Signed{..} ->
let elem = (`Fold.elem` Client.requestHeaders sgRequest)
in elem ("Content-Encoding", "aws-chunked")
&& elem ("X-Amz-Decoded-Content-Length", "0")
&& elem ("Content-Length", "86")
testOneChunkBody :: Property
testOneChunkBody =
let n = 123
str = BS8.pack . show
inp = BS8.replicate n 'a'
in QC.forAll (mkSigned [inp]) $ \Signed{..} ->
let elem = (`Fold.elem` Client.requestHeaders sgRequest)
in elem ("Content-Encoding", "aws-chunked")
&& elem ("X-Amz-Decoded-Content-Length", str n)
&& elem ("Content-Length", str (87 + n + 86))
testTwoChunksBody :: Property
testTwoChunksBody =
let size = fromIntegral defaultChunkSize
sizeLen = length (showHex size "")
n = 123
str = BS8.pack . show
full = BS8.replicate size 'a' -- full-sized chunk
final = BS8.replicate n 'b' -- final non-empty chunk
in QC.forAll (mkSigned [full, final]) $ \Signed{..} ->
let elem = (`Fold.elem` Client.requestHeaders sgRequest)
in elem ("Content-Encoding", "aws-chunked")
&& elem ("X-Amz-Decoded-Content-Length", str (size + n))
&& elem ("Content-Length", str (sizeLen + 85 + size + 87 + n + 86))
mkSigned :: [BS8.ByteString] -> Gen (Signed ())
mkSigned bs = do
aReq <- arbitrary
aService <- arbitrary
let svc = aService
& serviceSigner .~ v4
req = aReq
& rqBody .~ Chunked (mkBody bs)
& rqService .~ svc
rqSign req <$> arbitrary <*> arbitrary <*> arbitrary
mkBody :: [BS8.ByteString] -> ChunkedBody
mkBody bs =
ChunkedBody defaultChunkSize
(fromIntegral . sum $ fmap BS8.length bs)
(Conduit.sourceList bs)