-
Notifications
You must be signed in to change notification settings - Fork 27
Expand file tree
/
Copy pathSessionSpec.purs
More file actions
126 lines (119 loc) · 5.48 KB
/
SessionSpec.purs
File metadata and controls
126 lines (119 loc) · 5.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
module Hyper.SessionSpec where
import Prelude
import Control.IxMonad ((:*>))
import Control.Monad.Aff (Aff)
import Control.Monad.Aff.Class (liftAff)
import Control.Monad.Eff.Class (liftEff)
import Control.Monad.Eff.Console (CONSOLE)
import Control.Monad.Eff.Random (RANDOM)
import Control.Monad.Eff.Ref (REF)
import Control.Monad.Writer.Trans (WriterT, execWriterT, runWriterT)
import Data.Either (Either)
import Data.Maybe (Maybe(..))
import Data.Monoid (class Monoid)
import Data.StrMap as StrMap
import Data.Tuple (Tuple(..), fst)
import Hyper.Conn (Conn)
import Hyper.Cookies (Values, cookies)
import Hyper.Middleware (Middleware, evalMiddleware, runMiddleware)
import Hyper.Node.Session.Cookie (CookieStore(..), mkSecret)
import Hyper.Node.Session.InMemory (newInMemorySessionStore)
import Hyper.Response (HeadersOpen, class Response)
import Hyper.Session (class SessionStore, delete, deleteSession, get, getSession, newSessionID, put, saveSession)
import Hyper.Test.TestServer (TestRequest(..), TestResponse(..), defaultRequest)
import Node.Buffer (BUFFER)
import Node.Crypto (CRYPTO)
import Test.Spec (Spec, it, describe)
import Test.Spec.Assertions (shouldEqual, shouldNotEqual)
type MyAff b state e = WriterT (TestResponse b state) (Aff e)
saveSession' ::
forall b state e req res store c session.
Response res (MyAff b state e) b =>
SessionStore store (MyAff b state e) session =>
session ->
Middleware
(MyAff b state e)
(Conn
req
(res HeadersOpen)
{ sessions :: { key :: String, store :: store }
, cookies :: Either String (StrMap.StrMap Values)
| c })
(Conn
req
(res HeadersOpen)
{ sessions :: { key :: String, store :: store }
, cookies :: Either String (StrMap.StrMap Values)
| c })
Unit
saveSession' = saveSession
run :: forall w m a. Functor m => WriterT w m a -> m a
run = runWriterT >>> map fst
getCookie :: Array (Tuple String String) -> String
getCookie [Tuple "Set-Cookie" c] = c
getCookie _ = ""
testStore :: forall store session e b state e.
SessionStore store (MyAff b state (console :: CONSOLE | e)) session =>
Show session =>
Eq session =>
Monoid session =>
Aff (console :: CONSOLE | e) store -> session -> session -> Spec (console :: CONSOLE | e) Unit
testStore store session session' = do
it "retrieves data that was stored" do
store' <- store
liftAff (session `shouldNotEqual` session')
id <- run $ newSessionID store'
id' <- run $ put store' id session
sessionOut <- run $ get store' id'
sessionOut `shouldEqual` Just session
id1 <- run $ newSessionID store'
id1' <- run $ put store' id1 session'
sessionOut' <- run $ get store' id1'
sessionOut' `shouldEqual` Just session'
sessionOutSecond <- run $ get store' id'
sessionOutSecond `shouldEqual` Just session
id2 <- run $ newSessionID store'
blankSession <- run $ get store' id2
blankSession `shouldEqual` Nothing
run $ delete store' id'
sessionOutDeleted <- run $ get store' id
sessionOutDeleted `shouldEqual` Nothing
it "works with getSession/saveSession/deleteSession" do
store' <- store
Tuple sessionOut _ <- { request: TestRequest defaultRequest
, response: TestResponse Nothing [] []
, components: { sessions: { key: "session", store: store' }
, cookies: unit }}
# runMiddleware (cookies :*> getSession) >>> run
sessionOut `shouldEqual` Nothing
TestResponse _ headers _ <- { request: TestRequest defaultRequest
, response: TestResponse Nothing [] []
, components: { sessions: { key: "session", store: store' }
, cookies: unit }}
# evalMiddleware (cookies :*> saveSession' session) >>> execWriterT
let newCookies = getCookie headers
Tuple sessionOut' _ <- { request: TestRequest defaultRequest { headers = StrMap.singleton "cookie" newCookies }
, response: TestResponse Nothing [] []
, components: { sessions: { key: "session", store: store' }
, cookies: unit }}
# runMiddleware (cookies :*> getSession) >>> run
sessionOut' `shouldEqual` Just session
Tuple response (TestResponse _ headers' _)
<- { request: TestRequest defaultRequest { headers = StrMap.singleton "cookie" newCookies }
, response: TestResponse Nothing [] []
, components: { sessions: { key: "session", store: store' }
, cookies: unit }}
# evalMiddleware (cookies :*> getSession :*> deleteSession) >>> runWriterT
let newCookies' = getCookie headers'
Tuple sessionOut' _ <- { request: TestRequest defaultRequest { headers = StrMap.singleton "cookie" newCookies' }
, response: TestResponse Nothing [] []
, components: { sessions: { key: "session", store: store' }
, cookies: unit }}
# runMiddleware (cookies :*> getSession) >>> run
sessionOut' `shouldEqual` Nothing
spec :: forall e. Spec (ref :: REF, console :: CONSOLE, random :: RANDOM, buffer :: BUFFER, crypto :: CRYPTO | e) Unit
spec = do
describe "Hyper.Node.Session.InMemory" do
testStore (liftEff newInMemorySessionStore) "value1" "value2"
describe "Hyper.Node.Session.Cookie" do
testStore (CookieStore <$> mkSecret) "value1" "value2"