git.iko.soy/typeable/servant
on master help sign in
Only 'text' type should have charset parameter
99374c5Julian K. Arni
src/Servant/API/ContentTypes.hs+2−2
@@ -44,9 +44,9 @@ data OctetStream deriving Typeable
44class Accept ctype where
44class Accept ctype where
45 contentType :: Proxy ctype -> M.MediaType
45 contentType :: Proxy ctype -> M.MediaType
46
46
47−-- | @application/json;charset=utf-8@
47+-- | @application/json@
48instance Accept JSON where
48instance Accept JSON where
49− contentType _ = "application" M.// "json" M./: ("charset", "utf-8")
49+ contentType _ = "application" M.// "json"
50
50
51-- | @text/plain;charset=utf-8@
51-- | @text/plain;charset=utf-8@
52instance Accept PlainText where
52instance Accept PlainText where
test/Servant/API/ContentTypesSpec.hs+46−17
@@ -13,7 +13,7 @@ import Data.Proxy
13import Data.ByteString.Char8
13import Data.ByteString.Char8
14import qualified Data.ByteString.Lazy as BSL
14import qualified Data.ByteString.Lazy as BSL
15import Data.List (maximumBy)
15import Data.List (maximumBy)
16−import Data.Maybe (fromJust, isJust)
16+import Data.Maybe (fromJust, isJust, isNothing)
17import Data.String (IsString (..))
17import Data.String (IsString (..))
18import Data.String.Conversions (cs)
18import Data.String.Conversions (cs)
19import qualified Data.Text as TextS
19import qualified Data.Text as TextS
@@ -61,6 +61,10 @@ spec = describe "Servant.API.ContentTypes" $ do
61
61
62 describe "handleAcceptH" $ do
62 describe "handleAcceptH" $ do
63
63
64+ it "returns Nothing if the 'Accept' header doesn't match" $ do
65+ handleAcceptH (Proxy :: Proxy '[JSON]) "text/plain" (3 :: Int)
66+ `shouldSatisfy` isNothing
67+
64 it "returns Just if the 'Accept' header matches" $ do
68 it "returns Just if the 'Accept' header matches" $ do
65 handleAcceptH (Proxy :: Proxy '[JSON]) "*/*" (3 :: Int)
69 handleAcceptH (Proxy :: Proxy '[JSON]) "*/*" (3 :: Int)
66 `shouldSatisfy` isJust
70 `shouldSatisfy` isJust
@@ -72,30 +76,55 @@ spec = describe "Servant.API.ContentTypes" $ do
72
76
73 it "returns the Content-Type as the first element of the tuple" $ do
77 it "returns the Content-Type as the first element of the tuple" $ do
74 handleAcceptH (Proxy :: Proxy '[JSON]) "*/*" (3 :: Int)
78 handleAcceptH (Proxy :: Proxy '[JSON]) "*/*" (3 :: Int)
75− `shouldSatisfy` ((== "application/json;charset=utf-8") . fst . fromJust)
79+ `shouldSatisfy` ((== "application/json") . fst . fromJust)
76 handleAcceptH (Proxy :: Proxy '[PlainText, JSON]) "application/json" (3 :: Int)
80 handleAcceptH (Proxy :: Proxy '[PlainText, JSON]) "application/json" (3 :: Int)
77− `shouldSatisfy` ((== "application/json;charset=utf-8") . fst . fromJust)
81+ `shouldSatisfy` ((== "application/json") . fst . fromJust)
78 handleAcceptH (Proxy :: Proxy '[PlainText, JSON, OctetStream])
82 handleAcceptH (Proxy :: Proxy '[PlainText, JSON, OctetStream])
79 "application/octet-stream" ("content" :: ByteString)
83 "application/octet-stream" ("content" :: ByteString)
80 `shouldSatisfy` ((== "application/octet-stream") . fst . fromJust)
84 `shouldSatisfy` ((== "application/octet-stream") . fst . fromJust)
81
85
82 it "returns the appropriately serialized representation" $ do
86 it "returns the appropriately serialized representation" $ do
83 property $ \x -> handleAcceptH (Proxy :: Proxy '[JSON]) "*/*" (x :: SomeData)
87 property $ \x -> handleAcceptH (Proxy :: Proxy '[JSON]) "*/*" (x :: SomeData)
84− == Just ("application/json;charset=utf-8", encode x)
88+ == Just ("application/json", encode x)
85−
89+
86− it "respects the Accept spec ordering" $
90+ it "respects the Accept spec ordering" $ do
87− property $ \a b c i -> fst (fromJust $ val a b c i) == (fst $ highest a b c)
88− where
89− highest a b c = maximumBy (compare `on` snd)
91+ let highest a b c = maximumBy (compare `on` snd)
90− [ ("application/octet-stream", a)
92+ [ ("application/octet-stream", a)
91− , ("application/json;charset=utf-8", b)
93+ , ("application/json", b)
92− , ("text/plain;charset=utf-8", c)
94+ , ("text/plain;charset=utf-8", c)
93− ]
95+ ]
94− acceptH a b c = addToAccept (Proxy :: Proxy OctetStream) a $
96+ let acceptH a b c = addToAccept (Proxy :: Proxy OctetStream) a $
95− addToAccept (Proxy :: Proxy JSON) b $
97+ addToAccept (Proxy :: Proxy JSON) b $
96− addToAccept (Proxy :: Proxy PlainText ) c ""
98+ addToAccept (Proxy :: Proxy PlainText ) c ""
97− val a b c i = handleAcceptH (Proxy :: Proxy '[OctetStream, JSON, PlainText])
99+ let val a b c i = handleAcceptH (Proxy :: Proxy '[OctetStream, JSON, PlainText])
98 (acceptH a b c) (i :: Int)
100 (acceptH a b c) (i :: Int)
101+ property $ \a b c i -> fst (fromJust $ val a b c i) == fst (highest a b c)
102+
103+ describe "handleCTypeH" $ do
104+
105+ it "returns Nothing if the 'Content-Type' header doesn't match" $ do
106+ handleCTypeH (Proxy :: Proxy '[JSON]) "text/plain" "𝓽𝓱𝓮 𝓽𝓲𝓶𝓮 𝓱𝓪𝓼 𝓬𝓸𝓶𝓮, 𝓽𝓱𝓮 𝔀𝓪𝓵𝓻𝓾𝓼 𝓼𝓪𝓲𝓭 "
107+ `shouldBe` (Nothing :: Maybe (Either String Value))
108+
109+ context "the 'Content-Type' header matches" $ do
110+ it "returns Just if the parameter matches" $ do
111+ handleCTypeH (Proxy :: Proxy '[JSON]) "application/json"
112+ "𝕥𝕠 𝕥𝕒𝕝𝕜 𝕠𝕗 𝕞𝕒𝕟𝕪 𝕥𝕙𝕚𝕟𝕘𝕤 "
113+ `shouldSatisfy` (isJust :: Maybe (Either String Value) -> Bool)
114+
115+ it "returns Just if there is no parameter" $ do
116+ handleCTypeH (Proxy :: Proxy '[JSON]) "application/json"
117+ "𝕥𝕠 𝕥𝕒𝕝𝕜 𝕠𝕗 𝕞𝕒𝕟𝕪 𝕥𝕙𝕚𝕟𝕘𝕤 "
118+ `shouldSatisfy` (isJust :: Maybe (Either String Value) -> Bool)
119+
120+ it "returns Just Left if the decoding fails" $ do
121+ let isJustLeft :: Maybe (Either String Value) -> Bool
122+ isJustLeft (Just (Left _)) = True
123+ isJustLeft _ = False
124+ handleCTypeH (Proxy :: Proxy '[JSON]) "application/json"
125+ "𝕺𝖋 𝖘𝖍𝖔𝖊𝖘--𝖆𝖓𝖉 𝖘𝖍𝖎𝖕𝖘--𝖆𝖓𝖉 𝖘𝖊𝖆𝖑𝖎𝖓𝖌-𝖜𝖆𝖝-- "
126+ `shouldSatisfy` isJustLeft
127+
99
128
100data SomeData = SomeData { record1 :: String, record2 :: Int }
129data SomeData = SomeData { record1 :: String, record2 :: Int }
101 deriving (Generic, Eq, Show)
130 deriving (Generic, Eq, Show)