sbsm 1.3.2 → 1.3.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/History.txt +7 -0
- data/README.md +0 -1
- data/lib/sbsm/app.rb +26 -21
- data/lib/sbsm/redirector.rb +3 -0
- data/lib/sbsm/session.rb +40 -31
- data/lib/sbsm/state.rb +2 -2
- data/lib/sbsm/trans_handler.rb +1 -1
- data/lib/sbsm/validator.rb +2 -0
- data/lib/sbsm/version.rb +1 -1
- data/test/simple_sbsm.rb +24 -2
- data/test/test_application.rb +62 -9
- data/test/test_session.rb +11 -5
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cc83ce9eaa4b2e9edae741b89a255562e1dfd7c7
|
4
|
+
data.tar.gz: 0a3ac026d12912a8ffa5858ed73abf735d51d5d6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ab32237e7ab03816f1c24ab0d3cad5b7076f318531b04894c983adf7595427cd4e2853f4c6ec86027d44c6a3d5fec764562c3a5f7b8a0b2bfd693f7a09e16cce
|
7
|
+
data.tar.gz: 300f865f03dc9f0ef0d7ea26b52039b63c2ac44ca411dfbe255b3bf5a66ef357531fe1c846b8302f6f0a0b0d4033602dcd22080e5bb36aa2663bb4603417bb29
|
data/History.txt
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
=== 1.3.3 / 7.12.2016
|
2
|
+
* Hashes are handled differently in mod_ruby and rack add a test for it, but I am unsure
|
3
|
+
whether I handle everything is okay, as I had to add article to the STRINGS in davaz.compatible
|
4
|
+
to make the app work again
|
5
|
+
** mod_ruby workedwith @request.params["hash[3]"] = "6"
|
6
|
+
** rack works like @request.params['real_hash'] = {'1' => 'a', '2' => 'b'}
|
7
|
+
|
1
8
|
=== 1.3.2 / 15.11.2016
|
2
9
|
* Requires the drb_uri-parameter when creating an app
|
3
10
|
* Determine the MIME-Type of all returned files by their ending using gem mimemagic
|
data/README.md
CHANGED
@@ -10,7 +10,6 @@ Application framework for state based session management. See lib/sbsm.rb
|
|
10
10
|
|
11
11
|
* Open problems
|
12
12
|
** There is no real integration test using rack-test to prove that a minimal app is working
|
13
|
-
** Handling a POST request for handling a form does not work yet
|
14
13
|
** Handling redirects is not tested (and probably will not work)
|
15
14
|
** Handling passthru is not tested (and probably will not work)
|
16
15
|
** I get often the error `Errno::EACCES at / Permission denied @ rb_sysopen - /tmp/sbsm_lock`. Reloading the page once or twices fixes the problem.
|
data/lib/sbsm/app.rb
CHANGED
@@ -35,14 +35,9 @@ module SBSM
|
|
35
35
|
# App a base class for Webrick server
|
36
36
|
class App < SBSM::DRbServer
|
37
37
|
include DRbUndumped
|
38
|
-
PERSISTENT_COOKIE_NAME = "cookie-persistent-sbsm-1.3.1"
|
39
|
-
SBSM.info "PERSISTENT_COOKIE_NAME #{PERSISTENT_COOKIE_NAME}"
|
40
|
-
|
41
38
|
attr_reader :sbsm, :my_self, :trans_handler, :validator, :drb_uri
|
42
39
|
|
43
|
-
OPTIONS = [ :app, :config_file, :trans_handler, :validator, :persistence_layer, :server_uri, :session, :unknown_user ]
|
44
|
-
COOKIE_ID = 'sbsm-persistent-cookie-id'
|
45
|
-
|
40
|
+
OPTIONS = [ :app, :config_file, :trans_handler, :validator, :persistence_layer, :server_uri, :session, :unknown_user, :proxy ]
|
46
41
|
OPTIONS.each{ |opt| eval "attr_reader :#{opt}" }
|
47
42
|
|
48
43
|
# Base class for a SBSM based WebRick HTTP server
|
@@ -52,32 +47,37 @@ module SBSM
|
|
52
47
|
#
|
53
48
|
# === arguments
|
54
49
|
#
|
50
|
+
# * +app+ - The app we should handle requests for
|
55
51
|
# * +validator+ - A Ruby class overriding the SBSM::Validator class
|
56
52
|
# * +trans_handler+ - A Ruby class overriding the SBSM::TransHandler class
|
57
53
|
# * +persistence_layer+ - Persistence Layer to use
|
54
|
+
# * +cookie_name+ - The cookie to save persistent user data
|
55
|
+
# * +drb_uri+ - URI for DRB-Server of app
|
58
56
|
#
|
59
57
|
# === Examples
|
60
58
|
# Look at steinwies.ch
|
61
59
|
# * https://github.com/zdavatz/steinwies.ch (simple, mostly static files, one form, no persistence layer)
|
62
60
|
#
|
63
|
-
def initialize(app:, validator:, trans_handler:, drb_uri:, persistence_layer: nil)
|
64
|
-
@app
|
61
|
+
def initialize(app:, validator:, trans_handler:, drb_uri:, persistence_layer: nil, cookie_name: nil)
|
62
|
+
SBSM.info "initialize #{$0} app #{app.class} @app is now #{@app.class} validator #{validator} th #{trans_handler} drb_uri #{drb_uri}"
|
63
|
+
@app = app unless @app
|
64
|
+
@cookie_name = cookie_name || SBSM::Session::PERSISTENT_COOKIE_NAME
|
65
65
|
@drb_uri = drb_uri
|
66
66
|
@trans_handler = trans_handler
|
67
67
|
@validator = validator
|
68
|
-
SBSM.info "initialize @app is now #{@app.class} validator #{validator} th #{trans_handler} drb_uri #{drb_uri}"
|
69
68
|
super(persistence_layer)
|
70
69
|
end
|
71
70
|
|
71
|
+
SESSION_ID = '_session_id'
|
72
|
+
|
72
73
|
def call(env) ## mimick sbsm/lib/app.rb
|
73
74
|
request = Rack::Request.new(env)
|
74
75
|
response = Rack::Response.new
|
75
|
-
if request.cookies[
|
76
|
-
session_id = request.cookies[
|
76
|
+
if request.cookies[SESSION_ID] && request.cookies[SESSION_ID].length > 1
|
77
|
+
session_id = request.cookies[SESSION_ID]
|
77
78
|
else
|
78
79
|
session_id = rand((2**(0.size * 8 -2) -1)*10240000000000).to_s(16)
|
79
80
|
end
|
80
|
-
|
81
81
|
file_name = File.expand_path(File.join('doc', request.path))
|
82
82
|
if File.file?(file_name)
|
83
83
|
mime_type = MimeMagic.by_extension(File.extname(file_name)).type
|
@@ -88,26 +88,31 @@ module SBSM
|
|
88
88
|
end
|
89
89
|
|
90
90
|
return [400, {}, []] if /favicon.ico/i.match(request.path)
|
91
|
-
SBSM.debug "#{request.path}: cookies are #{request.cookies} for session_id #{session_id}"
|
92
91
|
@drb_uri ||= @app.drb_uri
|
93
92
|
args = {
|
94
93
|
'database_manager' => CGI::Session::DRbSession,
|
95
94
|
'drbsession_uri' => @drb_uri,
|
96
95
|
'session_path' => '/',
|
97
|
-
|
96
|
+
@cookie_name => session_id,
|
98
97
|
}
|
99
|
-
@
|
100
|
-
@
|
98
|
+
SBSM.debug "starting session_id #{session_id} #{request.path}: cookies #{@cookie_name} are #{request.cookies} @session #{@session.class} @cgi #{@cgi.class}"
|
99
|
+
@cgi = CGI.initialize_without_offline_prompt('html4') unless @cgi
|
100
|
+
@session = CGI::Session.new(@cgi, args) unless @session
|
101
101
|
saved = self[session_id]
|
102
|
-
@proxy = DRbObject.new(saved, server_uri)
|
102
|
+
@proxy = DRbObject.new(saved, server_uri) unless @proxy.is_a?(DRbObject)
|
103
103
|
@proxy.trans_handler = @trans_handler
|
104
|
-
@proxy.app = @app
|
104
|
+
@proxy.app = @app unless @proxy.app
|
105
105
|
res = @proxy.drb_process(self, request)
|
106
106
|
response.write res
|
107
107
|
response.headers['Content-Type'] ||= 'text/html; charset=utf-8'
|
108
|
-
response.
|
109
|
-
|
110
|
-
|
108
|
+
response.headers.merge!(@proxy.http_headers)
|
109
|
+
if (result = response.headers.find { |k,v| /status/i.match(k) })
|
110
|
+
response.status = result.last.to_i
|
111
|
+
response.headers.delete(result.first)
|
112
|
+
end
|
113
|
+
response.set_cookie(@cookie_name, :value => @proxy.cookie_input)
|
114
|
+
response.set_cookie(SESSION_ID, :value => session_id)
|
115
|
+
SBSM.debug "finish session_id #{session_id}: header with cookies #{response.headers} from #{@proxy.cookie_input}"
|
111
116
|
response.finish
|
112
117
|
end
|
113
118
|
end
|
data/lib/sbsm/redirector.rb
CHANGED
@@ -7,6 +7,7 @@ module SBSM
|
|
7
7
|
module Redirector
|
8
8
|
def http_headers
|
9
9
|
if(redirect?)
|
10
|
+
SBSM.debug "reached Redirector::http_headers"
|
10
11
|
@redirected = @state.redirected = true
|
11
12
|
event, *args = @state.direct_event
|
12
13
|
if(args.first.is_a? Hash)
|
@@ -25,11 +26,13 @@ module SBSM
|
|
25
26
|
if(direct.is_a?(Array))
|
26
27
|
direct = direct.first
|
27
28
|
end
|
29
|
+
SBSM.debug "reached Redirector::redirect?"
|
28
30
|
direct && (@request_method != 'GET' \
|
29
31
|
|| ![direct, :sort].include?(event))
|
30
32
|
end
|
31
33
|
def to_html
|
32
34
|
if(redirect?)
|
35
|
+
SBSM.debug "reached Redirector::to_html"
|
33
36
|
''
|
34
37
|
else
|
35
38
|
super
|
data/lib/sbsm/session.rb
CHANGED
@@ -89,22 +89,23 @@ module SBSM
|
|
89
89
|
''
|
90
90
|
end
|
91
91
|
def initialize(key, app, validator=nil)
|
92
|
-
|
92
|
+
SBSM.info "initialize app #{app.class} @app is now #{@app.class} validator #{validator} th #{@trans_handler}" # drb_uri #{drb_uri}"
|
93
|
+
touch()
|
93
94
|
reset_input()
|
94
|
-
|
95
|
+
reset_cookie()
|
95
96
|
raise "Must pass key and app and validator to session" unless key && app # && validator
|
96
97
|
@app = app
|
97
98
|
@key = key
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
99
|
+
@validator = validator
|
100
|
+
@attended_states = {}
|
101
|
+
@persistent_user_input = {}
|
102
|
+
logout()
|
103
|
+
@unknown_user_class = @user.class
|
104
|
+
@variables = {}
|
104
105
|
@mutex = Mutex.new
|
105
106
|
@cgi = CGI.initialize_without_offline_prompt('html4')
|
106
107
|
SBSM.debug "session initialized #{self} key #{key} app #{app.class} #{@validator.class} th #{@trans_handler.class} with @cgi #{@cgi}"
|
107
|
-
|
108
|
+
super(app)
|
108
109
|
end
|
109
110
|
def age(now=Time.now)
|
110
111
|
now - @mtime
|
@@ -155,8 +156,7 @@ module SBSM
|
|
155
156
|
@cookie_input[key]
|
156
157
|
end
|
157
158
|
def cookie_name
|
158
|
-
|
159
|
-
nil
|
159
|
+
self::class::PERSISTENT_COOKIE_NAME
|
160
160
|
end
|
161
161
|
def default_language
|
162
162
|
self::class::DEFAULT_LANGUAGE
|
@@ -168,7 +168,6 @@ module SBSM
|
|
168
168
|
def drb_process(app, rack_request)
|
169
169
|
start = Time.now
|
170
170
|
@request_path ||= rack_request.path
|
171
|
-
SBSM.debug("rack_request #{rack_request.class} #{@request_path} #{rack_request.request_method} #{@cgi}")
|
172
171
|
rack_request.params.each { |key, val| @cgi.params.store(key, val) }
|
173
172
|
@trans_handler.translate_uri(rack_request)
|
174
173
|
html = @mutex.synchronize do
|
@@ -213,13 +212,15 @@ module SBSM
|
|
213
212
|
reset_cookie()
|
214
213
|
return if request.cookies.is_a?(DRb::DRbUnknown)
|
215
214
|
if(cuki_str = request.cookies[self::class::PERSISTENT_COOKIE_NAME])
|
216
|
-
|
217
|
-
|
218
|
-
valid = @validator.validate(key, val
|
215
|
+
SBSM.debug "cuki_str #{self::class::PERSISTENT_COOKIE_NAME} #{cuki_str}"
|
216
|
+
eval(cuki_str).each { |key, val|
|
217
|
+
valid = @validator.validate(key, val)
|
219
218
|
@cookie_input.store(key, valid)
|
220
219
|
}
|
220
|
+
SBSM.debug "@cookie_input now #{@cookie_input}"
|
221
221
|
end
|
222
222
|
end
|
223
|
+
# should matches stuff like "hash[1]"
|
223
224
|
@@hash_ptrn = /([^\[]+)((\[[^\]]+\])+)/
|
224
225
|
@@index_ptrn = /[^\[\]]+/
|
225
226
|
def import_user_input(rack_req)
|
@@ -227,25 +228,39 @@ module SBSM
|
|
227
228
|
# DRbConnectionRefused Exception. Therefore, do it only once...
|
228
229
|
return if(@user_input_imported)
|
229
230
|
hash = rack_req.env.merge rack_req.params
|
231
|
+
hash.merge! rack_req.POST if rack_req.POST
|
232
|
+
hash.delete('rack.request.form_hash')
|
233
|
+
SBSM.debug "hash has #{hash.size } items #{hash.keys}"
|
230
234
|
hash.each do |key, value|
|
231
235
|
next if /^rack\./.match(key)
|
232
236
|
index = nil
|
233
237
|
@unsafe_input.push([key.to_s.dup, value.to_s.dup])
|
234
238
|
unless(key.nil? || key.empty?)
|
239
|
+
if value.is_a?(Hash)
|
240
|
+
key_sym = key.to_sym
|
241
|
+
if @validator.validate(key_sym, value)
|
242
|
+
@valid_input[key_sym] ||= {}
|
243
|
+
value.each{ |k, v|
|
244
|
+
@valid_input[key_sym][k] = v
|
245
|
+
}
|
246
|
+
end
|
247
|
+
next
|
248
|
+
end
|
249
|
+
# Next for
|
235
250
|
if match = @@hash_ptrn.match(key)
|
236
251
|
key = match[1]
|
237
252
|
index = match[2]
|
238
|
-
#puts key
|
253
|
+
# puts "key #{key} index #{index} value #{value}"
|
239
254
|
end
|
240
255
|
key = key.intern
|
241
256
|
if(key == :confirm_pass)
|
242
257
|
pass = rack_req.params["pass"]
|
243
|
-
|
258
|
+
SBSM.debug "pass:#{pass} - confirm:#{value}"
|
244
259
|
@valid_input[key] = @valid_input[:set_pass] \
|
245
260
|
= @validator.set_pass(pass, value)
|
246
261
|
else
|
247
262
|
valid = @validator.validate(key, value)
|
248
|
-
#
|
263
|
+
# SBSM.debug "Checking #{key} -> #{value} valid #{valid.inspect} index #{index.inspect}"
|
249
264
|
if(index)
|
250
265
|
target = (@valid_input[key] ||= {})
|
251
266
|
indices = []
|
@@ -259,18 +274,11 @@ module SBSM
|
|
259
274
|
target.store(last, valid)
|
260
275
|
else
|
261
276
|
@valid_input[key] = valid
|
262
|
-
# puts "@valid_input #{key} -> #{value} valid #{valid.inspect} index #{index.inspect}"
|
263
|
-
"dummy" # Some statement is necessary here to avoid Date data loading error on Ruby 1.9.3
|
264
277
|
end
|
265
278
|
end
|
266
279
|
end
|
267
|
-
#puts "imported #{key} -> #{value} => #{@valid_input[key].inspect}"
|
268
280
|
end
|
269
281
|
@user_input_imported = true
|
270
|
-
@valid_input
|
271
|
-
#puts @unsafe_input.inspect
|
272
|
-
#puts @valid_input.inspect
|
273
|
-
#$stdout.flush
|
274
282
|
end
|
275
283
|
def infos
|
276
284
|
@state.infos if @state.respond_to?(:infos)
|
@@ -298,10 +306,10 @@ module SBSM
|
|
298
306
|
end
|
299
307
|
end
|
300
308
|
def logout
|
301
|
-
SBSM.debug "logout #{request_path.inspect} setting @state #{self::class::DEFAULT_STATE.new(self, @user)}"
|
302
309
|
__checkout
|
303
310
|
@user = @app.unknown_user()
|
304
311
|
@active_state = @state = self::class::DEFAULT_STATE.new(self, @user)
|
312
|
+
SBSM.debug "logout #{request_path.inspect} setting @state #{@state.object_id} #{@state.class} remember #{persistent_user_input(:remember).inspect}"
|
305
313
|
@state.init
|
306
314
|
@attended_states.store(@state.object_id, @state)
|
307
315
|
end
|
@@ -371,6 +379,7 @@ module SBSM
|
|
371
379
|
import_user_input(rack_request)
|
372
380
|
import_cookies(rack_request)
|
373
381
|
@state = active_state.trigger(event())
|
382
|
+
SBSM.debug "active_state.trigger state #{@state.object_id} remember #{persistent_user_input(:remember).inspect}"
|
374
383
|
#FIXME: is there a better way to distinguish returning states?
|
375
384
|
# ... we could simply refuse to init if event == :sort, but that
|
376
385
|
# would not solve the problem cleanly, I think.
|
@@ -379,9 +388,11 @@ module SBSM
|
|
379
388
|
@state.init
|
380
389
|
end
|
381
390
|
unless @state.volatile?
|
382
|
-
SBSM.debug "Changing to #{@state.
|
391
|
+
SBSM.debug "Changing from #{@active_state.object_id} to state #{@state.object_id} remember #{persistent_user_input(:remember).inspect}"
|
383
392
|
@active_state = @state
|
384
393
|
@attended_states.store(@state.object_id, @state)
|
394
|
+
else
|
395
|
+
SBSM.debug "Stay in volatile state #{@state.object_id}"
|
385
396
|
end
|
386
397
|
@zone = @active_state.zone
|
387
398
|
@active_state.touch
|
@@ -391,10 +402,10 @@ module SBSM
|
|
391
402
|
ensure
|
392
403
|
@user_input_imported = false
|
393
404
|
end
|
394
|
-
''
|
395
405
|
end
|
396
406
|
def reset
|
397
407
|
if @redirected
|
408
|
+
SBSM.debug "reached Session::reset"
|
398
409
|
@redirected = false
|
399
410
|
else
|
400
411
|
reset_input()
|
@@ -421,6 +432,7 @@ module SBSM
|
|
421
432
|
end
|
422
433
|
end
|
423
434
|
def set_cookie_input(key, val)
|
435
|
+
SBSM.debug "cookie_set_or_get #{key} #{val}"
|
424
436
|
@cookie_input.store(key, val)
|
425
437
|
end
|
426
438
|
def server_name
|
@@ -443,9 +455,6 @@ module SBSM
|
|
443
455
|
@state.to_html(cgi)
|
444
456
|
rescue DRb::DRbConnError
|
445
457
|
raise
|
446
|
-
rescue StandardError => err
|
447
|
-
SBSM.info "StandardError: #@request_path"
|
448
|
-
[ err.class, err.message ].join("\n")
|
449
458
|
end
|
450
459
|
def user_agent
|
451
460
|
@user_agent ||= (@request.user_agent if @request.respond_to?(:user_agent))
|
data/lib/sbsm/state.rb
CHANGED
@@ -175,6 +175,7 @@ module SBSM
|
|
175
175
|
end
|
176
176
|
def trigger(event)
|
177
177
|
if(@redirected)
|
178
|
+
SBSM.debug "reached State::trigger"
|
178
179
|
@redirected = false
|
179
180
|
else
|
180
181
|
@errors = {}
|
@@ -190,7 +191,6 @@ module SBSM
|
|
190
191
|
if(state.respond_to?(:previous=))
|
191
192
|
state.previous = self
|
192
193
|
end
|
193
|
-
# puts "state.rb #{__LINE__} state #{state.inspect}"
|
194
194
|
state
|
195
195
|
end
|
196
196
|
def _trigger(event)
|
@@ -264,7 +264,7 @@ module SBSM
|
|
264
264
|
aval = a.send(sortby)
|
265
265
|
bval = b.send(sortby)
|
266
266
|
rescue
|
267
|
-
warn "could not sort by #{sortby}"
|
267
|
+
SBSM.warn "could not sort by #{sortby}"
|
268
268
|
next
|
269
269
|
end
|
270
270
|
res = if (aval.nil? && bval.nil?)
|
data/lib/sbsm/trans_handler.rb
CHANGED
data/lib/sbsm/validator.rb
CHANGED
@@ -32,6 +32,7 @@ require 'drb/drb'
|
|
32
32
|
require 'uri'
|
33
33
|
require 'stringio'
|
34
34
|
require 'hpricot'
|
35
|
+
require 'sbsm/logger'
|
35
36
|
|
36
37
|
module SBSM
|
37
38
|
class InvalidDataError < RuntimeError
|
@@ -148,6 +149,7 @@ module SBSM
|
|
148
149
|
self.send(key, value)
|
149
150
|
end
|
150
151
|
rescue InvalidDataError => e
|
152
|
+
SBSM.debug("#{e.key} #{e}")
|
151
153
|
@errors.store(e.key, e)
|
152
154
|
end
|
153
155
|
end
|
data/lib/sbsm/version.rb
CHANGED
data/test/simple_sbsm.rb
CHANGED
@@ -14,6 +14,7 @@ SERVER_NAME = 'localhost:9878'
|
|
14
14
|
# Some string shared with the unit test
|
15
15
|
HOME_HTML_CONTENT = 'Überall zu Hause' # mit UTF-8!
|
16
16
|
ABOUT_HTML_CONTENT = 'About SBSM: TDD ist great!'
|
17
|
+
REDIRECT_HTML_CONTENT = 'This content should be redirected to feedback'
|
17
18
|
FEEDBACK_HTML_CONTENT = 'Give us your feedback about SBSM'
|
18
19
|
CONFIRM_HTML_CONTENT = 'Please confirm your feedback'
|
19
20
|
SENT_HTML_CONTENT = 'Thanks for you feedback! Hope to see you soon'
|
@@ -26,6 +27,7 @@ module Demo
|
|
26
27
|
EVENTS = %i{
|
27
28
|
home
|
28
29
|
about
|
30
|
+
redirect
|
29
31
|
feedback
|
30
32
|
}
|
31
33
|
STRINGS = %i{
|
@@ -38,6 +40,7 @@ module Demo
|
|
38
40
|
EVENTS = %i{
|
39
41
|
home
|
40
42
|
about
|
43
|
+
redirect
|
41
44
|
feedback
|
42
45
|
}
|
43
46
|
@@class_counter = 0
|
@@ -62,6 +65,7 @@ module Demo
|
|
62
65
|
end
|
63
66
|
end
|
64
67
|
class AboutState < GlobalState
|
68
|
+
DIRECT_EVENT = :about
|
65
69
|
def initialize(session, user)
|
66
70
|
SBSM.info "AboutState #{session}"
|
67
71
|
super(session, user)
|
@@ -70,6 +74,22 @@ module Demo
|
|
70
74
|
'About SBSM: TDD ist great!'
|
71
75
|
end
|
72
76
|
end
|
77
|
+
class RedirectState < GlobalState
|
78
|
+
DIRECT_EVENT = :redirect
|
79
|
+
def initialize(session, user)
|
80
|
+
SBSM.info "RedirectState #{session}"
|
81
|
+
super(session, user)
|
82
|
+
end
|
83
|
+
def http_headers
|
84
|
+
{
|
85
|
+
'Status' => '303 See Other',
|
86
|
+
'Location' => 'feedback',
|
87
|
+
}
|
88
|
+
end
|
89
|
+
def to_html(cgi)
|
90
|
+
REDIRECT_HTML_CONTENT
|
91
|
+
end
|
92
|
+
end
|
73
93
|
class FeedbackMail
|
74
94
|
attr_accessor :errors
|
75
95
|
attr_reader :email, :anrede, :name, :vorname, :firma, :adresse, :ort,
|
@@ -183,6 +203,7 @@ module Demo
|
|
183
203
|
GLOBAL_MAP = {
|
184
204
|
:home => Demo::HomeState,
|
185
205
|
:about => Demo::AboutState,
|
206
|
+
:redirect => Demo::RedirectState,
|
186
207
|
:feedback => Demo::FeedbackState,
|
187
208
|
}
|
188
209
|
DIRECT_EVENT = nil
|
@@ -198,10 +219,11 @@ module Demo
|
|
198
219
|
class SimpleSBSM < SBSM::App
|
199
220
|
SESSION = Session
|
200
221
|
attr_reader :drb_uri
|
201
|
-
def initialize
|
222
|
+
def initialize(cookie_name: nil)
|
202
223
|
@drb_uri = SERVER_URI
|
203
224
|
SBSM.info "SimpleSBSM.new"
|
204
|
-
super(:app => self, :validator => Validator.new, :trans_handler => SBSM::TransHandler.instance, :drb_uri => SERVER_URI
|
225
|
+
super(:app => self, :validator => Validator.new, :trans_handler => SBSM::TransHandler.instance, :drb_uri => SERVER_URI,
|
226
|
+
cookie_name: cookie_name)
|
205
227
|
end
|
206
228
|
end
|
207
229
|
end
|
data/test/test_application.rb
CHANGED
@@ -9,6 +9,7 @@ ENV['REQUEST_METHOD'] = 'GET'
|
|
9
9
|
require 'minitest/autorun'
|
10
10
|
require 'rack/test'
|
11
11
|
require 'sbsm/app'
|
12
|
+
require 'sbsm/session'
|
12
13
|
require 'simple_sbsm'
|
13
14
|
require 'nokogiri'
|
14
15
|
begin
|
@@ -16,29 +17,69 @@ begin
|
|
16
17
|
rescue LoadError
|
17
18
|
end
|
18
19
|
|
19
|
-
class
|
20
|
+
class AppVariantTest < MiniTest::Unit::TestCase
|
21
|
+
include Rack::Test::Methods
|
22
|
+
MY_COOKIE_NAME = 'test-cookie'
|
23
|
+
def setup
|
24
|
+
@@myapp = Demo::SimpleSBSM.new(cookie_name: MY_COOKIE_NAME)
|
25
|
+
SBSM.info msg = "Starting #{SERVER_URI}"
|
26
|
+
DRb.start_service(SERVER_URI, @@myapp)
|
27
|
+
sleep(0.1)
|
28
|
+
end
|
29
|
+
def teardown
|
30
|
+
DRb.stop_service
|
31
|
+
end
|
32
|
+
def app
|
33
|
+
@@myapp
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_post_feedback
|
37
|
+
get '/de/page' do # needed to set cookie
|
38
|
+
last_response.set_cookie(MY_COOKIE_NAME, :value => Hash.new('anrede' => 'value2'))
|
39
|
+
end
|
40
|
+
get '/de/page/feedback' do
|
41
|
+
end
|
42
|
+
assert_equal ["_session_id", MY_COOKIE_NAME], last_request.cookies.keys
|
43
|
+
skip "Cannot test cookie_input"
|
44
|
+
assert_equal ['anrede', 'name'], @@myapp.proxy.cookie_input.keys
|
45
|
+
assert_equal 'xxx', @@myapp.proxy.persistent_user_input(:anrede)
|
46
|
+
|
47
|
+
assert_equal ['value2', 'value3'], @@myapp.proxy.cookie_input.values
|
48
|
+
assert_match /anrede=value2/, CGI.unescape(last_response.headers['Set-Cookie'])
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
class AppTest < MiniTest::Unit::TestCase
|
20
53
|
include Rack::Test::Methods
|
21
54
|
|
22
55
|
def setup
|
56
|
+
@@myapp = Demo::SimpleSBSM.new
|
23
57
|
SBSM.info msg = "Starting #{SERVER_URI}"
|
24
|
-
DRb.start_service(SERVER_URI,
|
58
|
+
DRb.start_service(SERVER_URI, @@myapp)
|
25
59
|
sleep(0.1)
|
26
60
|
end
|
27
61
|
def teardown
|
28
62
|
DRb.stop_service
|
29
63
|
end
|
30
64
|
def app
|
31
|
-
|
65
|
+
@@myapp
|
32
66
|
end
|
33
67
|
def test_post_feedback
|
34
68
|
get '/de/page' do # needed to set cookie
|
35
|
-
|
69
|
+
last_response.set_cookie(SBSM::Session::PERSISTENT_COOKIE_NAME, :value => Hash.new('anrede' => 'value2', 'name' => 'values'))
|
36
70
|
end
|
37
71
|
get '/de/page/feedback' do
|
38
|
-
last_response.set_cookie SBSM::App::PERSISTENT_COOKIE_NAME, :value => "second_cookie"
|
39
72
|
end
|
73
|
+
# assert_match /anrede.*=.*value2/, CGI.unescape(last_response.headers['Set-Cookie'])
|
40
74
|
assert last_response.ok?
|
75
|
+
assert_equal ["_session_id", SBSM::Session::PERSISTENT_COOKIE_NAME], last_request.cookies.keys
|
76
|
+
skip "Cannot test cookie_input"
|
77
|
+
assert_match /anrede.*=.*value2/, CGI.unescape(last_response.headers['Set-Cookie'])
|
41
78
|
assert_match FEEDBACK_HTML_CONTENT, last_response.body
|
79
|
+
assert_equal ['anrede'], @@myapp.proxy.cookie_input.keys
|
80
|
+
assert_equal ['value2'], @@myapp.proxy.cookie_input.values
|
81
|
+
assert_equal ['anrede', 'name'], @@myapp.proxy.cookie_input.keys
|
82
|
+
assert_equal ['value2', 'value3'], @@myapp.proxy.cookie_input.values
|
42
83
|
page = Nokogiri::HTML(last_response.body)
|
43
84
|
x = page.css('div')
|
44
85
|
skip 'We must add here an input form or we cannot continue testing'
|
@@ -54,7 +95,7 @@ class MyTest < MiniTest::Unit::TestCase
|
|
54
95
|
assert last_response.ok?
|
55
96
|
assert_match CONFIRM_DONE_HTML_CONTENT, last_response.body
|
56
97
|
end
|
57
|
-
|
98
|
+
|
58
99
|
def test_session_home
|
59
100
|
get '/home'
|
60
101
|
assert last_response.ok?
|
@@ -62,6 +103,15 @@ class MyTest < MiniTest::Unit::TestCase
|
|
62
103
|
assert_match HOME_HTML_CONTENT, last_response.body
|
63
104
|
assert_match /utf-8/i, last_response.headers['Content-Type']
|
64
105
|
end
|
106
|
+
|
107
|
+
def test_session_redirect
|
108
|
+
get '/de/page/redirect'
|
109
|
+
assert_equal 303,last_response.status
|
110
|
+
assert_equal 'feedback',last_response.headers['Location']
|
111
|
+
assert_match REDIRECT_HTML_CONTENT, last_response.body
|
112
|
+
assert_match /utf-8/i, last_response.headers['Content-Type']
|
113
|
+
end
|
114
|
+
|
65
115
|
def test_css_file
|
66
116
|
css_content = "html { max-width: 960px; margin: 0 auto; }"
|
67
117
|
css_file = File.join('doc/sbsm.css')
|
@@ -79,7 +129,7 @@ class MyTest < MiniTest::Unit::TestCase
|
|
79
129
|
get '/de/page/about'
|
80
130
|
assert last_response.ok?
|
81
131
|
assert_match /^About SBSM: TDD ist great!/, last_response.body
|
82
|
-
get '/home'
|
132
|
+
get '/de/page/home'
|
83
133
|
assert last_response.ok?
|
84
134
|
assert_match HOME_HTML_CONTENT, last_response.body
|
85
135
|
end
|
@@ -102,12 +152,11 @@ class MyTest < MiniTest::Unit::TestCase
|
|
102
152
|
m = /class_counter is (\d+)$/.match(body)
|
103
153
|
counter = m[1]
|
104
154
|
assert_match /class_counter is (\d+)$/, body
|
105
|
-
# Getting the request a second time must increment the class, but not the member counter
|
106
155
|
get '/'
|
107
156
|
assert last_response.ok?
|
108
157
|
body = last_response.body.clone
|
109
158
|
assert_match /^request_path is \/$/, body
|
110
|
-
assert_match /member_counter is
|
159
|
+
assert_match /member_counter is 2$/, body
|
111
160
|
assert_match /class_counter is #{counter.to_i+1}$/, body
|
112
161
|
end
|
113
162
|
def test_session_home_then_fr_about
|
@@ -119,5 +168,9 @@ class MyTest < MiniTest::Unit::TestCase
|
|
119
168
|
assert last_response.ok?
|
120
169
|
assert_match ABOUT_HTML_CONTENT, last_response.body
|
121
170
|
end
|
171
|
+
|
172
|
+
def test_show_stats
|
173
|
+
# We add it here to get some more or less useful statistics
|
174
|
+
Session.show_stats '/de/page'
|
122
175
|
end
|
123
176
|
end
|
data/test/test_session.rb
CHANGED
@@ -27,6 +27,7 @@
|
|
27
27
|
|
28
28
|
require 'minitest/autorun'
|
29
29
|
require 'sbsm/session'
|
30
|
+
require 'sbsm/validator'
|
30
31
|
require 'rack'
|
31
32
|
require 'rack/test'
|
32
33
|
|
@@ -58,8 +59,8 @@ class StubSessionValidator
|
|
58
59
|
end
|
59
60
|
end
|
60
61
|
class StubSessionRequest < Rack::Request
|
61
|
-
def initialize(path='')
|
62
|
-
super(Rack::MockRequest.env_for("http://example.com:8080/#{path}",
|
62
|
+
def initialize(path='', params = {})
|
63
|
+
super(Rack::MockRequest.env_for("http://example.com:8080/#{path}", params))
|
63
64
|
end
|
64
65
|
end
|
65
66
|
class StubSessionView
|
@@ -136,7 +137,8 @@ class TestSession < Minitest::Test
|
|
136
137
|
def test_user_input_hash
|
137
138
|
@request["hash[1]"] = "4"
|
138
139
|
@request["hash[2]"] = "5"
|
139
|
-
@request["hash[3]"] = "6"
|
140
|
+
@request.params["hash[3]"] = "6"
|
141
|
+
@request.params['real_hash'] = {'1' => 'a', '2' => 'b'}
|
140
142
|
@session.process(@request)
|
141
143
|
hash = @session.user_input(:hash)
|
142
144
|
assert_equal(Hash, hash.class)
|
@@ -144,6 +146,10 @@ class TestSession < Minitest::Test
|
|
144
146
|
assert_equal("4", hash["1"])
|
145
147
|
assert_equal("5", hash["2"])
|
146
148
|
assert_equal("6", hash["3"])
|
149
|
+
real_hash = @session.user_input(:real_hash)
|
150
|
+
assert_equal(Hash, real_hash.class)
|
151
|
+
assert_equal(2, real_hash.size)
|
152
|
+
assert_equal("b", real_hash['2'])
|
147
153
|
end
|
148
154
|
def test_attended_states_store
|
149
155
|
@session.process(@request)
|
@@ -364,7 +370,7 @@ class TestSession < Minitest::Test
|
|
364
370
|
assert_equal('en', lnf3.language) ## flavor does not change!
|
365
371
|
end
|
366
372
|
def test_lookandfeel2
|
367
|
-
|
373
|
+
session = StubSessionSession.new("test", StubSessionApp.new, StubSessionValidator.new)
|
368
374
|
session.lookandfeel=nil
|
369
375
|
session.persistent_user_input = {
|
370
376
|
:flavor => 'gcc',
|
@@ -372,7 +378,7 @@ class TestSession < Minitest::Test
|
|
372
378
|
lnf = session.lookandfeel
|
373
379
|
assert_equal('gcc', session.flavor)
|
374
380
|
end
|
375
|
-
|
381
|
+
def test_lookandfeel3
|
376
382
|
session = StubSessionSession.new("test", StubSessionApp.new, StubSessionValidator.new)
|
377
383
|
session.lookandfeel=nil
|
378
384
|
lnf2 = session.lookandfeel
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sbsm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
4
|
+
version: 1.3.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Masaomi Hatakeyama, Zeno R.R. Davatz
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-12-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|