@@ -31,6 +31,8 @@ import Network.HTTP.Types (methodGet, methodHead, parseMethod,
31-- indication of how to proceed or what went wrong.
31-- indication of how to proceed or what went wrong.
33-- This function checks that the response code is not 500.
33-- This function checks that the response code is not 500.
34not500 :: ResponsePredicate Text Bool
36not500 :: ResponsePredicate Text Bool
35not500 = ResponsePredicate "not500" (\resp -> not $ responseStatus resp == status500)
37not500 = ResponsePredicate "not500" (\resp -> not $ responseStatus resp == status500)
@@ -53,6 +55,8 @@ not500 = ResponsePredicate "not500" (\resp -> not $ responseStatus resp == statu
54-- * JSON Grammar: <https://tools.ietf.org/html/rfc7159#section-2 RFC 7159 Section 2>
56-- * JSON Grammar: <https://tools.ietf.org/html/rfc7159#section-2 RFC 7159 Section 2>
55-- * JSON Grammar: <https://tools.ietf.org/html/rfc4627#section-2 RFC 4627 Section 2>
57-- * JSON Grammar: <https://tools.ietf.org/html/rfc4627#section-2 RFC 4627 Section 2>
56onlyJsonObjects :: ResponsePredicate Text Bool
60onlyJsonObjects :: ResponsePredicate Text Bool
57onlyJsonObjects
61onlyJsonObjects
58 = ResponsePredicate "onlyJsonObjects" (\resp -> case decode (responseBody resp) of
62 = ResponsePredicate "onlyJsonObjects" (\resp -> case decode (responseBody resp) of
@@ -76,6 +80,8 @@ onlyJsonObjects
77-- * 201 Created: <https://tools.ietf.org/html/rfc7231#section-6.3.2 RFC 7231 Section 6.3.2>
81-- * 201 Created: <https://tools.ietf.org/html/rfc7231#section-6.3.2 RFC 7231 Section 6.3.2>
78-- * Location header: <https://tools.ietf.org/html/rfc7231#section-7.1.2 RFC 7231 Section 7.1.2>
82-- * Location header: <https://tools.ietf.org/html/rfc7231#section-7.1.2 RFC 7231 Section 7.1.2>
79createContainsValidLocation :: RequestPredicate Text Bool
85createContainsValidLocation :: RequestPredicate Text Bool
80createContainsValidLocation
86createContainsValidLocation
81 = RequestPredicate
87 = RequestPredicate
@@ -114,6 +120,8 @@ getsHaveLastModifiedHeader
115-- * @Allow@ header: <https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html RFC 2616 Section 14.7>
121-- * @Allow@ header: <https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html RFC 2616 Section 14.7>
116-- * Status 405: <https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html RFC 2616 Section 10.4.6>
122-- * Status 405: <https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html RFC 2616 Section 10.4.6>
117notAllowedContainsAllowHeader :: RequestPredicate Text Bool
125notAllowedContainsAllowHeader :: RequestPredicate Text Bool
118notAllowedContainsAllowHeader
126notAllowedContainsAllowHeader
119 = RequestPredicate
127 = RequestPredicate
@@ -144,6 +152,8 @@ notAllowedContainsAllowHeader
144-- __References__:
152-- __References__:
146-- * @Accept@ header: <https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html RFC 2616 Section 14.1>
154-- * @Accept@ header: <https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html RFC 2616 Section 14.1>
147honoursAcceptHeader :: RequestPredicate Text Bool
157honoursAcceptHeader :: RequestPredicate Text Bool
148honoursAcceptHeader
158honoursAcceptHeader
149 = RequestPredicate
159 = RequestPredicate
@@ -171,7 +181,7 @@ honoursAcceptHeader
172-- * @Cache-Control@ header: <https://tools.ietf.org/html/rfc7234#section-5.2 RFC 7234 Section 5.2>
182-- * @Cache-Control@ header: <https://tools.ietf.org/html/rfc7234#section-5.2 RFC 7234 Section 5.2>
174−-- #SINCE#
184+-- /Since 0.0.0.0/
175getsHaveCacheControlHeader :: RequestPredicate Text Bool
185getsHaveCacheControlHeader :: RequestPredicate Text Bool
176getsHaveCacheControlHeader
186getsHaveCacheControlHeader
177 = RequestPredicate
187 = RequestPredicate
@@ -188,7 +198,7 @@ getsHaveCacheControlHeader
189-- Like 'getsHaveCacheControlHeader', but for @HEAD@ requests.
199-- Like 'getsHaveCacheControlHeader', but for @HEAD@ requests.
191−-- #SINCE#
201+-- /Since 0.0.0.0/
192headsHaveCacheControlHeader :: RequestPredicate Text Bool
202headsHaveCacheControlHeader :: RequestPredicate Text Bool
193headsHaveCacheControlHeader
203headsHaveCacheControlHeader
194 = RequestPredicate
204 = RequestPredicate
@@ -260,7 +270,7 @@ linkHeadersAreValid
261-- * @WWW-Authenticate@ header: <https://tools.ietf.org/html/rfc7235#section-4.1 RFC 7235 Section 4.1>
271-- * @WWW-Authenticate@ header: <https://tools.ietf.org/html/rfc7235#section-4.1 RFC 7235 Section 4.1>
263−-- #SINCE#
273+-- /Since 0.0.0.0/
264unauthorizedContainsWWWAuthenticate :: ResponsePredicate Text Bool
274unauthorizedContainsWWWAuthenticate :: ResponsePredicate Text Bool
265unauthorizedContainsWWWAuthenticate
275unauthorizedContainsWWWAuthenticate
266 = ResponsePredicate "unauthorizedContainsWWWAuthenticate" (\resp ->
276 = ResponsePredicate "unauthorizedContainsWWWAuthenticate" (\resp ->
@@ -276,6 +286,9 @@ unauthorizedContainsWWWAuthenticate
277-- Still, this is all kind of ugly.
287-- Still, this is all kind of ugly.
289+-- | A predicate that depends only on the response.
279data ResponsePredicate n r = ResponsePredicate
292data ResponsePredicate n r = ResponsePredicate
280 { respPredName :: n
293 { respPredName :: n
281 , respPred :: Response LBS.ByteString -> r
294 , respPred :: Response LBS.ByteString -> r
@@ -292,6 +305,9 @@ instance (Monoid n, Monoid r) => Monoid (ResponsePredicate n r) where
292 , respPred = respPred a <> respPred b
305 , respPred = respPred a <> respPred b
308+-- | A predicate that depends on both the request and the response.
295data RequestPredicate n r = RequestPredicate
311data RequestPredicate n r = RequestPredicate
296 { reqPredName :: n
312 { reqPredName :: n
297 , reqResps :: Request -> Manager -> IO (r, [Response LBS.ByteString])
313 , reqResps :: Request -> Manager -> IO (r, [Response LBS.ByteString])
@@ -309,6 +325,7 @@ instance (Monoid n, Monoid r) => Monoid (RequestPredicate n r) where
309 , reqResps = \x m -> liftM2 (<>) (reqResps a x m) (reqResps b x m)
325 , reqResps = \x m -> liftM2 (<>) (reqResps a x m) (reqResps b x m)
328+-- | A set of predicates. Construct one with 'mempty' and '<%>'.
312data Predicates n r = Predicates
329data Predicates n r = Predicates
313 { reqPreds :: RequestPredicate n r
330 { reqPreds :: RequestPredicate n r
314 , respPreds :: ResponsePredicate n r
331 , respPreds :: ResponsePredicate n r
@@ -339,7 +356,7 @@ instance JoinPreds (ResponsePredicate Text Bool) where
340-- > not500 <%> onlyJsonObjects <%> empty
357-- > not500 <%> onlyJsonObjects <%> empty
342−-- #SINCE#
359+-- /Since 0.0.0.0/
343(<%>) :: JoinPreds a => a -> Predicates [Text] [Text] -> Predicates [Text] [Text]
360(<%>) :: JoinPreds a => a -> Predicates [Text] [Text] -> Predicates [Text] [Text]
344(<%>) = joinPreds
361(<%>) = joinPreds
345infixr 6 <%>
362infixr 6 <%>