forked from assaf/zombie
/
cookies_test.coffee
308 lines (245 loc) · 10.9 KB
/
cookies_test.coffee
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
{ assert, brains, Browser } = require("./helpers")
describe "Cookies", ->
# Parse string with cookies in it (like document.cookies) and return object
# with name/value pairs for each cookie.
parse = (cookies)->
return cookies
.split(/;\s*/)
.map((cookie)-> cookie.split("="))
.reduce((all, [name, value])->
all[name] = value.replace(/^"(.*)"$/, "$1")
all
, Object.create({}))
# Extracts cookies from @browser, parses and sets @cookies.
cookies_from_html = ->
@cookies = parse(@browser.text("html"))
return
before (done)->
brains.get "/cookies", (req, res)->
res.cookie "_name", "value"
res.cookie "_expires1", "3s", expires: new Date(Date.now() + 3000)
res.cookie "_expires2", "5s", "Max-Age": 5000
res.cookie "_expires3", "0s", expires: new Date(Date.now() - 100)
res.cookie "_path1", "yummy", path: "/cookies"
res.cookie "_path2", "yummy", path: "/cookies/sub"
res.cookie "_path3", "wrong", path: "/wrong"
res.cookie "_path4", "yummy", path: "/"
res.cookie "_domain1", "here", domain: ".localhost"
res.cookie "_domain2", "not here", domain: "not.localhost"
res.cookie "_domain3", "wrong", domain: "notlocalhost"
res.cookie "_multiple", "specific", path: "/cookies"
res.cookie "_multiple", "general", path: "/"
res.cookie "_http_only","value", httpOnly: true
res.cookie "_dup", "one", path: "/"
res.send "<html></html>"
brains.get "/cookies/echo", (req,res)->
cookies = ("#{k}=#{v}" for k,v of req.cookies).join("; ")
res.send "<html>#{cookies}</html>"
brains.get "/cookies/empty", (req,res)->
res.send "<html></html>"
brains.ready done
describe "get cookies", ->
before (done)->
@browser = new Browser()
@browser.visit "http://localhost:3003/cookies", done
describe "cookies", ->
before ->
@cookies = @browser.cookies("localhost", "/cookies")
it "should have access to session cookie", ->
assert.equal @cookies.get("_name"), "value"
it "should have access to persistent cookie", ->
assert.equal @cookies.get("_expires1"), "3s"
assert.equal @cookies.get("_expires2"), "5s"
it "should not have access to expired cookies", ->
assert @cookies.get("_expires3") == undefined
it "should have access to cookies for the path /cookies", ->
assert.equal @cookies.get("_path1"), "yummy"
it "should have access to cookies for paths which are ancestors of /cookies", ->
assert.equal @cookies.get("_path4"), "yummy"
it "should not have access to other paths", ->
assert @cookies.get("_path2") == undefined
assert @cookies.get("_path3") == undefined
it "should have access to .domain", ->
assert.equal @cookies.get("_domain1"), "here"
it "should not have access to other domains", ->
assert @cookies.get("_domain2") == undefined
assert @cookies.get("_domain3") == undefined
it "should access most specific cookie", ->
assert.equal @cookies.get("_multiple"), "specific"
describe "host in domain", ->
before ->
@cookies = @browser.cookies("host.localhost")
it "should have access to host cookies", ->
assert.equal @cookies.get("_domain1"), "here"
it "should not have access to other hosts' cookies", ->
assert @cookies.get("_domain2") == undefined
assert @cookies.get("_domain3") == undefined
describe "document.cookie", ->
before ->
@cookie = @browser.document.cookie
it "should return name/value pairs", ->
assert /^(\w+=\w+; )+\w+=\w+$/.test(@cookie)
describe "pairs", ->
before ->
@pairs = parse(@cookie)
it "should include only visible cookies", ->
keys = (key for key, value of @pairs).sort()
assert.deepEqual keys, "_domain1 _dup _expires1 _expires2 _multiple _name _path1 _path4".split(" ")
it "should match name to value", ->
assert.equal @pairs._name, "value"
assert.equal @pairs._path1, "yummy"
it "should not include httpOnly cookies", ->
for key, value of @pairs
assert key != "_http_only"
describe "host", ->
before (done)->
browser = new Browser()
browser.visit("http://host.localhost:3003/cookies")
.then =>
@cookies = browser.cookies("localhost", "/cookies")
return
.then(done, done)
it "should be able to set domain cookies", ->
assert.equal @cookies.get("_domain1"), "here"
describe "get cookies and redirect", ->
before (done)->
brains.get "/cookies/redirect", (req, res)->
res.cookie "_expires4", "3s" #, expires: new Date(Date.now() + 3000), "Path": "/"
res.redirect "/"
browser = new Browser()
browser.visit("http://localhost:3003/cookies/redirect")
.then =>
@cookies = browser.cookies("localhost", "/cookies/redirect")
return
.then(done, done)
it "should have access to persistent cookie", ->
assert.equal @cookies.get("_expires4"), "3s"
describe "duplicates", ->
before (done)->
brains.get "/cookies2", (req, res)->
res.cookie "_dup", "two", path: "/"
res.send ""
brains.get "/cookies3", (req, res)->
res.cookie "_dup", "three", path: "/"
res.send ""
@browser = new Browser()
@browser.visit("http://localhost:3003/cookies")
.then =>
@browser.visit "http://localhost:3003/cookies2"
.then =>
@browser.visit "http://localhost:3003/cookies3"
.then(done, done)
it "should retain last value", ->
assert.equal @browser.cookies().get("_dup"), "three"
it "should only retain last cookie", ->
dups = @browser.cookies().all().filter((c)-> c.key == "_dup")
assert.equal dups.length, 1
describe "send cookies", ->
before (done)->
@browser = new Browser()
@browser.cookies("localhost" ).set "_name", "value"
@browser.cookies("localhost" ).set "_expires1", "3s", "max-age": 3000
@browser.cookies("localhost" ).set "_expires2", "0s", "max-age": 0
@browser.cookies("localhost", "/cookies" ).set "_path1", "here"
@browser.cookies("localhost", "/cookies/echo" ).set "_path2", "here"
@browser.cookies("localhost", "/jars" ).set "_path3", "there", "path": "/jars"
@browser.cookies("localhost", "/cookies/fido" ).set "_path4", "there", "path": "/cookies/fido"
@browser.cookies("localhost", "/" ).set "_path5", "here", "path": "/cookies"
@browser.cookies("localhost", "/jars/" ).set "_path6", "there"
@browser.cookies(".localhost" ).set "_domain1", "here"
@browser.cookies("not.localhost" ).set "_domain2", "there"
@browser.cookies("notlocalhost" ).set "_domain3", "there"
@browser.visit("http://localhost:3003/cookies/echo")
.then(cookies_from_html.bind(this))
.then(done, done)
it "should send session cookie", ->
assert.equal @cookies._name, "value"
it "should pass persistent cookie to server", ->
assert.equal @cookies._expires1, "3s"
it "should not pass expired cookie to server", ->
assert @cookies._expires2 == undefined
it "should pass path cookies to server", ->
assert.equal @cookies._path1, "here"
assert.equal @cookies._path2, "here"
it "should pass cookies that specified a different path when they were assigned", ->
assert.equal @cookies._path5, "here"
it "should not pass unrelated path cookies to server", ->
assert @cookies._path3 == undefined
assert @cookies._path4 == undefined
assert @cookies._path6 == undefined
it "should pass sub-domain cookies to server", ->
assert.equal @cookies._domain1, "here"
it "should not pass other domain cookies to server", ->
assert @cookies._domain2 == undefined
assert @cookies._domain3 == undefined
describe "setting cookies from subdomains", ->
before ->
@browser = new Browser()
@browser.cookies("www.localhost").update("foo=bar; domain=.localhost")
it "should be accessible", ->
assert.equal "bar", @browser.cookies("localhost").get("foo")
assert.equal "bar", @browser.cookies("www.localhost").get("foo")
describe "setting Cookie header", ->
before ->
@header = { cookie: "" }
browser = new Browser()
browser.cookies().update("foo=bar;")
browser.cookies().addHeader @header
it "should send V0 header", ->
assert.equal @header.cookie, "foo=bar"
describe "document.cookie", ->
describe "setting cookie", ->
before (done)->
@browser = new Browser()
@browser.visit("http://localhost:3003/cookies")
.then =>
@browser.document.cookie = "foo=bar"
return
.then(done, done)
it "should be available from document", ->
assert ~@browser.document.cookie.split("; ").indexOf("foo=bar")
describe "on reload", ->
before (done)->
@browser.visit("http://localhost:3003/cookies/echo")
.then(cookies_from_html.bind(this))
.then(done, done)
it "should send to server", ->
assert.equal @cookies.foo, "bar"
describe "different path", ->
before (done)->
@browser.visit("http://localhost:3003/cookies")
.then =>
@browser.document.cookie = "foo=bar"
return
.then(done, done)
before (done)->
@browser.visit("http://localhost:3003/cookies/other")
.then =>
@browser.document.cookie = "foo=qux" # more specific path, not visible to /cookies.echo
return
.finally(done)
before (done)->
@browser.visit("http://localhost:3003/cookies/echo")
.then(cookies_from_html.bind(this))
.then(done, done)
it "should not be visible", ->
assert !@cookies.bar
assert.equal @cookies.foo, "bar"
describe "setting cookie with quotes", ->
before (done)->
@browser.visit("http://localhost:3003/cookies/empty")
.then =>
@browser.document.cookie = "foo=bar\"baz"
return
.then(done, done)
it "should be available from document", ->
assert.equal @browser.cookies().get("foo"), "bar\"baz"
describe "setting cookie with semicolon", ->
before (done)->
@browser.visit("http://localhost:3003/cookies/empty")
.then =>
@browser.document.cookie = "foo=bar; baz"
return
.then(done, done)
it "should be available from document", ->
assert.equal @browser.cookies().get("foo"), "bar"