module TestRawRequest where import Data.ByteString import Data.CaseInsensitive (mk) import Network.HTTP.Client (method) import Network.Wai (Request (..)) import Servant import Servant.API.RawRequest import Test.QuickCheck.Monadic (PropertyM (..), assert, monadicIO) import Test.Tasty import TestLib (returns400, success) import qualified Network.HTTP.Simple as S import qualified Network.HTTP.Types.Header as NTH import qualified Test.Tasty.QuickCheck as QC type RawRequestAPI = "check-raw-request" :> RawRequest :> Get '[JSON] NoContent rawRequestServer :: Server RawRequestAPI rawRequestServer = rawRequest where rawRequest :: Request -> Handler NoContent rawRequest req = do let reqHeaders = requestHeaders req reqQS = queryString req case (lookup "testHeader" reqHeaders, reqQS == [("test_query", Just "val")]) of (Just "foo", True) -> pure NoContent (_, _) -> throwError err400 {errBody = "Missing value"} headerList :: [NTH.Header] headerList = [(mk "testHeader", "foo")] rawRequestProps :: Int -> TestTree rawRequestProps port = testGroup "RawRequest" [ QC.testProperty "Raw Request holds the headers, query string of the original request." $ monadicIO $ do result <- (fetchEndpoint port "?test_query=val" headerList) >>= success assert $ result == True , QC.testProperty "Raw Reuest rejects a request with missing headers" $ monadicIO $ do result <- (fetchEndpoint port "?test_query=val" []) >>= returns400 assert $ result == True , QC.testProperty "Raw Reuest rejects a request with missing query string" $ monadicIO $ do result <- (fetchEndpoint port "?invalid" headerList) >>= returns400 assert $ result == True ] where fetchEndpoint :: Int -> String -> [NTH.Header] -> PropertyM IO (S.Response ByteString) fetchEndpoint port' queryVal hList = do let initReq = S.parseRequest_ $ "http://localhost:" <> (show port') <> "/check-raw-request" <> queryVal reqHeader = S.setRequestHeaders hList initReq req = reqHeader {method = "GET"} in do resp <- S.httpBS req pure resp