roda-rest_api 1.4.5 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,61 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+ # stub: roda-rest_api 2.0.1 ruby lib
6
+
7
+ Gem::Specification.new do |s|
8
+ s.name = "roda-rest_api"
9
+ s.version = "2.0.1"
10
+
11
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
+ s.require_paths = ["lib"]
13
+ s.authors = ["Michel Benevento"]
14
+ s.date = "2015-06-29"
15
+ s.description = "Create restful API easily with the Roda framework"
16
+ s.email = "michelbenevento@yahoo.com"
17
+ s.extra_rdoc_files = [
18
+ "README.md"
19
+ ]
20
+ s.files = [
21
+ ".document",
22
+ "Gemfile",
23
+ "README.md",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "lib/roda/plugins/rest_api.rb",
27
+ "lib/roda/rest_api.rb",
28
+ "roda-rest_api.gemspec",
29
+ "test/rest_api_api_test.rb",
30
+ "test/rest_api_form_input_test.rb",
31
+ "test/rest_api_id_pattern_test.rb",
32
+ "test/rest_api_nested_test.rb",
33
+ "test/rest_api_perf_benchmark.rb",
34
+ "test/rest_api_permit_test.rb",
35
+ "test/rest_api_resource_test.rb",
36
+ "test/rest_api_routes_test.rb",
37
+ "test/rest_api_serialize_test.rb",
38
+ "test/rest_api_singleton_test.rb",
39
+ "test/rest_api_split_route_test.rb",
40
+ "test/rest_api_upgrade_test.rb",
41
+ "test/rest_api_wrapper_test.rb",
42
+ "test/test_helpers.rb"
43
+ ]
44
+ s.homepage = "http://github.com/beno/roda-rest_api"
45
+ s.licenses = ["MIT"]
46
+ s.rubygems_version = "2.4.5"
47
+ s.summary = "Restful resources for Roda"
48
+
49
+ if s.respond_to? :specification_version then
50
+ s.specification_version = 4
51
+
52
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
53
+ s.add_runtime_dependency(%q<roda>, ["~> 2"])
54
+ else
55
+ s.add_dependency(%q<roda>, ["~> 2"])
56
+ end
57
+ else
58
+ s.add_dependency(%q<roda>, ["~> 2"])
59
+ end
60
+ end
61
+
@@ -0,0 +1,76 @@
1
+ require "test_helpers"
2
+
3
+ class RestApiApiTest < Minitest::Test
4
+ include TestHelpers
5
+
6
+ def setup
7
+ end
8
+
9
+ def test_api_version
10
+ app :rest_api do |r|
11
+ r.api do
12
+ r.version 1 do
13
+ 'api version 1'
14
+ end
15
+ end
16
+ end
17
+ assert_equal 'api version 1', request.get('/api/v1').body
18
+ end
19
+
20
+ def test_api_version_no_path
21
+ app :rest_api do |r|
22
+ r.api(path: '') do
23
+ r.version 1 do
24
+ 'api version 1'
25
+ end
26
+ end
27
+ end
28
+ assert_equal 'api version 1', request.get('/v1').body
29
+ end
30
+
31
+ def test_api_version_subdomain
32
+ app :rest_api do |r|
33
+ r.api(subdomain: 'api') do
34
+ r.version 1 do
35
+ 'api version 1'
36
+ end
37
+ end
38
+ end
39
+ assert_equal 'api version 1', request.get('/api/v1', "HTTP_HOST" => "api.example.com").body
40
+ end
41
+
42
+ def test_api_host_fail
43
+ app :rest_api do |r|
44
+ r.api(subdomain: 'api') do
45
+ r.version 1 do
46
+ 'api version 1'
47
+ end
48
+ end
49
+ end
50
+ assert_equal 404, request.get('/api/v1', "HTTP_HOST" => "www.example.com").status
51
+ end
52
+
53
+ def test_api_path_fail
54
+ app :rest_api do |r|
55
+ r.api do
56
+ r.version 1 do
57
+ 'api version 1'
58
+ end
59
+ end
60
+ end
61
+ assert_equal 404, request.get('/v1').status
62
+ end
63
+
64
+ def test_api_path_fail2
65
+ app :rest_api do |r|
66
+ r.api do
67
+ r.resource :foo do |foo|
68
+ foo.list {[]}
69
+ end
70
+ end
71
+ end
72
+ assert_equal 404, request.get('/foo').status
73
+ end
74
+
75
+ end
76
+
@@ -0,0 +1,31 @@
1
+ require "test_helpers"
2
+
3
+ class RestApiFormInputTest < Minitest::Test
4
+ include TestHelpers
5
+
6
+ def setup
7
+ app :rest_api do |r|
8
+ r.resource :albums do |rsc|
9
+ rsc.save { |atts| Album.create_or_update(atts) }
10
+ rsc.permit :name
11
+ end
12
+ end
13
+ end
14
+
15
+ def test_create
16
+ id, name = 1, 'bar'
17
+ album = Album.new(id, name)
18
+ response = request.post('/albums', params: {name: name})
19
+ assert_equal album.to_json, response.body
20
+ assert_equal 201, response.status
21
+ end
22
+
23
+ def test_update
24
+ id, name = 12, 'foo'
25
+ album = Album.new(id, name)
26
+ assert_equal album.to_json, request.patch('/albums/12', params: {id: id, name: name}).body
27
+ assert_equal album.to_json, request.put('/albums/12', params: {id: id, name: name}).body
28
+ end
29
+
30
+ end
31
+
@@ -0,0 +1,56 @@
1
+ require "test_helpers"
2
+
3
+ class RestApiIdPatternTest < Minitest::Test
4
+ include TestHelpers
5
+
6
+ def setup
7
+ app :rest_api do |r|
8
+ r.api id_pattern: /id([\d]+)/ do
9
+ r.resource :artists, id_pattern: /@([\d]+)/ do |rsc|
10
+ rsc.one { |atts| "ARTIST_#{atts[:id]}" }
11
+ r.resource :songs, id_pattern: /foo([\d]+)/ do |rsc|
12
+ rsc.one { |atts| "SONG_#{atts[:id]}" }
13
+ end
14
+ r.resource :concerts do |rsc| # need to be explicit
15
+ rsc.one { |atts| "CONCERT_#{atts[:id]}" }
16
+ end
17
+ end
18
+ r.resource :venues do |rsc|
19
+ rsc.one { |atts| "VENUE_#{atts[:id]}" }
20
+ end
21
+ r.resource :albums do |rsc|
22
+ rsc.save { |atts| "SAVE_ALBUM_#{atts[:id]}" }
23
+ rsc.routes :create, :update
24
+ end
25
+
26
+ end
27
+ end
28
+ end
29
+
30
+ def test_complex_pattern
31
+ assert_equal "SAVE_ALBUM_12", request.put('api/albums/id12', params:{foo:'bar'}).body
32
+ end
33
+
34
+ def test_failing_pattern
35
+ assert_equal 404, request.get('api/albums/12').status
36
+ end
37
+
38
+ def test_pattern_override
39
+ assert_equal "ARTIST_12", request.get('api/artists/@12').body
40
+ end
41
+
42
+ def test_nested
43
+ assert_equal "SONG_4", request.get('api/artists/@12/songs/foo4').body
44
+ end
45
+
46
+ def test_nested_fallback
47
+ assert_equal "CONCERT_3", request.get('api/artists/@12/concerts/@3').body
48
+ end
49
+
50
+ def test_fallback
51
+ assert_equal "VENUE_5", request.get('api/venues/id5').body
52
+ end
53
+
54
+
55
+
56
+ end
@@ -0,0 +1,105 @@
1
+ require "test_helpers"
2
+
3
+ class RestApiNestedTest < Minitest::Test
4
+ include TestHelpers
5
+
6
+ def setup
7
+ app :rest_api do |r|
8
+ r.resource :albums do |albums|
9
+ albums.list { |params| Album.find({} ) }
10
+ albums.one { |params| Album[params[:id]] }
11
+ albums.routes :index, :show
12
+ r.resource :songs do |songs|
13
+ songs.list { |params| Song.find({ :album_id => params[:parent_id]} ) }
14
+ songs.one { |params| Song[params[:id]] }
15
+ songs.routes :index, :show
16
+ end
17
+ r.resource :settings, singleton: true do |settings|
18
+ settings.one { |params| Settings[3] }
19
+ settings.save { |atts| Settings[3].save(atts) }
20
+ settings.routes :show, :update
21
+ settings.permit :name
22
+ end
23
+ r.resource :artwork, parent_key: :album_id do |artwork|
24
+ artwork.list { |params| Artwork.find(params) }
25
+ artwork.routes :index
26
+ end
27
+ r.resource :favorites, bare: true do |favorites|
28
+ favorites.list { |params| Favorite.find(params) }
29
+ favorites.one { |params| Favorite[params[:id]] }
30
+ favorites.routes :index, :show
31
+ r.resource :things do |things|
32
+ things.list { |params| Thing.find(params) }
33
+ things.one { |params| Thing[params[:id]] }
34
+ things.routes :index, :edit
35
+ end
36
+
37
+ end
38
+ end
39
+
40
+ end
41
+ end
42
+
43
+ def test_album_index
44
+ assert_equal Album.find({}).to_json, request.get('/albums').body
45
+ end
46
+
47
+ def test_album_show
48
+ assert_equal Album[10].to_json, request.get('/albums/10').body
49
+ end
50
+
51
+ def test_album_fail
52
+ assert_equal 404, request.get('/albums/--').status
53
+ end
54
+
55
+ def test_songs_index
56
+ assert_equal Song.find({:album_id => 12 }).to_json, request.get('/albums/12/songs').body
57
+ end
58
+
59
+ def test_songs_show
60
+ assert_equal Song[10].to_json, request.get('/albums/12/songs/10').body
61
+ end
62
+
63
+ def test_songs_fail
64
+ assert_equal 404, request.get('/albums/12/songs/--').status
65
+ end
66
+
67
+ def test_singleton_update
68
+ id, name = 3, 'bar'
69
+ settings = Settings.new(id, name)
70
+ assert_equal settings.to_json, request.patch('/albums/12/settings', input: {name: name}.to_json).body
71
+ end
72
+ #
73
+ def test_favorites_index
74
+ assert_equal Favorite.find({}).to_json, request.get('/albums/favorites').body
75
+ end
76
+
77
+ def test_favorites_show
78
+ assert_equal Favorite[7].to_json, request.get('/albums/favorites/7').body
79
+ end
80
+
81
+ def test_filtered_default
82
+ assert_equal Song.find({:album_id => 9 }).to_json, request.get('/albums/9/songs').body
83
+ end
84
+
85
+ def test_filtered_custom
86
+ assert_equal Artwork.find({:album_id => 8 }).to_json, request.get('/albums/8/artwork').body
87
+ end
88
+
89
+ def test_deep_nest_fail
90
+ assert_equal 404, request.get('/albums/favorites/4/things/3').status
91
+ end
92
+
93
+ def test_deep_nest
94
+ assert_equal Thing[3].to_json, request.get('/albums/favorites/things/3/edit').body
95
+ end
96
+
97
+
98
+ class Song < Mock ; end
99
+ class Settings < Mock ; end
100
+ class Favorite < Mock ; end
101
+ class Artwork < Mock ; end
102
+ class Thing < Mock ; end
103
+
104
+
105
+ end
@@ -0,0 +1,35 @@
1
+ require "test_helpers"
2
+ require "minitest/benchmark"
3
+
4
+ class RestApiPerformanceTest < Minitest::Benchmark
5
+ include TestHelpers
6
+
7
+ def setup
8
+ app :rest_api do |r|
9
+ r.resource :albums do |rsc|
10
+ rsc.list { |params| Album.find(params) }
11
+ rsc.one { |params| Album[params[:id]] }
12
+ rsc.save { |atts| Album.create_or_update(atts) }
13
+ rsc.routes :show, :create
14
+ end
15
+ end
16
+ end
17
+
18
+ def bench_show
19
+ assert_performance_linear 0.99 do |n|
20
+ n.times do
21
+ request.get('/albums/12').body
22
+ end
23
+ end
24
+ end
25
+
26
+ def bench_create
27
+ assert_performance_linear 0.99 do |n|
28
+ n.times do
29
+ request.post('/albums', 'rack.input' => post_args({name: 'foo'})}).body
30
+ end
31
+ end
32
+ end
33
+
34
+
35
+ end
@@ -0,0 +1,117 @@
1
+ require "test_helpers"
2
+
3
+ class RestApiPermitTest < Minitest::Test
4
+ include TestHelpers
5
+
6
+
7
+ def test_index_permitted
8
+ app :rest_api do |r|
9
+ r.resource :albums do |albums|
10
+ albums.list { |params| Album.find(params) }
11
+ albums.routes :index
12
+ albums.permit :page
13
+ end
14
+ end
15
+ params = {page: '2'}
16
+ assert_equal Album.find(params).to_json, request.get('/albums', {'QUERY_STRING' => 'page=2'}).body
17
+ end
18
+
19
+
20
+ def test_index_not_permitted
21
+ app :rest_api do |r|
22
+ r.resource :albums do |albums|
23
+ albums.list { |params| Album.find(params) }
24
+ albums.routes :index
25
+ albums.permit :page
26
+ end
27
+ end
28
+ params = {page_ct: '2'}
29
+ assert_equal Album.find({}).to_json, request.get('/albums', {'QUERY_STRING' => 'page_ct=2'}).body
30
+ end
31
+
32
+ def test_create_permitted
33
+ app :rest_api do |r|
34
+ r.resource :albums do |albums|
35
+ albums.save { |params| Album.create_or_update(params) }
36
+ albums.routes :create, :update
37
+ albums.permit :name, :price
38
+ end
39
+ end
40
+ atts = {name: 'name', price: 3}
41
+ album = Album.new(1, atts[:name], atts[:price])
42
+ assert_equal album.to_json, request.post('/albums', input: atts.to_json).body
43
+ assert_equal 201, request.post('/albums', input: atts.to_json).status
44
+ end
45
+
46
+ def test_create_not_permitted
47
+ app :rest_api do |r|
48
+ r.resource :albums do |albums|
49
+ albums.save { |params| Album.create_or_update(params) }
50
+ albums.routes :create, :update
51
+ albums.permit :name
52
+ end
53
+ end
54
+
55
+ atts = {name: 'name', price: 3}
56
+ album = Album.new(1, atts[:name])
57
+ assert_equal album.to_json, request.post('/albums', input: atts.to_json).body
58
+ end
59
+
60
+ def test_create_nested_single
61
+ app :rest_api do |r|
62
+ r.resource :albums do |albums|
63
+ albums.save { |params| Album.create_or_update(params) }
64
+ albums.routes :create, :update
65
+ albums.permit :name, {price: :amount}
66
+ end
67
+ end
68
+
69
+ atts = {name: 'name', price: {amount: 4}}
70
+ album = Album.new(1, atts[:name], atts[:price])
71
+ assert_equal album.to_json, request.post('/albums', input: atts.to_json).body
72
+ end
73
+
74
+ def test_create_nested_array
75
+ app :rest_api do |r|
76
+ r.resource :albums do |albums|
77
+ albums.save { |params| Album.create_or_update(params) }
78
+ albums.routes :create, :update
79
+ albums.permit :name, {price: [:amount, :currency, :discount]}
80
+ end
81
+ end
82
+
83
+ atts = {name: 'name', price: {amount: 4}}
84
+ album = Album.new(1, atts[:name], atts[:price])
85
+ assert_equal album.to_json, request.post('/albums', input: atts.to_json).body
86
+ end
87
+
88
+ def test_create_nested_single_not_permitted
89
+ app :rest_api do |r|
90
+ r.resource :albums do |albums|
91
+ albums.save { |params| Album.create_or_update(params) }
92
+ albums.routes :create, :update
93
+ albums.permit :name, {price: :total}
94
+ end
95
+ end
96
+
97
+ atts = {name: 'name', price: {amount: 4}}
98
+ album = Album.new(1, atts[:name], {})
99
+ assert_equal album.to_json, request.post('/albums', input: atts.to_json).body
100
+ end
101
+
102
+ def test_create_nested_array_not_permitted
103
+ app :rest_api do |r|
104
+ r.resource :albums do |albums|
105
+ albums.save { |params| Album.create_or_update(params) }
106
+ albums.routes :create, :update
107
+ albums.permit :name, {price: [:total, :currency, :discount]}
108
+ end
109
+ end
110
+
111
+ atts = {name: 'name', price: {amount: 4, currency:'foo'}}
112
+ album = Album.new(1, atts[:name], {currency:'foo'})
113
+ assert_equal album.to_json, request.post('/albums', input: atts.to_json).body
114
+ end
115
+
116
+
117
+ end