@@ -14,18 +14,22 @@ import Prelude.Compat
14
14
import Data.Aeson
15
15
import Data.ByteString.Char8 (ByteString , append , pack )
16
16
import qualified Data.ByteString.Lazy as BSL
17
+ import qualified Data.ByteString.Lazy.Char8 as BSL8
17
18
import Data.Either
18
19
import Data.Function (on )
19
20
import Data.List (maximumBy )
21
+ import qualified Data.List.NonEmpty as NE
20
22
import Data.Maybe (fromJust , isJust , isNothing )
21
23
import Data.Proxy
22
24
import Data.String (IsString (.. ))
23
25
import Data.String.Conversions (cs )
24
26
import qualified Data.Text as TextS
25
27
import qualified Data.Text.Lazy as TextL
26
28
import GHC.Generics
29
+ import qualified Network.HTTP.Media as M
27
30
import Test.Hspec
28
31
import Test.QuickCheck
32
+ import Text.Read (readMaybe )
29
33
import "quickcheck-instances" Test.QuickCheck.Instances ()
30
34
31
35
import Servant.API.ContentTypes
@@ -101,6 +105,14 @@ spec = describe "Servant.API.ContentTypes" $ do
101
105
" application/octet-stream" (" content" :: ByteString )
102
106
`shouldSatisfy` isJust
103
107
108
+ it " returns Just if the 'Accept' header matches, with multiple mime types" $ do
109
+ handleAcceptH (Proxy :: Proxy '[JSONorText ]) " application/json" (3 :: Int )
110
+ `shouldSatisfy` isJust
111
+ handleAcceptH (Proxy :: Proxy '[JSONorText ]) " text/plain" (3 :: Int )
112
+ `shouldSatisfy` isJust
113
+ handleAcceptH (Proxy :: Proxy '[JSONorText ]) " image/jpeg" (3 :: Int )
114
+ `shouldBe` Nothing
115
+
104
116
it " returns the Content-Type as the first element of the tuple" $ do
105
117
handleAcceptH (Proxy :: Proxy '[JSON ]) " */*" (3 :: Int )
106
118
`shouldSatisfy` ((== " application/json" ) . fst . fromJust)
@@ -158,6 +170,15 @@ spec = describe "Servant.API.ContentTypes" $ do
158
170
(encode val)
159
171
`shouldBe` Just (Right val)
160
172
173
+ it " returns Just (Right val) if the decoding succeeds for either of multiple mime-types" $ do
174
+ let val = 42 :: Int
175
+ handleCTypeH (Proxy :: Proxy '[JSONorText ]) " application/json"
176
+ " 42" `shouldBe` Just (Right val)
177
+ handleCTypeH (Proxy :: Proxy '[JSONorText ]) " text/plain"
178
+ " 42" `shouldBe` Just (Right val)
179
+ handleCTypeH (Proxy :: Proxy '[JSONorText ]) " image/jpeg"
180
+ " 42" `shouldBe` (Nothing :: Maybe (Either String Int ))
181
+
161
182
#if MIN_VERSION_aeson(0,9,0)
162
183
-- aeson >= 0.9 decodes top-level strings
163
184
describe " eitherDecodeLenient" $ do
@@ -201,6 +222,18 @@ instance ToJSON ByteString where
201
222
instance IsString AcceptHeader where
202
223
fromString = AcceptHeader . fromString
203
224
225
+ -- To test multiple content types
226
+ data JSONorText
227
+
228
+ instance Accept JSONorText where
229
+ contentTypes _ = " text" M. // " plain" NE. :| [ " application" M. // " json" ]
230
+
231
+ instance MimeRender JSONorText Int where
232
+ mimeRender _ = cs . show
233
+
234
+ instance MimeUnrender JSONorText Int where
235
+ mimeUnrender _ = maybe (Left " " ) Right . readMaybe . BSL8. unpack
236
+
204
237
addToAccept :: Accept a => Proxy a -> ZeroToOne -> AcceptHeader -> AcceptHeader
205
238
addToAccept p (ZeroToOne f) (AcceptHeader h) = AcceptHeader (cont h)
206
239
where new = cs (show $ contentType p) `append` " ; q=" `append` pack (show f)
0 commit comments