tynn 1.4.0 → 2.0.0.alpha

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,27 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "helper"
1
4
  require_relative "../lib/tynn/secure_headers"
2
5
 
3
- test "secure headers" do
4
- Tynn.plugin(Tynn::SecureHeaders)
6
+ class SecureHeadersTest < Minitest::Test
7
+ HEADERS = Tynn::SecureHeaders::HEADERS
8
+
9
+ def setup
10
+ @app = Class.new(Tynn)
11
+ end
12
+
13
+ def test_dont_override_default_headers
14
+ @app.set(:default_headers, "Content-Type" => "application/json")
15
+
16
+ @app.plugin(Tynn::SecureHeaders)
17
+
18
+ assert @app.default_headers.key?("Content-Type")
19
+ end
20
+
21
+ def test_dont_override_if_exists
22
+ @app.set(:default_headers, "X-Frame-Options" => "DENY")
23
+
24
+ @app.plugin(Tynn::SecureHeaders)
5
25
 
6
- Tynn.define do
7
- root do
8
- res.write("safe")
9
- end
26
+ assert_equal "DENY", @app.default_headers["X-Frame-Options"]
10
27
  end
11
28
 
12
- app = Tynn::Test.new
13
- app.get("/")
29
+ def test_respond_with_secure_headers
30
+ @app.plugin(Tynn::SecureHeaders)
14
31
 
15
- secure_headers = {
16
- "X-Content-Type-Options" => "nosniff",
17
- "X-Frame-Options" => "SAMEORIGIN",
18
- "X-Permitted-Cross-Domain-Policies" => "none",
19
- "X-XSS-Protection" => "1; mode=block"
20
- }
32
+ @app.define {}
21
33
 
22
- headers = app.res.headers
34
+ ts = Tynn::Test.new(@app)
35
+ ts.get("/")
23
36
 
24
- secure_headers.each do |header, value|
25
- assert_equal(value, headers[header])
37
+ assert_equal HEADERS, ts.res.headers
26
38
  end
27
39
  end
@@ -1,20 +1,53 @@
1
- require "securerandom"
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "helper"
2
4
  require_relative "../lib/tynn/session"
3
5
 
4
- test "session" do
5
- Tynn.plugin(Tynn::Session, secret: SecureRandom.hex(64))
6
+ class SessionTest < Minitest::Test
7
+ def setup
8
+ @app = Class.new(Tynn)
9
+ end
10
+
11
+ def test_raise_error_if_secret_is_empty
12
+ assert_raises { @app.plugin(Tynn::Session) }
13
+ end
14
+
15
+ def test_raise_error_if_secret_is_short
16
+ assert_raises { @app.plugin(Tynn::Session, secret: "__not_secure__") }
17
+ end
18
+
19
+ def test_set_and_get_session
20
+ @app.plugin(Tynn::Session, secret: SecureRandom.hex(64))
6
21
 
7
- Tynn.define do
8
- root do
9
- session[:foo] = "foo"
22
+ @app.define do
23
+ get do
24
+ session[:foo] = "foo"
10
25
 
11
- res.write(session[:foo])
26
+ res.write(session[:foo])
27
+ end
12
28
  end
29
+
30
+ ts = Tynn::Test.new(@app)
31
+ ts.get("/")
32
+
33
+ assert_equal "foo", ts.res.body
34
+ assert_equal "foo", ts.req.session["foo"]
13
35
  end
14
36
 
15
- app = Tynn::Test.new
16
- app.get("/")
37
+ def test_set_same_site_attribute
38
+ @app.plugin(Tynn::Session, secret: SecureRandom.hex(64))
39
+
40
+ @app.define do
41
+ get do
42
+ session[:foo] = "foo"
43
+ end
44
+ end
17
45
 
18
- assert_equal "foo", app.res.body
19
- assert_equal "foo", app.req.env["rack.session"]["foo"]
46
+ ts = Tynn::Test.new(@app)
47
+ ts.get("/")
48
+
49
+ cookie = ts.res.headers["Set-Cookie"]
50
+
51
+ assert_match(/; SameSite=Lax/, cookie)
52
+ end
20
53
  end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "helper"
4
+
5
+ class SettingsTest < Minitest::Test
6
+ def setup
7
+ @app = Class.new(Tynn)
8
+ end
9
+
10
+ def test_set_and_get
11
+ @app.set(:foo, "foo")
12
+
13
+ assert_equal "foo", @app.settings[:foo]
14
+ end
15
+
16
+ def test_set_hash
17
+ @app.set(:foo, bar: "bar")
18
+
19
+ assert_equal "bar", @app.settings[:foo][:bar]
20
+ end
21
+
22
+ def test_set_hash_with_merge
23
+ @app.set(:foo, foo: "foo", bar: "bar")
24
+ @app.set(:foo, bar: "foo", baz: "baz")
25
+
26
+ assert_equal "foo", @app.settings[:foo][:foo]
27
+ assert_equal "foo", @app.settings[:foo][:bar]
28
+ assert_equal "baz", @app.settings[:foo][:baz]
29
+ end
30
+
31
+ def test_set_hash_without_merge
32
+ @app.set(:foo, bar: "bar")
33
+ @app.set!(:foo, baz: "baz")
34
+
35
+ assert_equal nil, @app.settings[:foo][:bar]
36
+ assert_equal "baz", @app.settings[:foo][:baz]
37
+ end
38
+
39
+ def test_inheritance
40
+ @app.set(:foo, "foo")
41
+
42
+ @child1 = Class.new(@app)
43
+ @child2 = Class.new(@child1)
44
+
45
+ assert_equal "foo", @child1.settings[:foo]
46
+ assert_equal "foo", @child2.settings[:foo]
47
+
48
+ @child2.set(:foo, "bar")
49
+
50
+ assert_equal "foo", @child1.settings[:foo]
51
+ assert_equal "bar", @child2.settings[:foo]
52
+ end
53
+ end
@@ -1,60 +1,132 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "helper"
1
4
  require_relative "../lib/tynn/ssl"
2
5
 
3
- setup do
4
- Tynn::Test.new
5
- end
6
+ class SSLTest < Minitest::Test
7
+ def setup
8
+ @app = Class.new(Tynn)
9
+ end
10
+
11
+ def test_redirect_to_https
12
+ @app.plugin(Tynn::SSL)
13
+
14
+ @app.define {}
6
15
 
7
- test "redirects to https" do |app|
8
- Tynn.plugin(Tynn::SSL)
16
+ ts = Tynn::Test.new(@app)
17
+ ts.get("/")
9
18
 
10
- Tynn.define do
19
+ assert_equal 301, ts.res.status
20
+ assert_equal "https://example.org/", ts.res.location
11
21
  end
12
22
 
13
- app.get("/")
23
+ def test_redirect_port_80
24
+ @app.plugin(Tynn::SSL)
14
25
 
15
- assert_equal 301, app.res.status
16
- assert_equal "https://example.org/", app.res.location
17
- end
26
+ @app.define {}
18
27
 
19
- test "https request" do |app|
20
- Tynn.plugin(Tynn::SSL)
28
+ ts = Tynn::Test.new(@app)
29
+ ts.get("/", {}, "HTTP_HOST" => "example.org:80")
21
30
 
22
- Tynn.define do
23
- root do
24
- res.write("secure")
25
- end
31
+ assert_equal 301, ts.res.status
32
+ assert_equal "https://example.org/", ts.res.location
26
33
  end
27
34
 
28
- app.get("/", {}, "HTTPS" => "on")
35
+ def test_redirect_port_443
36
+ @app.plugin(Tynn::SSL)
29
37
 
30
- assert_equal 200, app.res.status
31
- assert_equal "secure", app.res.body
32
- end
38
+ @app.define {}
33
39
 
34
- test "hsts header" do |app|
35
- Tynn.plugin(Tynn::SSL)
40
+ ts = Tynn::Test.new(@app)
41
+ ts.get("/", {}, "HTTP_HOST" => "example.org:443")
36
42
 
37
- Tynn.define do
43
+ assert_equal 301, ts.res.status
44
+ assert_equal "https://example.org/", ts.res.location
38
45
  end
39
46
 
40
- app = Tynn::Test.new
41
- app.get("/", {}, "HTTPS" => "on")
47
+ def test_redirect_to_non_default_port
48
+ @app.plugin(Tynn::SSL)
42
49
 
43
- header = app.res.headers["Strict-Transport-Security"]
50
+ @app.define {}
44
51
 
45
- assert_equal "max-age=15552000; includeSubdomains", header
46
- end
52
+ ts = Tynn::Test.new(@app)
53
+ ts.get("/", {}, "HTTP_HOST" => "example.org:4567")
47
54
 
48
- test "hsts header options" do |app|
49
- Tynn.plugin(Tynn::SSL, hsts: { expires: 1, subdomains: false, preload: true })
55
+ assert_equal 301, ts.res.status
56
+ assert_equal "https://example.org:4567/", ts.res.location
57
+ end
58
+
59
+ def test_accept_safe_request
60
+ @app.plugin(Tynn::SSL)
61
+
62
+ @app.define { res.write("secure") }
50
63
 
51
- Tynn.define do
64
+ ts = Tynn::Test.new(@app)
65
+ ts.get("/", {}, "HTTPS" => "on")
66
+
67
+ assert_equal 200, ts.res.status
68
+ assert_equal "secure", ts.res.body
52
69
  end
53
70
 
54
- app = Tynn::Test.new
55
- app.get("/", {}, "HTTPS" => "on")
71
+ def test_set_hsts_header_with_defaults
72
+ @app.plugin(Tynn::SSL)
73
+
74
+ @app.define {}
75
+
76
+ ts = Tynn::Test.new(@app)
77
+ ts.get("/", {}, "HTTPS" => "on")
78
+
79
+ header = ts.res.headers["Strict-Transport-Security"]
80
+
81
+ assert_equal "max-age=15552000; includeSubdomains", header
82
+ end
56
83
 
57
- header = app.res.headers["Strict-Transport-Security"]
84
+ def test_set_hsts_header_with_options
85
+ @app.plugin(Tynn::SSL, hsts: {
86
+ expires: 1, subdomains: false, preload: true
87
+ })
58
88
 
59
- assert_equal "max-age=1; preload", header
89
+ @app.define {}
90
+
91
+ ts = Tynn::Test.new(@app)
92
+ ts.get("/", {}, "HTTPS" => "on")
93
+
94
+ header = ts.res.headers["Strict-Transport-Security"]
95
+
96
+ assert_equal "max-age=1; preload", header
97
+ end
98
+
99
+ def test_disable_hsts
100
+ @app.plugin(Tynn::SSL, hsts: false)
101
+
102
+ @app.define {}
103
+
104
+ ts = Tynn::Test.new(@app)
105
+ ts.get("/", {}, "HTTPS" => "on")
106
+
107
+ header = ts.res.headers["Strict-Transport-Security"]
108
+
109
+ assert_equal "max-age=0; includeSubdomains", header
110
+ end
111
+
112
+ def test_set_secure_flag
113
+ @app.plugin(Tynn::SSL, hsts: false)
114
+
115
+ @app.define do
116
+ get do
117
+ res.set_cookie("first", "cookie", secure: false)
118
+ res.set_cookie("other", "cookie", http_only: true)
119
+ res.set_cookie("secure", "cookie", secure: true)
120
+ end
121
+ end
122
+
123
+ ts = Tynn::Test.new(@app)
124
+ ts.get("/", {}, "HTTPS" => "on")
125
+
126
+ first, other, secure = ts.res.headers["Set-Cookie"].split("\n")
127
+
128
+ assert_equal "first=cookie; secure", first
129
+ assert_equal "other=cookie; HttpOnly; secure", other
130
+ assert_equal "secure=cookie; secure", secure
131
+ end
60
132
  end
@@ -1,13 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "helper"
1
4
  require_relative "../lib/tynn/static"
2
5
 
3
- test "static" do
4
- Tynn.plugin(Tynn::Static, %w(/test), root: Dir.pwd)
6
+ class StaticTest < Minitest::Test
7
+ def setup
8
+ @app = Class.new(Tynn)
9
+ end
10
+
11
+ def test_serve_static_files_ok
12
+ @app.plugin(Tynn::Static, ["/test"], root: Dir.pwd)
13
+
14
+ @app.define {}
5
15
 
6
- Tynn.define do
16
+ ts = Tynn::Test.new(@app)
17
+ ts.get("/test/static_test.rb")
18
+
19
+ assert_equal 200, ts.res.status
7
20
  end
8
21
 
9
- app = Tynn::Test.new
10
- app.get("/test/static_test.rb")
22
+ def test_serve_static_files_not_found
23
+ @app.plugin(Tynn::Static, ["/test"], root: Dir.pwd)
24
+
25
+ @app.define {}
11
26
 
12
- assert_equal File.read(__FILE__), app.res.body
27
+ ts = Tynn::Test.new(@app)
28
+ ts.get("/test/file_not_exists.rb")
29
+
30
+ assert_equal 404, ts.res.status
31
+ end
13
32
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tynn
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 2.0.0.alpha
5
5
  platform: ruby
6
6
  authors:
7
- - Francesco Rodríguez
7
+ - Francesco Rodriguez
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-19 00:00:00.000000000 Z
11
+ date: 2016-05-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -16,70 +16,70 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.6'
19
+ version: 2.x
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.6'
26
+ version: 2.x
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: syro
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '1.1'
33
+ version: '2.1'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '1.1'
40
+ version: '2.1'
41
41
  - !ruby/object:Gem::Dependency
42
- name: cutest
42
+ name: erubis
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '1.2'
47
+ version: '2.7'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '1.2'
54
+ version: '2.7'
55
55
  - !ruby/object:Gem::Dependency
56
- name: erubis
56
+ name: minitest
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '2.7'
61
+ version: '5.8'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '2.7'
68
+ version: '5.8'
69
69
  - !ruby/object:Gem::Dependency
70
- name: hmote
70
+ name: rake
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '1.4'
75
+ version: '11.0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '1.4'
82
+ version: '11.0'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: tilt
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -94,9 +94,8 @@ dependencies:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: '2.0'
97
- description: Thin library to create web applications
98
- email:
99
- - frodsan@protonmail.ch
97
+ description: A thin library for web development in Ruby
98
+ email: hello@frodsan.com
100
99
  executables: []
101
100
  extensions: []
102
101
  extra_rdoc_files: []
@@ -104,12 +103,10 @@ files:
104
103
  - LICENSE
105
104
  - README.md
106
105
  - lib/tynn.rb
107
- - lib/tynn/all_methods.rb
106
+ - lib/tynn/base.rb
107
+ - lib/tynn/default_headers.rb
108
108
  - lib/tynn/environment.rb
109
- - lib/tynn/hmote.rb
110
109
  - lib/tynn/json.rb
111
- - lib/tynn/not_found.rb
112
- - lib/tynn/protection.rb
113
110
  - lib/tynn/render.rb
114
111
  - lib/tynn/request.rb
115
112
  - lib/tynn/response.rb
@@ -120,19 +117,18 @@ files:
120
117
  - lib/tynn/static.rb
121
118
  - lib/tynn/test.rb
122
119
  - lib/tynn/version.rb
123
- - test/all_methods_test.rb
124
- - test/core_test.rb
125
120
  - test/default_headers_test.rb
126
121
  - test/environment_test.rb
127
122
  - test/helper.rb
128
- - test/hmote_test.rb
129
123
  - test/json_test.rb
130
124
  - test/middleware_test.rb
131
- - test/not_found_test.rb
132
- - test/protection_test.rb
125
+ - test/plugin_test.rb
133
126
  - test/render_test.rb
127
+ - test/request_headers_test.rb
128
+ - test/routing_test.rb
134
129
  - test/secure_headers_test.rb
135
130
  - test/session_test.rb
131
+ - test/settings_test.rb
136
132
  - test/ssl_test.rb
137
133
  - test/static_test.rb
138
134
  homepage: https://github.com/frodsan/tynn
@@ -147,31 +143,30 @@ required_ruby_version: !ruby/object:Gem::Requirement
147
143
  requirements:
148
144
  - - ">="
149
145
  - !ruby/object:Gem::Version
150
- version: '0'
146
+ version: 2.3.0
151
147
  required_rubygems_version: !ruby/object:Gem::Requirement
152
148
  requirements:
153
- - - ">="
149
+ - - ">"
154
150
  - !ruby/object:Gem::Version
155
- version: '0'
151
+ version: 1.3.1
156
152
  requirements: []
157
153
  rubyforge_project:
158
- rubygems_version: 2.4.8
154
+ rubygems_version: 2.5.1
159
155
  signing_key:
160
156
  specification_version: 4
161
- summary: Thin library to create web applications
157
+ summary: A thin library for web development in Ruby
162
158
  test_files:
163
- - test/all_methods_test.rb
164
- - test/core_test.rb
165
159
  - test/default_headers_test.rb
166
160
  - test/environment_test.rb
167
161
  - test/helper.rb
168
- - test/hmote_test.rb
169
162
  - test/json_test.rb
170
163
  - test/middleware_test.rb
171
- - test/not_found_test.rb
172
- - test/protection_test.rb
164
+ - test/plugin_test.rb
173
165
  - test/render_test.rb
166
+ - test/request_headers_test.rb
167
+ - test/routing_test.rb
174
168
  - test/secure_headers_test.rb
175
169
  - test/session_test.rb
170
+ - test/settings_test.rb
176
171
  - test/ssl_test.rb
177
172
  - test/static_test.rb