1module CookieTest (cookieTest) where 2 3import Prelude hiding (exp) 4import Test.Hspec 5import qualified Data.ByteString as BS 6import Test.HUnit hiding (path) 7import Network.HTTP.Client 8import qualified Network.HTTP.Conduit as HC 9import Data.ByteString.UTF8 10import Data.Monoid 11import Data.Time.Clock 12import Data.Time.Calendar 13import qualified Data.CaseInsensitive as CI 14import Web.Cookie 15 16default_request :: HC.Request 17default_request = HC.parseRequest_ "http://www.google.com/" 18 19default_cookie :: Cookie 20default_cookie = Cookie { cookie_name = fromString "name" 21 , cookie_value = fromString "value" 22 , cookie_expiry_time = default_time 23 , cookie_domain = fromString "www.google.com" 24 , cookie_path = fromString "/" 25 , cookie_creation_time = default_time 26 , cookie_last_access_time = default_time 27 , cookie_persistent = False 28 , cookie_host_only = False 29 , cookie_secure_only = False 30 , cookie_http_only = False 31 } 32 33default_time :: UTCTime 34default_time = UTCTime (ModifiedJulianDay 56200) (secondsToDiffTime 0) 35 36default_diff_time :: DiffTime 37default_diff_time = secondsToDiffTime 1209600 38 39default_set_cookie :: SetCookie 40default_set_cookie = def { setCookieName = fromString "name" 41 , setCookieValue = fromString "value" 42 , setCookiePath = Just $ fromString "/" 43 , setCookieExpires = Just default_time 44 , setCookieMaxAge = Just default_diff_time 45 , setCookieDomain = Just $ fromString "www.google.com" 46 , setCookieHttpOnly = False 47 , setCookieSecure = False 48 } 49 50testValidIp :: IO () 51testValidIp = assertBool "Couldn't parse valid IP address" $ 52 isIpAddress $ fromString "1.2.3.4" 53 54testIpNumTooHigh :: IO () 55testIpNumTooHigh = assertBool "One of the digits in the IP address is too large" $ 56 not $ isIpAddress $ fromString "501.2.3.4" 57 58testTooManySegmentsInIp :: IO () 59testTooManySegmentsInIp = assertBool "Too many segments in the ip address" $ 60 not $ isIpAddress $ fromString "1.2.3.4.5" 61 62testCharsInIp :: IO () 63testCharsInIp = assertBool "Chars are not allowed in IP addresses" $ 64 not $ isIpAddress $ fromString "1.2a3.4.5" 65 66testDomainMatchesSuccess :: IO () 67testDomainMatchesSuccess = assertBool "Domains should match" $ 68 domainMatches (fromString "www.google.com") (fromString "google.com") 69 70testSameDomain :: IO () 71testSameDomain = assertBool "Same domain should match" $ 72 domainMatches domain domain 73 where domain = fromString "www.google.com" 74 75testSiblingDomain :: IO () 76testSiblingDomain = assertBool "Sibling domain should not match" $ 77 not $ domainMatches (fromString "www.google.com") (fromString "secure.google.com") 78 79testParentDomain :: IO () 80testParentDomain = assertBool "Parent domain should fail" $ 81 not $ domainMatches (fromString "google.com") (fromString "www.google.com") 82 83testNaiveSuffixDomain :: IO () 84testNaiveSuffixDomain = assertBool "Naively checking for suffix for domain matching should fail" $ 85 not $ domainMatches (fromString "agoogle.com") (fromString "google.com") 86 87testDefaultPath :: IO () 88testDefaultPath = assertEqual "Getting default path from a request" 89 (fromString "/") (defaultPath default_request) 90 91testShortDefaultPath :: IO () 92testShortDefaultPath = assertEqual "Getting default path from a short path" 93 (fromString "/") (defaultPath $ default_request {HC.path = fromString "/search"}) 94 95testPopulatedDefaultPath :: IO () 96testPopulatedDefaultPath = assertEqual "Getting default path from a request with a path" 97 (fromString "/search") (defaultPath $ default_request {HC.path = fromString "/search/term"}) 98 99testParamsDefaultPath :: IO () 100testParamsDefaultPath = assertEqual "Getting default path from a request with a path and GET params" 101 (fromString "/search") (defaultPath $ default_request {HC.path = fromString "/search/term?var=val"}) 102 103testDefaultPathEndingInSlash :: IO () 104testDefaultPathEndingInSlash = assertEqual "Getting default path that ends in a slash" 105 (fromString "/search/term") (defaultPath $ default_request {HC.path = fromString "/search/term/"}) 106 107testSamePathsMatch :: IO () 108testSamePathsMatch = assertBool "The same path should match" $ 109 pathMatches path' path' 110 where path' = fromString "/a/path" 111 112testPathSlashAtEnd :: IO () 113testPathSlashAtEnd = assertBool "Putting the slash at the end should still match paths" $ 114 pathMatches (fromString "/a/path/to/here") (fromString "/a/path/") 115 116testPathNoSlashAtEnd :: IO () 117testPathNoSlashAtEnd = assertBool "Not putting the slash at the end should still match paths" $ 118 pathMatches (fromString "/a/path/to/here") (fromString "/a/path") 119 120testDivergingPaths :: IO () 121testDivergingPaths = assertBool "Diverging paths don't match" $ 122 not $ pathMatches (fromString "/a/path/to/here") (fromString "/a/different/path") 123 124testCookieEqualitySuccess :: IO () 125testCookieEqualitySuccess = assertEqual "The same cookies should be equal" 126 cookie cookie 127 where cookie = default_cookie 128 129testCookieEqualityResiliance :: IO () 130testCookieEqualityResiliance = assertEqual "Cookies should still be equal if extra options are changed" 131 (default_cookie {cookie_persistent = True}) (default_cookie {cookie_host_only = True}) 132 133testDomainChangesEquality :: IO () 134testDomainChangesEquality = assertBool "Changing the domain should make cookies not equal" $ 135 default_cookie /= (default_cookie {cookie_domain = fromString "/search"}) 136 137testRemoveCookie :: IO () 138testRemoveCookie = assertEqual "Removing a cookie works" 139 (Just default_cookie, createCookieJar []) (removeExistingCookieFromCookieJar default_cookie $ createCookieJar [default_cookie]) 140 141testRemoveNonexistantCookie :: IO () 142testRemoveNonexistantCookie = assertEqual "Removing a nonexistent cookie doesn't work" 143 (Nothing, createCookieJar [default_cookie]) (removeExistingCookieFromCookieJar (default_cookie {cookie_name = fromString "key2"}) $ createCookieJar [default_cookie]) 144 145testRemoveCorrectCookie :: IO () 146testRemoveCorrectCookie = assertEqual "Removing only the correct cookie" 147 (Just search_for, createCookieJar [red_herring]) (removeExistingCookieFromCookieJar search_for $ createCookieJar [red_herring, search_for]) 148 where search_for = default_cookie {cookie_name = fromString "name1"} 149 red_herring = default_cookie {cookie_name = fromString "name2"} 150 151testEvictExpiredCookies :: IO () 152testEvictExpiredCookies = assertEqual "Evicting expired cookies works" 153 (createCookieJar [a, c]) (evictExpiredCookies (createCookieJar [a, b, c, d]) middle) 154 where a = default_cookie { cookie_name = fromString "a" 155 , cookie_expiry_time = UTCTime (ModifiedJulianDay 3) (secondsToDiffTime 0) 156 } 157 b = default_cookie { cookie_name = fromString "b" 158 , cookie_expiry_time = UTCTime (ModifiedJulianDay 1) (secondsToDiffTime 0) 159 } 160 c = default_cookie { cookie_name = fromString "c" 161 , cookie_expiry_time = UTCTime (ModifiedJulianDay 3) (secondsToDiffTime 0) 162 } 163 d = default_cookie { cookie_name = fromString "d" 164 , cookie_expiry_time = UTCTime (ModifiedJulianDay 1) (secondsToDiffTime 0) 165 } 166 middle = UTCTime (ModifiedJulianDay 2) (secondsToDiffTime 0) 167 168testEvictNoCookies :: IO () 169testEvictNoCookies = assertEqual "Evicting empty cookie jar" 170 (createCookieJar []) (evictExpiredCookies (createCookieJar []) middle) 171 where middle = UTCTime (ModifiedJulianDay 2) (secondsToDiffTime 0) 172 173testComputeCookieStringUpdateLastAccessTime :: IO () 174testComputeCookieStringUpdateLastAccessTime = assertEqual "Updates last access time upon using cookies" 175 (fromString "name=value", out_cookie_jar) (computeCookieString request cookie_jar now True) 176 where request = default_request 177 cookie_jar = createCookieJar [default_cookie] 178 now = UTCTime (ModifiedJulianDay 0) (secondsToDiffTime 1) 179 out_cookie_jar = createCookieJar [default_cookie {cookie_last_access_time = now}] 180 181testComputeCookieStringHostOnly :: IO () 182testComputeCookieStringHostOnly = assertEqual "Host only cookies should match host exactly" 183 (fromString "name=value", cookie_jar) (computeCookieString request cookie_jar default_time True) 184 where request = default_request 185 cookie_jar = createCookieJar [default_cookie {cookie_host_only = True}] 186 187testComputeCookieStringHostOnlyFilter :: IO () 188testComputeCookieStringHostOnlyFilter = assertEqual "Host only cookies shouldn't match subdomain" 189 (fromString "", cookie_jar) (computeCookieString request cookie_jar default_time True) 190 where request = default_request {HC.host = fromString "sub1.sub2.google.com"} 191 cookie_jar = createCookieJar [default_cookie { cookie_host_only = True 192 , cookie_domain = fromString "sub2.google.com" 193 } 194 ] 195 196testComputeCookieStringDomainMatching :: IO () 197testComputeCookieStringDomainMatching = assertEqual "Domain matching works for new requests" 198 (fromString "name=value", cookie_jar) (computeCookieString request cookie_jar default_time True) 199 where request = default_request {HC.host = fromString "sub1.sub2.google.com"} 200 cookie_jar = createCookieJar [default_cookie {cookie_domain = fromString "sub2.google.com"}] 201 202testComputeCookieStringPathMatching :: IO () 203testComputeCookieStringPathMatching = assertEqual "Path matching works for new requests" 204 (fromString "name=value", cookie_jar) (computeCookieString request cookie_jar default_time True) 205 where request = default_request {HC.path = fromString "/a/path/to/nowhere"} 206 cookie_jar = createCookieJar [default_cookie {cookie_path = fromString "/a/path"}] 207 208testComputeCookieStringPathMatchingFails :: IO () 209testComputeCookieStringPathMatchingFails = assertEqual "Path matching fails when it should" 210 (fromString "", cookie_jar) (computeCookieString request cookie_jar default_time True) 211 where request = default_request {HC.path = fromString "/a/different/path/to/nowhere"} 212 cookie_jar = createCookieJar [default_cookie {cookie_path = fromString "/a/path"}] 213 214testComputeCookieStringPathMatchingWithParms :: IO () 215testComputeCookieStringPathMatchingWithParms = assertEqual "Path matching succeeds when request has GET params" 216 (fromString "name=value", cookie_jar) (computeCookieString request cookie_jar default_time True) 217 where request = default_request {HC.path = fromString "/a/path/to/nowhere?var=val"} 218 cookie_jar = createCookieJar [default_cookie {cookie_path = fromString "/a/path"}] 219 220testComputeCookieStringSecure :: IO () 221testComputeCookieStringSecure = assertEqual "Secure flag filters properly" 222 (fromString "", cookie_jar) (computeCookieString default_request cookie_jar default_time True) 223 where cookie_jar = createCookieJar [default_cookie {cookie_secure_only = True}] 224 225testComputeCookieStringHttpOnly :: IO () 226testComputeCookieStringHttpOnly = assertEqual "http-only flag filters properly" 227 (fromString "", cookie_jar) (computeCookieString default_request cookie_jar default_time False) 228 where cookie_jar = createCookieJar [default_cookie {cookie_http_only = True}] 229 230testComputeCookieStringSort :: IO () 231testComputeCookieStringSort = assertEqual "Sorting works correctly" 232 (fromString "c1=v1;c3=v3;c4=v4;c2=v2", cookie_jar_out) format_output 233 where now = UTCTime (ModifiedJulianDay 10) (secondsToDiffTime 11) 234 cookie_jar = createCookieJar [ default_cookie { cookie_name = fromString "c1" 235 , cookie_value = fromString "v1" 236 , cookie_path = fromString "/all/encompassing/request" 237 } 238 , default_cookie { cookie_name = fromString "c2" 239 , cookie_value = fromString "v2" 240 , cookie_path = fromString "/all" 241 } 242 , default_cookie { cookie_name = fromString "c3" 243 , cookie_value = fromString "v3" 244 , cookie_path = fromString "/all/encompassing" 245 , cookie_creation_time = UTCTime (ModifiedJulianDay 0) (secondsToDiffTime 1) 246 } 247 , default_cookie { cookie_name = fromString "c4" 248 , cookie_value = fromString "v4" 249 , cookie_path = fromString "/all/encompassing" 250 , cookie_creation_time = UTCTime (ModifiedJulianDay 0) (secondsToDiffTime 2) 251 } 252 ] 253 cookie_jar_out = createCookieJar [ default_cookie { cookie_name = fromString "c1" 254 , cookie_value = fromString "v1" 255 , cookie_path = fromString "/all/encompassing/request" 256 , cookie_last_access_time = now 257 } 258 , default_cookie { cookie_name = fromString "c2" 259 , cookie_value = fromString "v2" 260 , cookie_path = fromString "/all" 261 , cookie_last_access_time = now 262 } 263 , default_cookie { cookie_name = fromString "c3" 264 , cookie_value = fromString "v3" 265 , cookie_path = fromString "/all/encompassing" 266 , cookie_creation_time = UTCTime (ModifiedJulianDay 0) (secondsToDiffTime 1) 267 , cookie_last_access_time = now 268 } 269 , default_cookie { cookie_name = fromString "c4" 270 , cookie_value = fromString "v4" 271 , cookie_path = fromString "/all/encompassing" 272 , cookie_creation_time = UTCTime (ModifiedJulianDay 0) (secondsToDiffTime 2) 273 , cookie_last_access_time = now 274 } 275 ] 276 request = default_request {HC.path = fromString "/all/encompassing/request/path"} 277 format_output = computeCookieString request cookie_jar default_time False 278 279testInsertCookiesIntoRequestWorks :: IO () 280testInsertCookiesIntoRequestWorks = assertEqual "Inserting cookies works" 281 [(CI.mk $ fromString "Cookie", fromString "key=val")] out_headers 282 where out_headers = HC.requestHeaders req 283 (req, _) = insertCookiesIntoRequest req' cookie_jar default_time 284 cookie_jar = createCookieJar [ default_cookie { cookie_name = fromString "key" 285 , cookie_value = fromString "val" 286 } 287 ] 288 req' = default_request {HC.requestHeaders = [(CI.mk $ fromString "Cookie", 289 fromString "otherkey=otherval")]} 290 291testReceiveSetCookie :: IO () 292testReceiveSetCookie = assertEqual "Receiving a Set-Cookie" 293 (createCookieJar [default_cookie]) (receiveSetCookie default_set_cookie default_request default_time True $ createCookieJar []) 294 295testReceiveSetCookieTrailingDot :: IO () 296testReceiveSetCookieTrailingDot = assertEqual "Receiving a Set-Cookie with a trailing domain dot" 297 (createCookieJar []) (receiveSetCookie set_cookie default_request default_time True $ createCookieJar []) 298 where set_cookie = default_set_cookie {setCookieDomain = Just $ fromString "www.google.com."} 299 300testReceiveSetCookieLeadingDot :: IO () 301testReceiveSetCookieLeadingDot = assertEqual "Receiving a Set-Cookie with a leading domain dot" 302 (createCookieJar [default_cookie]) (receiveSetCookie set_cookie default_request default_time True $ createCookieJar []) 303 where set_cookie = default_set_cookie {setCookieDomain = Just $ fromString ".www.google.com"} 304 305testReceiveSetCookieNoDomain :: IO () 306testReceiveSetCookieNoDomain = assertEqual "Receiving cookie without domain" 307 (createCookieJar [default_cookie]) (receiveSetCookie set_cookie default_request default_time True $ createCookieJar []) 308 where set_cookie = default_set_cookie {setCookieDomain = Nothing} 309 310testReceiveSetCookieEmptyDomain :: IO () 311testReceiveSetCookieEmptyDomain = assertEqual "Receiving cookie with empty domain" 312 (createCookieJar [default_cookie]) (receiveSetCookie set_cookie default_request default_time True $ createCookieJar []) 313 where set_cookie = default_set_cookie {setCookieDomain = Just BS.empty} 314 315-- Can't test public suffixes until that module is written 316 317testReceiveSetCookieNonMatchingDomain :: IO () 318testReceiveSetCookieNonMatchingDomain = assertEqual "Receiving cookie with non-matching domain" 319 (createCookieJar []) (receiveSetCookie set_cookie default_request default_time True $ createCookieJar []) 320 where set_cookie = default_set_cookie {setCookieDomain = Just $ fromString "www.wikipedia.org"} 321 322testReceiveSetCookieHostOnly :: IO () 323testReceiveSetCookieHostOnly = assertBool "Checking host-only flag gets set" $ 324 cookie_host_only $ head $ destroyCookieJar $ receiveSetCookie set_cookie default_request default_time True $ createCookieJar [] 325 where set_cookie = default_set_cookie {setCookieDomain = Nothing} 326 327testReceiveSetCookieHostOnlyNotSet :: IO () 328testReceiveSetCookieHostOnlyNotSet = assertBool "Checking host-only flag doesn't get set" $ 329 not $ cookie_host_only $ head $ destroyCookieJar $ receiveSetCookie set_cookie default_request default_time True $ createCookieJar [] 330 where set_cookie = default_set_cookie {setCookieDomain = Just $ fromString "google.com"} 331 332testReceiveSetCookieHttpOnly :: IO () 333testReceiveSetCookieHttpOnly = assertBool "Checking http-only flag gets set" $ 334 cookie_http_only $ head $ destroyCookieJar $ receiveSetCookie set_cookie default_request default_time True $ createCookieJar [] 335 where set_cookie = default_set_cookie {setCookieHttpOnly = True} 336 337testReceiveSetCookieHttpOnlyNotSet :: IO () 338testReceiveSetCookieHttpOnlyNotSet = assertBool "Checking http-only flag doesn't get set" $ 339 not $ cookie_http_only $ head $ destroyCookieJar $ receiveSetCookie set_cookie default_request default_time True $ createCookieJar [] 340 where set_cookie = default_set_cookie {setCookieHttpOnly = False} 341 342testReceiveSetCookieHttpOnlyDrop :: IO () 343testReceiveSetCookieHttpOnlyDrop = assertEqual "Checking non http request gets dropped" 344 (createCookieJar []) (receiveSetCookie set_cookie default_request default_time False $ createCookieJar []) 345 where set_cookie = default_set_cookie {setCookieHttpOnly = True} 346 347testReceiveSetCookieName :: IO () 348testReceiveSetCookieName = assertEqual "Name gets set correctly" 349 (fromString "name") (cookie_name $ head $ destroyCookieJar $ receiveSetCookie default_set_cookie default_request default_time True $ createCookieJar []) 350 351testReceiveSetCookieValue :: IO () 352testReceiveSetCookieValue = assertEqual "Value gets set correctly" 353 (fromString "value") (cookie_value $ head $ destroyCookieJar $ receiveSetCookie default_set_cookie default_request default_time True $ createCookieJar []) 354 355testReceiveSetCookieExpiry :: IO () 356testReceiveSetCookieExpiry = assertEqual "Expiry gets set correctly" 357 now_plus_diff_time (cookie_expiry_time $ head $ destroyCookieJar $ receiveSetCookie default_set_cookie default_request default_time True $ createCookieJar []) 358 where now_plus_diff_time = ((fromRational $ toRational default_diff_time) `addUTCTime` default_time) 359 360testReceiveSetCookieNoMaxAge :: IO () 361testReceiveSetCookieNoMaxAge = assertEqual "Expiry is based on the given value" 362 default_time (cookie_expiry_time $ head $ destroyCookieJar $ receiveSetCookie cookie_without_max_age default_request default_time True $ createCookieJar []) 363 where cookie_without_max_age = default_set_cookie {setCookieMaxAge = Nothing} 364 365testReceiveSetCookieNoExpiry :: IO () 366testReceiveSetCookieNoExpiry = assertEqual "Expiry is based on max age" 367 now_plus_diff_time (cookie_expiry_time $ head $ destroyCookieJar $ receiveSetCookie cookie_without_expiry default_request default_time True $ createCookieJar []) 368 where now_plus_diff_time = ((fromRational $ toRational default_diff_time) `addUTCTime` default_time) 369 cookie_without_expiry = default_set_cookie {setCookieExpires = Nothing} 370 371testReceiveSetCookieNoExpiryNoMaxAge :: IO () 372testReceiveSetCookieNoExpiryNoMaxAge = assertBool "Expiry is set to a future date" $ 373 default_time < (cookie_expiry_time $ head $ destroyCookieJar $ receiveSetCookie basic_cookie default_request default_time True $ createCookieJar []) 374 where basic_cookie = default_set_cookie { setCookieExpires = Nothing, setCookieMaxAge = Nothing } 375 376testReceiveSetCookiePath :: IO () 377testReceiveSetCookiePath = assertEqual "Path gets set correctly" 378 (fromString "/a/path") (cookie_path $ head $ destroyCookieJar $ receiveSetCookie set_cookie default_request default_time True $ createCookieJar []) 379 where set_cookie = default_set_cookie {setCookiePath = Just $ fromString "/a/path"} 380 381testReceiveSetCookieNoPath :: IO () 382testReceiveSetCookieNoPath = assertEqual "Path gets set correctly when nonexistent" 383 (fromString "/a/path/to") (cookie_path $ head $ destroyCookieJar $ receiveSetCookie set_cookie request default_time True $ createCookieJar []) 384 where set_cookie = default_set_cookie {setCookiePath = Nothing} 385 request = default_request {HC.path = fromString "/a/path/to/nowhere"} 386 387testReceiveSetCookieCreationTime :: IO () 388testReceiveSetCookieCreationTime = assertEqual "Creation time gets set correctly" 389 now (cookie_creation_time $ head $ destroyCookieJar $ receiveSetCookie default_set_cookie default_request now True $ createCookieJar []) 390 where now = UTCTime (ModifiedJulianDay 0) (secondsToDiffTime 1) 391 392testReceiveSetCookieAccessTime :: IO () 393testReceiveSetCookieAccessTime = assertEqual "Last access time gets set correctly" 394 now (cookie_last_access_time $ head $ destroyCookieJar $ receiveSetCookie default_set_cookie default_request now True $ createCookieJar []) 395 where now = UTCTime (ModifiedJulianDay 0) (secondsToDiffTime 1) 396 397testReceiveSetCookiePersistent :: IO () 398testReceiveSetCookiePersistent = assertBool "Persistent flag gets set correctly" $ 399 cookie_persistent $ head $ destroyCookieJar $ receiveSetCookie set_cookie default_request default_time True $ createCookieJar [] 400 where set_cookie = default_set_cookie {setCookieExpires = Just default_time} 401 402testReceiveSetCookieSecure :: IO () 403testReceiveSetCookieSecure = assertBool "Secure flag gets set correctly" $ 404 cookie_secure_only $ head $ destroyCookieJar $ receiveSetCookie set_cookie default_request default_time True $ createCookieJar [] 405 where set_cookie = default_set_cookie {setCookieSecure = True} 406 407testReceiveSetCookieMaxAge :: IO () 408testReceiveSetCookieMaxAge = assertEqual "Max-Age gets set correctly" 409 total (cookie_expiry_time $ head $ destroyCookieJar $ receiveSetCookie set_cookie default_request now True $ createCookieJar []) 410 where set_cookie = default_set_cookie { setCookieExpires = Nothing 411 , setCookieMaxAge = Just $ secondsToDiffTime 10 412 } 413 now = UTCTime (ModifiedJulianDay 10) (secondsToDiffTime 12) 414 total = UTCTime (ModifiedJulianDay 10) (secondsToDiffTime 22) 415 416testReceiveSetCookiePreferMaxAge :: IO () 417testReceiveSetCookiePreferMaxAge = assertEqual "Max-Age is preferred over Expires" 418 total (cookie_expiry_time $ head $ destroyCookieJar $ receiveSetCookie set_cookie default_request now True $ createCookieJar []) 419 where set_cookie = default_set_cookie { setCookieExpires = Just exp 420 , setCookieMaxAge = Just $ secondsToDiffTime 10 421 } 422 exp = UTCTime (ModifiedJulianDay 11) (secondsToDiffTime 5) 423 now = UTCTime (ModifiedJulianDay 10) (secondsToDiffTime 12) 424 total = UTCTime (ModifiedJulianDay 10) (secondsToDiffTime 22) 425 426testReceiveSetCookieExisting :: IO () 427testReceiveSetCookieExisting = assertEqual "Existing cookie gets updated" 428 t (cookie_expiry_time $ head $ destroyCookieJar $ receiveSetCookie set_cookie default_request default_time True $ createCookieJar [default_cookie]) 429 where set_cookie = default_set_cookie { setCookieExpires = Just t 430 , setCookieMaxAge = Nothing 431 } 432 t = UTCTime (ModifiedJulianDay 10) (secondsToDiffTime 12) 433 434testReceiveSetCookieExistingCreation :: IO () 435testReceiveSetCookieExistingCreation = assertEqual "Creation time gets updated in existing cookie" 436 default_time (cookie_creation_time $ head $ destroyCookieJar $ receiveSetCookie default_set_cookie default_request now True $ createCookieJar [default_cookie]) 437 where now = UTCTime (ModifiedJulianDay 10) (secondsToDiffTime 12) 438 439testReceiveSetCookieExistingHttpOnly :: IO () 440testReceiveSetCookieExistingHttpOnly = assertEqual "Existing http-only cookie gets dropped" 441 default_time (cookie_expiry_time $ head $ destroyCookieJar $ receiveSetCookie default_set_cookie default_request default_time False $ createCookieJar [existing_cookie]) 442 where existing_cookie = default_cookie {cookie_http_only = True} 443 444testMonoidPreferRecent :: IO () 445testMonoidPreferRecent = assertEqual "Monoid prefers more recent cookies" 446 (cct $ createCookieJar [c2]) (cct $ createCookieJar [c1] `Data.Monoid.mappend` createCookieJar [c2]) 447 where c1 = default_cookie {cookie_creation_time = UTCTime (ModifiedJulianDay 0) (secondsToDiffTime 1)} 448 c2 = default_cookie {cookie_creation_time = UTCTime (ModifiedJulianDay 0) (secondsToDiffTime 2)} 449 cct cj = cookie_creation_time $ head $ destroyCookieJar cj 450 451ipParseTests :: Spec 452ipParseTests = do 453 it "Valid IP" testValidIp 454 it "Digit Too High" testIpNumTooHigh 455 it "Too Many Segments" testTooManySegmentsInIp 456 it "Chars in IP" testCharsInIp 457 458domainMatchingTests :: Spec 459domainMatchingTests = do 460 it "Should Match" testDomainMatchesSuccess 461 it "Same Domain" testSameDomain 462 it "Sibling Domain" testSiblingDomain 463 it "Parent Domain" testParentDomain 464 it "Checking for Naive suffix-check" testNaiveSuffixDomain 465 466defaultPathTests :: Spec 467defaultPathTests = do 468 it "Basic default path test" testDefaultPath 469 it "Basic populated default path" testPopulatedDefaultPath 470 it "Default path from request with GET params works" testParamsDefaultPath 471 it "Getting a default path that ends in a slash" testDefaultPathEndingInSlash 472 it "Getting a short default path" testShortDefaultPath 473 474pathMatchingTests :: Spec 475pathMatchingTests = do 476 it "Same paths match" testSamePathsMatch 477 it "Putting slash at end" testPathSlashAtEnd 478 it "Not putting slash at end" testPathNoSlashAtEnd 479 it "Diverging paths don't match" testDivergingPaths 480 481equalityTests :: Spec 482equalityTests = do 483 it "The same cookie should be equal to itself" testCookieEqualitySuccess 484 it "Changing extra options shouldn't change equality" testCookieEqualityResiliance 485 it "Changing a cookie's domain should change its equality" testDomainChangesEquality 486 487removeTests :: Spec 488removeTests = do 489 it "Removing a cookie works" testRemoveCookie 490 it "Removing a nonexistent cookie doesn't work" testRemoveNonexistantCookie 491 it "Removing the correct cookie" testRemoveCorrectCookie 492 493evictionTests :: Spec 494evictionTests = do 495 it "Testing eviction" testEvictExpiredCookies 496 it "Evicting from empty cookie jar" testEvictNoCookies 497 498sendingTests :: Spec 499sendingTests = do 500 it "Updates last access time upon using cookies" testComputeCookieStringUpdateLastAccessTime 501 it "Host-only flag matches exact host" testComputeCookieStringHostOnly 502 it "Host-only flag doesn't match subdomain" testComputeCookieStringHostOnlyFilter 503 it "Domain matching works properly" testComputeCookieStringDomainMatching 504 it "Path matching works" testComputeCookieStringPathMatching 505 it "Path matching fails when it should" testComputeCookieStringPathMatchingFails 506 it "Path matching succeeds when request has GET params" testComputeCookieStringPathMatchingWithParms 507 it "Secure flag filters correctly" testComputeCookieStringSecure 508 it "Http-only flag filters correctly" testComputeCookieStringHttpOnly 509 it "Sorting works correctly" testComputeCookieStringSort 510 it "Inserting cookie header works" testInsertCookiesIntoRequestWorks 511 512receivingTests :: Spec 513receivingTests = do 514 it "Can receive set-cookie" testReceiveSetCookie 515 it "Receiving a Set-Cookie with a trailing dot on the domain" testReceiveSetCookieTrailingDot 516 it "Receiving a Set-Cookie with a leading dot on the domain" testReceiveSetCookieLeadingDot 517 it "Set-Cookie with no domain" testReceiveSetCookieNoDomain 518 it "Set-Cookie with empty domain" testReceiveSetCookieEmptyDomain 519 it "Set-Cookie with non-matching domain" testReceiveSetCookieNonMatchingDomain 520 it "Host-only flag gets set" testReceiveSetCookieHostOnly 521 it "Host-only flag doesn't get set" testReceiveSetCookieHostOnlyNotSet 522 it "Http-only flag gets set" testReceiveSetCookieHttpOnly 523 it "Http-only flag doesn't get set" testReceiveSetCookieHttpOnlyNotSet 524 it "Checking non http request gets dropped" testReceiveSetCookieHttpOnlyDrop 525 it "Name gets set correctly" testReceiveSetCookieName 526 it "Value gets set correctly" testReceiveSetCookieValue 527 it "Expiry gets set correctly" testReceiveSetCookieExpiry 528 it "Expiry gets set based on max age if no expiry is given" testReceiveSetCookieNoExpiry 529 it "Expiry gets set based on given value if no max age is given" testReceiveSetCookieNoMaxAge 530 it "Expiry gets set to a future date if no expiry and no max age are given" testReceiveSetCookieNoExpiryNoMaxAge 531 it "Path gets set correctly when nonexistent" testReceiveSetCookieNoPath 532 it "Path gets set correctly" testReceiveSetCookiePath 533 it "Creation time gets set correctly" testReceiveSetCookieCreationTime 534 it "Last access time gets set correctly" testReceiveSetCookieAccessTime 535 it "Persistent flag gets set correctly" testReceiveSetCookiePersistent 536 it "Existing cookie gets updated" testReceiveSetCookieExisting 537 it "Creation time gets updated in existing cookie" testReceiveSetCookieExistingCreation 538 it "Existing http-only cookie gets dropped" testReceiveSetCookieExistingHttpOnly 539 it "Secure flag gets set correctly" testReceiveSetCookieSecure 540 it "Max-Age flag gets set correctly" testReceiveSetCookieMaxAge 541 it "Max-Age is preferred over Expires" testReceiveSetCookiePreferMaxAge 542 543monoidTests :: Spec 544monoidTests = do 545 it "Monoid prefers more recent cookies" testMonoidPreferRecent 546 547cookieTest :: Spec 548cookieTest = do 549 describe "ipParseTests" ipParseTests 550 describe "domainMatchingTests" domainMatchingTests 551 describe "defaultPathTests" defaultPathTests 552 describe "pathMatchingTests" pathMatchingTests 553 describe "equalityTests" equalityTests 554 describe "removeTests" removeTests 555 describe "evictionTests" evictionTests 556 describe "sendingTests" sendingTests 557 describe "receivingTests" receivingTests 558 describe "monoidTest" monoidTests 559