Spock-core-0.11.0.0: test/Web/Spock/Internal/CookiesSpec.hs
{-# LANGUAGE CPP #-}
{-# LANGUAGE OverloadedStrings #-}
module Web.Spock.Internal.CookiesSpec (spec) where
import Web.Spock.Internal.Cookies
import Control.Monad
import Data.Time
import Test.Hspec
import qualified Data.ByteString as BS
spec :: Spec
spec =
do describe "Generating Cookies" $
do describe "with the default settings" $
do let generated = g "foo" "bar" def
it "should generate the name-value pair" $
generated `shouldContainOnce` "foo=bar"
it "should not generate a max-age key" $
generated `shouldNotContain'` "Max-Age="
it "should not generate an expires key" $
generated `shouldNotContain'` "Expires="
it "should generate a root path" $
generated `shouldContainOnce` "Path=/"
it "should not generate a domain pair" $
generated `shouldNotContain'` "Domain="
it "should not generate a httponly key" $
generated `shouldNotContain'` "HttpOnly"
it "should not generate a secure key" $
generated `shouldNotContain'` "Secure"
describe "when setting an expiration time in the future" $
do let generated = g "foo" "bar" def { cs_EOL = CookieValidUntil (UTCTime (fromGregorian 2016 1 1) 0) }
it "should set the correct expires key" $
generated `shouldContainOnce` "Expires=Fri, 01-Jan-2016 00:00:00 GMT"
it "should set the correct max-age key" $
generated `shouldContainOnce` "Max-Age=10465200"
describe "when setting an expiration time in the past" $
do let generated = g "foo" "bar" def { cs_EOL = CookieValidUntil (UTCTime (fromGregorian 1970 1 1) 0) }
it "should set the correct expires key" $
generated `shouldContainOnce` "Expires=Thu, 01-Jan-1970 00:00:00 GMT"
it "should set the max-age key to 0" $
generated `shouldContainOnce` "Max-Age=0"
describe "when setting the path" $
it "should generate the correct path pair" $
g "foo" "bar" def { cs_path = Just "/the-path" } `shouldContainOnce` "Path=/the-path"
describe "when setting the domain" $
it "should generate the correct domain pair" $
g "foo" "bar" def { cs_domain = Just "example.org" } `shouldContainOnce` "Domain=example.org"
describe "when setting the httponly option" $
it "should generate the httponly key" $
g "foo" "bar" def { cs_HTTPOnly = True } `shouldContainOnce` "HttpOnly"
describe "when setting the secure option" $
it "should generate the secure key" $
g "foo" "bar" def { cs_secure = True } `shouldContainOnce` "Secure"
describe "cookie value" $
it "should be urlencoded" $
g "foo" "most+special chars;%бисквитки" def `shouldContainOnce`
"foo=most%2Bspecial%20chars%3B%25%D0%B1%D0%B8%D1%81%D0%BA%D0%B2%D0%B8%D1%82%D0%BA%D0%B8"
describe "Parsing cookies" $
do it "should parse urlencoded multiple cookies" $
parseCookies "foo=bar;quux=h&m" `shouldBe` [("foo", "bar"), ("quux", "h&m")]
it "should handle spacing between cookies" $
parseCookies "foo=bar; quux=bim" `shouldBe` [("foo", "bar"), ("quux", "bim")]
it "should parse urlencoded values" $
parseCookies "foo=most%2Bspecial%20chars%3B%25" `shouldBe` [("foo", "most+special chars;%")]
it "should parse urlencoded utf-8 content" $
parseCookies "foo=%D0%B1%D0%B8%D1%81%D0%BA%D0%B2%D0%B8%D1%82%D0%BA%D0%B8" `shouldBe` [("foo", "бисквитки")]
where
g n v cs = generateCookieHeaderString n v cs t
def = defaultCookieSettings
t = UTCTime (fromGregorian 2015 9 1) (21*60*60)
shouldContainOnce haystack needle =
let snb actual notExpected =
unless (actual /= notExpected) $
expectationFailure $
"Failed to find " ++ show needle ++ " in " ++ show haystack
in snd (BS.breakSubstring needle haystack) `snb` BS.empty
shouldNotContain' haystack needle =
snd (BS.breakSubstring needle haystack) `shouldBe` BS.empty