Document much of yesod-test, especially the "Making Requests" section
This commit is contained in:
parent
3f20c759dc
commit
cb4785cf28
@ -10,7 +10,7 @@ using css selectors.
|
|||||||
|
|
||||||
You can also easily build requests using forms present in the current page.
|
You can also easily build requests using forms present in the current page.
|
||||||
This is very useful for testing web applications built in yesod for example,
|
This is very useful for testing web applications built in yesod for example,
|
||||||
were your forms may have field names generated by the framework or a randomly
|
where your forms may have field names generated by the framework or a randomly
|
||||||
generated "\_token" field.
|
generated "\_token" field.
|
||||||
|
|
||||||
Your database is also directly available so you can use runDB to set up
|
Your database is also directly available so you can use runDB to set up
|
||||||
|
|||||||
@ -8,19 +8,19 @@
|
|||||||
Yesod.Test is a pragmatic framework for testing web applications built
|
Yesod.Test is a pragmatic framework for testing web applications built
|
||||||
using wai and persistent.
|
using wai and persistent.
|
||||||
|
|
||||||
By pragmatic I may also mean 'dirty'. It's main goal is to encourage integration
|
By pragmatic I may also mean 'dirty'. Its main goal is to encourage integration
|
||||||
and system testing of web applications by making everything /easy to test/.
|
and system testing of web applications by making everything /easy to test/.
|
||||||
|
|
||||||
Your tests are like browser sessions that keep track of cookies and the last
|
Your tests are like browser sessions that keep track of cookies and the last
|
||||||
visited page. You can perform assertions on the content of HTML responses,
|
visited page. You can perform assertions on the content of HTML responses,
|
||||||
using css selectors to explore the document more easily.
|
using CSS selectors to explore the document more easily.
|
||||||
|
|
||||||
You can also easily build requests using forms present in the current page.
|
You can also easily build requests using forms present in the current page.
|
||||||
This is very useful for testing web applications built in yesod for example,
|
This is very useful for testing web applications built in yesod, for example,
|
||||||
were your forms may have field names generated by the framework or a randomly
|
where your forms may have field names generated by the framework or a randomly
|
||||||
generated '_nonce' field.
|
generated nonce value.
|
||||||
|
|
||||||
Your database is also directly available so you can use runDBRunner to set up
|
Your database is also directly available so you can use 'runDB' to set up
|
||||||
backend pre-conditions, or to assert that your session is having the desired effect.
|
backend pre-conditions, or to assert that your session is having the desired effect.
|
||||||
|
|
||||||
-}
|
-}
|
||||||
@ -38,12 +38,12 @@ module Yesod.Test
|
|||||||
, yit
|
, yit
|
||||||
|
|
||||||
-- * Making requests
|
-- * Making requests
|
||||||
-- | To make a request you need to point to an url and pass in some parameters.
|
-- | You can construct requests with the 'RequestBuilder' monad, which lets you
|
||||||
--
|
-- set the URL and add parameters, headers, and files. Helper functions are provided to
|
||||||
-- To build your parameters you will use the RequestBuilder monad that lets you
|
-- lookup fields by label and to add the current nonce value from your forms.
|
||||||
-- add values, add files, lookup fields by label and find the current
|
-- Once built, the request can be executed with the 'request' method.
|
||||||
-- nonce value and add it to your request too.
|
|
||||||
--
|
--
|
||||||
|
-- Convenience functions like 'get' and 'post' build and execute common requests.
|
||||||
, get
|
, get
|
||||||
, post
|
, post
|
||||||
, postBody
|
, postBody
|
||||||
@ -57,16 +57,22 @@ module Yesod.Test
|
|||||||
, RequestBuilder
|
, RequestBuilder
|
||||||
, setUrl
|
, setUrl
|
||||||
|
|
||||||
-- | Yesod can auto generate field ids, so you are never sure what
|
-- *** Adding fields by label
|
||||||
-- the argument name should be for each one of your args when constructing
|
-- | Yesod can auto generate field names, so you are never sure what
|
||||||
|
-- the argument name should be for each one of your inputs when constructing
|
||||||
-- your requests. What you do know is the /label/ of the field.
|
-- your requests. What you do know is the /label/ of the field.
|
||||||
-- These functions let you add parameters to your request based
|
-- These functions let you add parameters to your request based
|
||||||
-- on currently displayed label names.
|
-- on currently displayed label names.
|
||||||
, byLabel
|
, byLabel
|
||||||
, fileByLabel
|
, fileByLabel
|
||||||
|
|
||||||
-- | Does the current form have a _nonce? Use any of these to add it to your
|
-- *** Nonces
|
||||||
-- request parameters.
|
-- | In order to prevent CSRF exploits, yesod-form adds a hidden input
|
||||||
|
-- to your forms with the name "_token". This token is a randomly generated,
|
||||||
|
-- per-session value called a /nonce/.
|
||||||
|
--
|
||||||
|
-- In order to prevent your forms from being rejected in tests, use one of
|
||||||
|
-- these functions to add the nonce to your request.
|
||||||
, addNonce
|
, addNonce
|
||||||
, addNonce_
|
, addNonce_
|
||||||
|
|
||||||
@ -188,7 +194,7 @@ data RequestPart
|
|||||||
= ReqKvPart T.Text T.Text
|
= ReqKvPart T.Text T.Text
|
||||||
| ReqFilePart T.Text FilePath BSL8.ByteString T.Text
|
| ReqFilePart T.Text FilePath BSL8.ByteString T.Text
|
||||||
|
|
||||||
-- | The RequestBuilder state monad constructs an url encoded string of arguments
|
-- | The 'RequestBuilder' state monad constructs a URL encoded string of arguments
|
||||||
-- to send with your requests. Some of the functions that run on it use the current
|
-- to send with your requests. Some of the functions that run on it use the current
|
||||||
-- response to analyze the forms that the server is expecting to receive.
|
-- response to analyze the forms that the server is expecting to receive.
|
||||||
type RequestBuilder site = ST.StateT (RequestBuilderData site) IO
|
type RequestBuilder site = ST.StateT (RequestBuilderData site) IO
|
||||||
@ -274,12 +280,12 @@ withResponse' getter f = maybe err f . getter =<< ST.get
|
|||||||
withResponse :: (SResponse -> YesodExample site a) -> YesodExample site a
|
withResponse :: (SResponse -> YesodExample site a) -> YesodExample site a
|
||||||
withResponse = withResponse' yedResponse
|
withResponse = withResponse' yedResponse
|
||||||
|
|
||||||
-- | Use HXT to parse a value from an html tag.
|
-- | Use HXT to parse a value from an HTML tag.
|
||||||
-- Check for usage examples in this module's source.
|
-- Check for usage examples in this module's source.
|
||||||
parseHTML :: HtmlLBS -> Cursor
|
parseHTML :: HtmlLBS -> Cursor
|
||||||
parseHTML html = fromDocument $ HD.parseLBS html
|
parseHTML html = fromDocument $ HD.parseLBS html
|
||||||
|
|
||||||
-- | Query the last response using css selectors, returns a list of matched fragments
|
-- | Query the last response using CSS selectors, returns a list of matched fragments
|
||||||
htmlQuery' :: MonadIO m
|
htmlQuery' :: MonadIO m
|
||||||
=> (state -> Maybe SResponse)
|
=> (state -> Maybe SResponse)
|
||||||
-> Query
|
-> Query
|
||||||
@ -289,7 +295,7 @@ htmlQuery' getter query = withResponse' getter $ \ res ->
|
|||||||
Left err -> failure $ query <> " did not parse: " <> T.pack (show err)
|
Left err -> failure $ query <> " did not parse: " <> T.pack (show err)
|
||||||
Right matches -> return $ map (encodeUtf8 . TL.pack) matches
|
Right matches -> return $ map (encodeUtf8 . TL.pack) matches
|
||||||
|
|
||||||
-- | Query the last response using css selectors, returns a list of matched fragments
|
-- | Query the last response using CSS selectors, returns a list of matched fragments
|
||||||
htmlQuery :: Query -> YesodExample site [HtmlLBS]
|
htmlQuery :: Query -> YesodExample site [HtmlLBS]
|
||||||
htmlQuery = htmlQuery' yedResponse
|
htmlQuery = htmlQuery' yedResponse
|
||||||
|
|
||||||
@ -354,7 +360,7 @@ bodyContains text = withResponse $ \ res ->
|
|||||||
contains :: BSL8.ByteString -> String -> Bool
|
contains :: BSL8.ByteString -> String -> Bool
|
||||||
contains a b = DL.isInfixOf b (TL.unpack $ decodeUtf8 a)
|
contains a b = DL.isInfixOf b (TL.unpack $ decodeUtf8 a)
|
||||||
|
|
||||||
-- | Queries the html using a css selector, and all matched elements must contain
|
-- | Queries the HTML using a CSS selector, and all matched elements must contain
|
||||||
-- the given string.
|
-- the given string.
|
||||||
htmlAllContain :: Query -> String -> YesodExample site ()
|
htmlAllContain :: Query -> String -> YesodExample site ()
|
||||||
htmlAllContain query search = do
|
htmlAllContain query search = do
|
||||||
@ -364,7 +370,7 @@ htmlAllContain query search = do
|
|||||||
_ -> liftIO $ HUnit.assertBool ("Not all "++T.unpack query++" contain "++search) $
|
_ -> liftIO $ HUnit.assertBool ("Not all "++T.unpack query++" contain "++search) $
|
||||||
DL.all (DL.isInfixOf search) (map (TL.unpack . decodeUtf8) matches)
|
DL.all (DL.isInfixOf search) (map (TL.unpack . decodeUtf8) matches)
|
||||||
|
|
||||||
-- | Queries the html using a css selector, and passes if any matched
|
-- | Queries the HTML using a CSS selector, and passes if any matched
|
||||||
-- element contains the given string.
|
-- element contains the given string.
|
||||||
--
|
--
|
||||||
-- Since 0.3.5
|
-- Since 0.3.5
|
||||||
@ -376,7 +382,7 @@ htmlAnyContain query search = do
|
|||||||
_ -> liftIO $ HUnit.assertBool ("None of "++T.unpack query++" contain "++search) $
|
_ -> liftIO $ HUnit.assertBool ("None of "++T.unpack query++" contain "++search) $
|
||||||
DL.any (DL.isInfixOf search) (map (TL.unpack . decodeUtf8) matches)
|
DL.any (DL.isInfixOf search) (map (TL.unpack . decodeUtf8) matches)
|
||||||
|
|
||||||
-- | Queries the html using a css selector, and fails if any matched
|
-- | Queries the HTML using a CSS selector, and fails if any matched
|
||||||
-- element contains the given string (in other words, it is the logical
|
-- element contains the given string (in other words, it is the logical
|
||||||
-- inverse of htmlAnyContains).
|
-- inverse of htmlAnyContains).
|
||||||
--
|
--
|
||||||
@ -389,7 +395,7 @@ htmlNoneContain query search = do
|
|||||||
found -> failure $ "Found " <> T.pack (show $ length found) <>
|
found -> failure $ "Found " <> T.pack (show $ length found) <>
|
||||||
" instances of " <> T.pack search <> " in " <> query <> " elements"
|
" instances of " <> T.pack search <> " in " <> query <> " elements"
|
||||||
|
|
||||||
-- | Performs a css query on the last response and asserts the matched elements
|
-- | Performs a CSS query on the last response and asserts the matched elements
|
||||||
-- are as many as expected.
|
-- are as many as expected.
|
||||||
htmlCount :: Query -> Int -> YesodExample site ()
|
htmlCount :: Query -> Int -> YesodExample site ()
|
||||||
htmlCount query count = do
|
htmlCount query count = do
|
||||||
@ -408,7 +414,7 @@ printMatches query = do
|
|||||||
matches <- htmlQuery query
|
matches <- htmlQuery query
|
||||||
liftIO $ hPutStrLn stderr $ show matches
|
liftIO $ hPutStrLn stderr $ show matches
|
||||||
|
|
||||||
-- | Add a parameter with the given name and value.
|
-- | Add a parameter with the given name and value to the request body.
|
||||||
addPostParam :: T.Text -> T.Text -> RequestBuilder site ()
|
addPostParam :: T.Text -> T.Text -> RequestBuilder site ()
|
||||||
addPostParam name value =
|
addPostParam name value =
|
||||||
ST.modify $ \rbd -> rbd { rbdPostData = (addPostData (rbdPostData rbd)) }
|
ST.modify $ \rbd -> rbd { rbdPostData = (addPostData (rbdPostData rbd)) }
|
||||||
@ -416,16 +422,25 @@ addPostParam name value =
|
|||||||
addPostData (MultipleItemsPostData posts) =
|
addPostData (MultipleItemsPostData posts) =
|
||||||
MultipleItemsPostData $ ReqKvPart name value : posts
|
MultipleItemsPostData $ ReqKvPart name value : posts
|
||||||
|
|
||||||
|
-- | Add a parameter with the given name and value to the query string.
|
||||||
addGetParam :: T.Text -> T.Text -> RequestBuilder site ()
|
addGetParam :: T.Text -> T.Text -> RequestBuilder site ()
|
||||||
addGetParam name value = ST.modify $ \rbd -> rbd
|
addGetParam name value = ST.modify $ \rbd -> rbd
|
||||||
{ rbdGets = (TE.encodeUtf8 name, Just $ TE.encodeUtf8 value)
|
{ rbdGets = (TE.encodeUtf8 name, Just $ TE.encodeUtf8 value)
|
||||||
: rbdGets rbd
|
: rbdGets rbd
|
||||||
}
|
}
|
||||||
|
|
||||||
-- | Add a file to be posted with the current request
|
-- | Add a file to be posted with the current request.
|
||||||
--
|
--
|
||||||
-- Adding a file will automatically change your request content-type to be multipart/form-data
|
-- Adding a file will automatically change your request content-type to be multipart/form-data.
|
||||||
addFile :: T.Text -> FilePath -> T.Text -> RequestBuilder site ()
|
--
|
||||||
|
-- ==== __Examples__
|
||||||
|
--
|
||||||
|
-- > request $ do
|
||||||
|
-- > addFile "profile_picture" "static/img/picture.png" "img/png"
|
||||||
|
addFile :: T.Text -- ^ The parameter name for the file.
|
||||||
|
-> FilePath -- ^ The path to the file.
|
||||||
|
-> T.Text -- ^ The MIME type of the file, e.g. "image/png".
|
||||||
|
-> RequestBuilder site ()
|
||||||
addFile name path mimetype = do
|
addFile name path mimetype = do
|
||||||
contents <- liftIO $ BSL8.readFile path
|
contents <- liftIO $ BSL8.readFile path
|
||||||
ST.modify $ \rbd -> rbd { rbdPostData = (addPostData (rbdPostData rbd) contents) }
|
ST.modify $ \rbd -> rbd { rbdPostData = (addPostData (rbdPostData rbd) contents) }
|
||||||
@ -476,18 +491,75 @@ nameFromLabel label = do
|
|||||||
(<>) :: T.Text -> T.Text -> T.Text
|
(<>) :: T.Text -> T.Text -> T.Text
|
||||||
(<>) = T.append
|
(<>) = T.append
|
||||||
|
|
||||||
byLabel :: T.Text -> T.Text -> RequestBuilder site ()
|
-- How does this work for the alternate <label><input></label> syntax?
|
||||||
|
|
||||||
|
-- | Finds the @\<label>@ with the given value, finds its corresponding @\<input>@, then adds a parameter
|
||||||
|
-- for that input to the request body.
|
||||||
|
--
|
||||||
|
-- ==== __Examples__
|
||||||
|
--
|
||||||
|
-- Given this HTML, we want to submit @f1=Michael@ to the server:
|
||||||
|
--
|
||||||
|
-- > <form method="POST">
|
||||||
|
-- > <label for="user">Username</label>
|
||||||
|
-- > <input id="user" name="f1" />
|
||||||
|
-- > </form>
|
||||||
|
--
|
||||||
|
-- You can set this parameter like so:
|
||||||
|
--
|
||||||
|
-- > request $ do
|
||||||
|
-- > byLabel "Username" "Michael"
|
||||||
|
--
|
||||||
|
-- This function also supports the implicit label syntax, in which
|
||||||
|
-- the @\<input>@ is nested inside the @\<label>@ rather than specified with @for@:
|
||||||
|
--
|
||||||
|
-- > <form method="POST">
|
||||||
|
-- > <label>Username <input name="f1"> </label>
|
||||||
|
-- > </form>
|
||||||
|
byLabel :: T.Text -- ^ The text contained in the @\<label>@.
|
||||||
|
-> T.Text -- ^ The value to set the parameter to.
|
||||||
|
-> RequestBuilder site ()
|
||||||
byLabel label value = do
|
byLabel label value = do
|
||||||
name <- nameFromLabel label
|
name <- nameFromLabel label
|
||||||
addPostParam name value
|
addPostParam name value
|
||||||
|
|
||||||
fileByLabel :: T.Text -> FilePath -> T.Text -> RequestBuilder site ()
|
-- | Finds the @\<label>@ with the given value, finds its corresponding @\<input>@, then adds a file for that input to the request body.
|
||||||
|
--
|
||||||
|
-- ==== __Examples__
|
||||||
|
--
|
||||||
|
-- Given this HTML, we want to submit a file with the parameter name @f1@ to the server:
|
||||||
|
--
|
||||||
|
-- > <form method="POST">
|
||||||
|
-- > <label for="imageInput">Please submit an image</label>
|
||||||
|
-- > <input id="imageInput" type="file" name="f1" accept="image/*">
|
||||||
|
-- > </form>
|
||||||
|
--
|
||||||
|
-- You can set this parameter like so:
|
||||||
|
--
|
||||||
|
-- > request $ do
|
||||||
|
-- > fileByLabel "Please submit an image" "static/img/picture.png" "img/png"
|
||||||
|
--
|
||||||
|
-- This function also supports the implicit label syntax, in which
|
||||||
|
-- the @\<input>@ is nested inside the @\<label>@ rather than specified with @for@:
|
||||||
|
--
|
||||||
|
-- > <form method="POST">
|
||||||
|
-- > <label>Please submit an image <input type="file" name="f1"> </label>
|
||||||
|
-- > </form>
|
||||||
|
fileByLabel :: T.Text -- ^ The text contained in the @\<label>@.
|
||||||
|
-> FilePath -- ^ The path to the file.
|
||||||
|
-> T.Text -- ^ The MIME type of the file, e.g. "image/png".
|
||||||
|
-> RequestBuilder site ()
|
||||||
fileByLabel label path mime = do
|
fileByLabel label path mime = do
|
||||||
name <- nameFromLabel label
|
name <- nameFromLabel label
|
||||||
addFile name path mime
|
addFile name path mime
|
||||||
|
|
||||||
-- | Lookup a _nonce form field and add it's value to the params.
|
-- | Lookup a _token form field and add its value to the params.
|
||||||
-- Receives a CSS selector that should resolve to the form element containing the nonce.
|
-- Receives a CSS selector that should resolve to the form element containing the nonce.
|
||||||
|
--
|
||||||
|
-- ==== __Examples__
|
||||||
|
--
|
||||||
|
-- > request $ do
|
||||||
|
-- > addNonce_ "#formID"
|
||||||
addNonce_ :: Query -> RequestBuilder site ()
|
addNonce_ :: Query -> RequestBuilder site ()
|
||||||
addNonce_ scope = do
|
addNonce_ scope = do
|
||||||
matches <- htmlQuery' rbdResponse $ scope <> "input[name=_token][type=hidden][value]"
|
matches <- htmlQuery' rbdResponse $ scope <> "input[name=_token][type=hidden][value]"
|
||||||
@ -500,7 +572,11 @@ addNonce_ scope = do
|
|||||||
addNonce :: RequestBuilder site ()
|
addNonce :: RequestBuilder site ()
|
||||||
addNonce = addNonce_ ""
|
addNonce = addNonce_ ""
|
||||||
|
|
||||||
-- | Perform a POST request to url
|
-- | Perform a POST request to @url@.
|
||||||
|
--
|
||||||
|
-- ==== __Examples__
|
||||||
|
--
|
||||||
|
-- > post HomeR
|
||||||
post :: (Yesod site, RedirectUrl site url)
|
post :: (Yesod site, RedirectUrl site url)
|
||||||
=> url
|
=> url
|
||||||
-> YesodExample site ()
|
-> YesodExample site ()
|
||||||
@ -508,7 +584,14 @@ post url = request $ do
|
|||||||
setMethod "POST"
|
setMethod "POST"
|
||||||
setUrl url
|
setUrl url
|
||||||
|
|
||||||
-- | Perform a POST request to url with sending a body into it.
|
-- | Perform a POST request to @url@ with the given body.
|
||||||
|
--
|
||||||
|
-- ==== __Examples__
|
||||||
|
--
|
||||||
|
-- > postBody HomeR "foobar"
|
||||||
|
--
|
||||||
|
-- > import Data.Aeson
|
||||||
|
-- > postBody HomeR (encode $ object ["age" .= (1 :: Integer)])
|
||||||
postBody :: (Yesod site, RedirectUrl site url)
|
postBody :: (Yesod site, RedirectUrl site url)
|
||||||
=> url
|
=> url
|
||||||
-> BSL8.ByteString
|
-> BSL8.ByteString
|
||||||
@ -518,7 +601,13 @@ postBody url body = request $ do
|
|||||||
setUrl url
|
setUrl url
|
||||||
setRequestBody body
|
setRequestBody body
|
||||||
|
|
||||||
-- | Perform a GET request to url, using params
|
-- | Perform a GET request to @url@.
|
||||||
|
--
|
||||||
|
-- ==== __Examples__
|
||||||
|
--
|
||||||
|
-- > get HomeR
|
||||||
|
--
|
||||||
|
-- > get ("http://google.com" :: Text)
|
||||||
get :: (Yesod site, RedirectUrl site url)
|
get :: (Yesod site, RedirectUrl site url)
|
||||||
=> url
|
=> url
|
||||||
-> YesodExample site ()
|
-> YesodExample site ()
|
||||||
@ -526,9 +615,28 @@ get url = request $ do
|
|||||||
setMethod "GET"
|
setMethod "GET"
|
||||||
setUrl url
|
setUrl url
|
||||||
|
|
||||||
|
-- | Sets the HTTP method used by the request.
|
||||||
|
--
|
||||||
|
-- ==== __Examples__
|
||||||
|
--
|
||||||
|
-- > request $ do
|
||||||
|
-- > setMethod "POST"
|
||||||
|
--
|
||||||
|
-- > import Network.HTTP.Types.Method
|
||||||
|
-- > request $ do
|
||||||
|
-- > setMethod methodPut
|
||||||
setMethod :: H.Method -> RequestBuilder site ()
|
setMethod :: H.Method -> RequestBuilder site ()
|
||||||
setMethod m = ST.modify $ \rbd -> rbd { rbdMethod = m }
|
setMethod m = ST.modify $ \rbd -> rbd { rbdMethod = m }
|
||||||
|
|
||||||
|
-- | Sets the URL used by the request.
|
||||||
|
--
|
||||||
|
-- ==== __Examples__
|
||||||
|
--
|
||||||
|
-- > request $ do
|
||||||
|
-- > setUrl HomeR
|
||||||
|
--
|
||||||
|
-- > request $ do
|
||||||
|
-- > setUrl ("http://google.com/" :: Text)
|
||||||
setUrl :: (Yesod site, RedirectUrl site url)
|
setUrl :: (Yesod site, RedirectUrl site url)
|
||||||
=> url
|
=> url
|
||||||
-> RequestBuilder site ()
|
-> RequestBuilder site ()
|
||||||
@ -551,18 +659,45 @@ setUrl url' = do
|
|||||||
}
|
}
|
||||||
|
|
||||||
-- | Simple way to set HTTP request body
|
-- | Simple way to set HTTP request body
|
||||||
|
--
|
||||||
|
-- ==== __ Examples__
|
||||||
|
--
|
||||||
|
-- > request $ do
|
||||||
|
-- > setRequestBody "foobar"
|
||||||
|
--
|
||||||
|
-- > import Data.Aeson
|
||||||
|
-- > request $ do
|
||||||
|
-- > setRequestBody $ encode $ object ["age" .= (1 :: Integer)]
|
||||||
setRequestBody :: (Yesod site)
|
setRequestBody :: (Yesod site)
|
||||||
=> BSL8.ByteString
|
=> BSL8.ByteString
|
||||||
-> RequestBuilder site ()
|
-> RequestBuilder site ()
|
||||||
setRequestBody body = ST.modify $ \rbd -> rbd { rbdPostData = BinaryPostData body }
|
setRequestBody body = ST.modify $ \rbd -> rbd { rbdPostData = BinaryPostData body }
|
||||||
|
|
||||||
|
-- | Adds the given header to the request; see "Network.HTTP.Types.Header" for creating 'Header's.
|
||||||
|
--
|
||||||
|
-- ==== __Examples__
|
||||||
|
--
|
||||||
|
-- > import Network.HTTP.Types.Header
|
||||||
|
-- > request $ do
|
||||||
|
-- > addRequestHeader (hUserAgent, "Chrome/41.0.2228.0")
|
||||||
addRequestHeader :: H.Header -> RequestBuilder site ()
|
addRequestHeader :: H.Header -> RequestBuilder site ()
|
||||||
addRequestHeader header = ST.modify $ \rbd -> rbd
|
addRequestHeader header = ST.modify $ \rbd -> rbd
|
||||||
{ rbdHeaders = header : rbdHeaders rbd
|
{ rbdHeaders = header : rbdHeaders rbd
|
||||||
}
|
}
|
||||||
|
|
||||||
-- | General interface to performing requests, allowing you to add extra
|
-- | The general interface for performing requests. 'request' takes a 'RequestBuilder',
|
||||||
-- headers as well as letting you specify the request method.
|
-- constructs a request, and executes it.
|
||||||
|
--
|
||||||
|
-- The 'RequestBuilder' allows you to build up attributes of the request, like the
|
||||||
|
-- headers, parameters, and URL of the request.
|
||||||
|
--
|
||||||
|
-- ==== __Examples__
|
||||||
|
--
|
||||||
|
-- > request $ do
|
||||||
|
-- > addNonce
|
||||||
|
-- > byLabel "First Name" "Felipe"
|
||||||
|
-- > setMethod "PUT"
|
||||||
|
-- > setUrl NameR
|
||||||
request :: Yesod site
|
request :: Yesod site
|
||||||
=> RequestBuilder site ()
|
=> RequestBuilder site ()
|
||||||
-> YesodExample site ()
|
-> YesodExample site ()
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user