standardapi 5.0.0.4 → 5.0.0.5
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.
- checksums.yaml +4 -4
- data/lib/standard_api/controller.rb +59 -32
- data/lib/standard_api/test_case/calculate_tests.rb +11 -5
- data/lib/standard_api/test_case/create_tests.rb +16 -20
- data/lib/standard_api/test_case/destroy_tests.rb +7 -3
- data/lib/standard_api/test_case/index_tests.rb +41 -15
- data/lib/standard_api/test_case/new_tests.rb +2 -2
- data/lib/standard_api/test_case/schema_tests.rb +21 -0
- data/lib/standard_api/test_case/show_tests.rb +13 -8
- data/lib/standard_api/test_case/update_tests.rb +23 -17
- data/lib/standard_api/test_case.rb +32 -17
- data/lib/standard_api/version.rb +3 -0
- data/lib/standard_api/views/application/schema.json.jbuilder +12 -8
- data/lib/standard_api/views/application/settings.json.jbuilder +0 -0
- data/lib/standard_api.rb +1 -3
- metadata +5 -3
- data/lib/standard_api/test_case/schema_test.rb +0 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7ddf2593f95bb453a53bca52257c21509a8a4042
|
4
|
+
data.tar.gz: f589c7fb725ea99636d6a04112fe83cf0647dc26
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1ec52191db1bfbc6bb3309f33b4870e26f964402a70e21a840e8f5e22847e9be76c7f9c86be6fd65131815e1a757c5b23e9e28e3f8ad1e8d789b28500bf932e0
|
7
|
+
data.tar.gz: 746e50e142dc29c8bea3ef2e9af5351b0f0887a850ed41804bbcdfeffb5a7eab59f71757392c8b3415be237f43b17aec703a7ebfc4f6b30611bfc29370081636
|
@@ -2,26 +2,14 @@ module StandardAPI
|
|
2
2
|
module Controller
|
3
3
|
|
4
4
|
def self.included(klass)
|
5
|
-
klass.helper_method :includes, :orders, :model
|
5
|
+
klass.helper_method :includes, :orders, :model, :resource_limit
|
6
|
+
klass.before_action :set_standardapi_headers
|
6
7
|
klass.append_view_path(File.join(File.dirname(__FILE__), 'views'))
|
7
8
|
klass.extend(ClassMethods)
|
8
9
|
end
|
9
|
-
|
10
|
-
def ping
|
11
|
-
render plain: 'pong'
|
12
|
-
end
|
13
|
-
|
14
|
-
def tables
|
15
|
-
controllers = Dir[Rails.root.join('app/controllers/*_controller.rb')].map{ |path| path.match(/(\w+)_controller.rb/)[1].camelize+"Controller" }.map(&:safe_constantize)
|
16
|
-
controllers.select! { |c| c.ancestors.include?(self.class) && c != self.class }
|
17
|
-
controllers.map!(&:model).compact!
|
18
|
-
controllers.map!(&:table_name)
|
19
|
-
|
20
|
-
render json: controllers
|
21
|
-
end
|
22
10
|
|
23
11
|
def index
|
24
|
-
instance_variable_set("@#{model.model_name.plural}", resources.limit(
|
12
|
+
instance_variable_set("@#{model.model_name.plural}", resources.limit(limit).offset(params[:offset]).sort(orders))
|
25
13
|
end
|
26
14
|
|
27
15
|
def calculate
|
@@ -94,33 +82,45 @@ module StandardAPI
|
|
94
82
|
@model = name.sub(/Controller\z/, '').singularize.camelize.safe_constantize
|
95
83
|
end
|
96
84
|
|
85
|
+
def model_includes
|
86
|
+
if self.respond_to?("#{model.model_name.singular}_includes", true)
|
87
|
+
self.send "#{model.model_name.singular}_includes"
|
88
|
+
else
|
89
|
+
[]
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def model_orders
|
94
|
+
if self.respond_to?("#{model.model_name.singular}_orders", true)
|
95
|
+
self.send "#{model.model_name.singular}_orders"
|
96
|
+
else
|
97
|
+
[]
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
97
101
|
end
|
98
|
-
|
102
|
+
|
99
103
|
private
|
100
104
|
|
101
|
-
def
|
102
|
-
|
105
|
+
def set_standardapi_headers
|
106
|
+
headers['StandardAPI-Version'] = StandardAPI::VERSION
|
103
107
|
end
|
104
108
|
|
105
|
-
def
|
106
|
-
|
107
|
-
params.require(model.model_name.singular).permit(self.send("#{model.model_name.singular}_params"))
|
108
|
-
else
|
109
|
-
[]
|
110
|
-
end
|
109
|
+
def model
|
110
|
+
self.class.model
|
111
111
|
end
|
112
112
|
|
113
113
|
def model_includes
|
114
|
-
|
115
|
-
self.send "#{model.model_name.singular}_includes"
|
116
|
-
else
|
117
|
-
[]
|
118
|
-
end
|
114
|
+
self.class.model_includes
|
119
115
|
end
|
120
116
|
|
121
117
|
def model_orders
|
122
|
-
|
123
|
-
|
118
|
+
self.class.model_orders
|
119
|
+
end
|
120
|
+
|
121
|
+
def model_params
|
122
|
+
if self.respond_to?("#{model.model_name.singular}_params", true)
|
123
|
+
params.require(model.model_name.singular).permit(self.send("#{model.model_name.singular}_params"))
|
124
124
|
else
|
125
125
|
[]
|
126
126
|
end
|
@@ -140,7 +140,15 @@ module StandardAPI
|
|
140
140
|
end
|
141
141
|
|
142
142
|
def resources
|
143
|
-
model.filter(params[:where]).filter(current_mask[model.table_name])
|
143
|
+
query = model.filter(params[:where]).filter(current_mask[model.table_name])
|
144
|
+
|
145
|
+
if params[:distinct_on]
|
146
|
+
query.distinct_on(params[:distinct_on])
|
147
|
+
elsif params[:distinct]
|
148
|
+
query.distinct
|
149
|
+
else
|
150
|
+
query
|
151
|
+
end
|
144
152
|
end
|
145
153
|
|
146
154
|
def includes
|
@@ -185,6 +193,25 @@ module StandardAPI
|
|
185
193
|
@excludes ||= model_excludes
|
186
194
|
end
|
187
195
|
|
196
|
+
# The maximum number of results returned by #index
|
197
|
+
def resource_limit
|
198
|
+
1000
|
199
|
+
end
|
200
|
+
|
201
|
+
def limit
|
202
|
+
if resource_limit
|
203
|
+
limit = params.require(:limit).to_i
|
204
|
+
|
205
|
+
if limit > resource_limit
|
206
|
+
raise ActionController::UnpermittedParameters.new([:limit, limit])
|
207
|
+
end
|
208
|
+
|
209
|
+
limit
|
210
|
+
else
|
211
|
+
params.permit(:limit)[:limit]
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
188
215
|
# Used in #calculate
|
189
216
|
# [{ count: :id }]
|
190
217
|
# [{ count: '*' }]
|
@@ -7,9 +7,10 @@ module StandardAPI
|
|
7
7
|
create_model
|
8
8
|
selects = [{ count: :id}, { maximum: :id }, { minimum: :id }, { average: :id }]
|
9
9
|
|
10
|
-
get :calculate,
|
10
|
+
get resource_path(:calculate, select: selects, format: :json)
|
11
11
|
assert_response :ok
|
12
|
-
|
12
|
+
calculations = @controller.instance_variable_get('@calculations')
|
13
|
+
assert_equal [[model.count(:id), model.maximum(:id), model.minimum(:id), model.average(:id).to_f]], calculations
|
13
14
|
end
|
14
15
|
|
15
16
|
test '#calculate.json params[:where]' do
|
@@ -19,27 +20,32 @@ module StandardAPI
|
|
19
20
|
selects = [{ count: :id}, { maximum: :id }, { minimum: :id }, { average: :id }]
|
20
21
|
predicate = { id: { gt: m1.id } }
|
21
22
|
|
22
|
-
get :calculate,
|
23
|
+
get resource_path(:calculate, where: predicate, select: selects, format: :json)
|
24
|
+
|
23
25
|
assert_response :ok
|
24
26
|
assert_equal [[
|
25
27
|
model.filter(predicate).count(:id),
|
26
28
|
model.filter(predicate).maximum(:id),
|
27
29
|
model.filter(predicate).minimum(:id),
|
28
30
|
model.filter(predicate).average(:id).to_f
|
29
|
-
]],
|
31
|
+
]], @controller.instance_variable_get('@calculations')
|
30
32
|
end
|
31
33
|
|
32
34
|
test '#calculate.json mask' do
|
35
|
+
# This is just to instance @controller
|
36
|
+
get resource_path(:calculate)
|
37
|
+
|
33
38
|
# If #current_mask isn't defined by StandardAPI we don't know how to
|
34
39
|
# test other's implementation of #current_mask. Return and don't test.
|
35
40
|
return if @controller.method(:current_mask).owner != StandardAPI
|
36
41
|
|
37
42
|
m = create_model
|
43
|
+
|
38
44
|
@controller.current_mask[plural_name] = { id: m.id + 100 }
|
39
45
|
selects = [{ count: :id}, { maximum: :id }, { minimum: :id }, { average: :id }]
|
40
46
|
get :calculate, select: selects, format: 'json'
|
41
47
|
assert_response :ok
|
42
|
-
assert_equal [[0, nil, nil, nil]],
|
48
|
+
assert_equal [[0, nil, nil, nil]], @controller.instance_variable_get('@calculations')
|
43
49
|
@controller.current_mask.delete(plural_name)
|
44
50
|
end
|
45
51
|
|
@@ -3,24 +3,18 @@ module StandardAPI
|
|
3
3
|
module CreateTests
|
4
4
|
extend ActiveSupport::Testing::Declarative
|
5
5
|
|
6
|
-
def setup
|
7
|
-
@request.content_type="application/json"
|
8
|
-
super
|
9
|
-
end
|
10
|
-
|
11
6
|
test '#create.json' do
|
12
7
|
attrs = attributes_for(singular_name, :nested).select{|k,v| !model.readonly_attributes.include?(k.to_s) }
|
13
8
|
create_webmocks(attrs)
|
14
9
|
|
15
10
|
assert_difference("#{model.name}.count") do
|
16
|
-
post :create,
|
11
|
+
post resource_path(:create, singular_name => attrs, format: :json)
|
17
12
|
assert_response :created
|
18
|
-
|
13
|
+
m = @controller.instance_variable_get("@#{singular_name}")
|
19
14
|
|
20
15
|
json = JSON.parse(response.body)
|
21
16
|
assert json.is_a?(Hash)
|
22
17
|
|
23
|
-
m = assigns(singular_name)
|
24
18
|
view_attributes(m.reload).select { |x| attrs.keys.map(&:to_s).include?(x) }.each do |key, value|
|
25
19
|
message = "Model / Attribute: #{m.class.name}##{key}"
|
26
20
|
if value.is_a?(BigDecimal)
|
@@ -37,13 +31,14 @@ module StandardAPI
|
|
37
31
|
create_webmocks(attrs)
|
38
32
|
|
39
33
|
assert_difference("#{model.name}.count") do
|
40
|
-
post :create, params: {singular_name => attrs}
|
34
|
+
post resource_path(:create, format: :json), params: {singular_name => attrs}
|
41
35
|
assert_response :created
|
42
|
-
|
36
|
+
m = @controller.instance_variable_get("@#{singular_name}")
|
37
|
+
assert m
|
43
38
|
|
44
39
|
json = JSON.parse(response.body)
|
45
40
|
assert json.is_a?(Hash)
|
46
|
-
m
|
41
|
+
m.reload
|
47
42
|
view_attributes(m).select { |x| attrs.keys.map(&:to_s).include?(x) }.each do |key, value|
|
48
43
|
message = "Model / Attribute: #{m.class.name}##{key}"
|
49
44
|
assert_equal normalize_attribute(m, key, attrs[key.to_sym]), value, message
|
@@ -64,14 +59,14 @@ module StandardAPI
|
|
64
59
|
create_webmocks(attrs)
|
65
60
|
|
66
61
|
assert_difference("#{model.name}.count", 0) do
|
67
|
-
post :create,
|
62
|
+
post resource_path(:create, singular_name => attrs, format: :json)
|
68
63
|
assert_response :bad_request
|
69
64
|
json = JSON.parse(response.body)
|
70
65
|
assert json.is_a?(Hash)
|
71
66
|
assert json['errors']
|
72
67
|
end
|
73
68
|
end
|
74
|
-
|
69
|
+
|
75
70
|
test '#create.html with invalid attributes renders edit action' do
|
76
71
|
return unless supports_format(:html)
|
77
72
|
|
@@ -87,7 +82,7 @@ module StandardAPI
|
|
87
82
|
create_webmocks(attrs)
|
88
83
|
|
89
84
|
assert_difference("#{model.name}.count", 0) do
|
90
|
-
post :create,
|
85
|
+
post resource_path(:create, singular_name => attrs, format: :html)
|
91
86
|
assert_response :bad_request
|
92
87
|
assert_equal response.body, 'properties#edit.html'
|
93
88
|
end
|
@@ -99,24 +94,25 @@ module StandardAPI
|
|
99
94
|
create_webmocks(attrs)
|
100
95
|
|
101
96
|
assert_difference("#{model.name}.count") do
|
102
|
-
post :create,
|
97
|
+
post resource_path(:create, singular_name => attrs, include: includes, format: :json)
|
103
98
|
assert_response :created
|
104
|
-
|
99
|
+
m = @controller.instance_variable_get("@#{singular_name}")
|
100
|
+
assert m
|
105
101
|
|
106
102
|
json = JSON.parse(response.body)
|
107
103
|
assert json.is_a?(Hash)
|
108
104
|
includes.each do |included|
|
109
105
|
assert json.key?(included.to_s), "#{included.inspect} not included in response"
|
110
106
|
|
111
|
-
association =
|
107
|
+
association = m.class.reflect_on_association(included)
|
112
108
|
next if !association
|
113
109
|
|
114
110
|
if ['belongs_to', 'has_one'].include?(association.macro.to_s)
|
115
|
-
view_attributes(
|
116
|
-
assert_equal json[included.to_s][key.to_s], normalize_to_json(
|
111
|
+
view_attributes(m.send(included)) do |key, value|
|
112
|
+
assert_equal json[included.to_s][key.to_s], normalize_to_json(m, key, value)
|
117
113
|
end
|
118
114
|
else
|
119
|
-
m =
|
115
|
+
m = m.send(included).first.try(:reload)
|
120
116
|
|
121
117
|
m_json = if m && m.has_attribute?(:id)
|
122
118
|
json[included.to_s].find { |x| x['id'] == normalize_to_json(m, :id, m.id) }
|
@@ -7,21 +7,25 @@ module StandardAPI
|
|
7
7
|
m = create_model
|
8
8
|
|
9
9
|
assert_difference("#{model.name}.count", -1) do
|
10
|
-
delete :destroy,
|
10
|
+
delete resource_path(:destroy, id: m.id, format: :json)
|
11
11
|
assert_response :no_content
|
12
12
|
assert_equal '', response.body
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
16
|
test '#destroy.json mask' do
|
17
|
+
m = create_model
|
18
|
+
|
19
|
+
# This is just to instance @controller
|
20
|
+
get resource_path(:show, id: m.id, format: 'json')
|
21
|
+
|
17
22
|
# If #current_mask isn't defined by StandardAPI we don't know how to
|
18
23
|
# test other's implementation of #current_mask. Return and don't test.
|
19
24
|
return if @controller.method(:current_mask).owner != StandardAPI
|
20
25
|
|
21
|
-
m = create_model
|
22
26
|
@controller.current_mask[plural_name] = { id: m.id + 1 }
|
23
27
|
assert_raises(ActiveRecord::RecordNotFound) do
|
24
|
-
delete :destroy,
|
28
|
+
delete resource_path(:destroy, id: m.id, format: :json)
|
25
29
|
end
|
26
30
|
@controller.current_mask.delete(plural_name)
|
27
31
|
end
|
@@ -4,58 +4,80 @@ module StandardAPI
|
|
4
4
|
extend ActiveSupport::Testing::Declarative
|
5
5
|
|
6
6
|
test '#index.json' do
|
7
|
-
get :index, format: :json
|
7
|
+
get resource_path(:index, format: :json), params: { limit: 10 }
|
8
8
|
assert_response :ok
|
9
|
-
|
9
|
+
models = @controller.instance_variable_get("@#{plural_name}")
|
10
|
+
assert_equal model.all.map(&:id).sort, models.map(&:id).sort
|
10
11
|
assert JSON.parse(response.body).is_a?(Array)
|
11
12
|
end
|
12
13
|
|
14
|
+
test '#index.json requires limit' do
|
15
|
+
assert_raises ActionController::ParameterMissing do
|
16
|
+
get resource_path(:index, format: :json)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
13
20
|
test '#index.json params[:limit]' do
|
14
|
-
get :index, params: { limit: 1 }
|
15
|
-
|
21
|
+
get resource_path(:index, format: :json), params: { limit: 1 }
|
22
|
+
models = @controller.instance_variable_get("@#{plural_name}")
|
23
|
+
assert_equal model.limit(1).sort(required_orders).to_sql, models.to_sql
|
24
|
+
end
|
25
|
+
|
26
|
+
test '#index.json params[:limit] does not exceed maximum limit' do
|
27
|
+
assert_raises ActionController::UnpermittedParameters do
|
28
|
+
get resource_path(:index, format: :json), params: { limit: 1000000 }
|
29
|
+
end
|
16
30
|
end
|
17
31
|
|
18
32
|
test '#index.json params[:where]' do
|
19
33
|
m = create_model
|
20
34
|
|
21
|
-
get :index, params: { where: { id: m.id } }
|
22
|
-
|
35
|
+
get resource_path(:index, format: :json), params: { limit: 10, where: { id: m.id } }
|
36
|
+
models = @controller.instance_variable_get("@#{plural_name}")
|
37
|
+
assert_equal [m], models
|
23
38
|
end
|
24
39
|
|
25
40
|
test '#index.json params[:order]' do
|
41
|
+
# This is just to instance @controller
|
42
|
+
get resource_path(:index, format: :json), params: { limit: 1 }
|
43
|
+
|
26
44
|
orders.each do |order|
|
27
45
|
@controller.instance_variable_set('@orders', nil) # Hack for dealing with caching / multiple request per controller life
|
28
|
-
get :index, params: { order: order }
|
29
|
-
|
46
|
+
get resource_path(:index, format: :json), params: { limit: 10, order: order }
|
47
|
+
models = @controller.instance_variable_get("@#{plural_name}")
|
48
|
+
assert_equal model.sort(order).limit(10).sort(required_orders).to_sql, models.to_sql
|
30
49
|
end
|
31
50
|
end
|
32
51
|
|
33
52
|
test '#index.json params[:offset]' do
|
34
|
-
get :index, params: { offset: 13 }
|
35
|
-
|
53
|
+
get resource_path(:index, format: :json), params: { limit: 10, offset: 13 }
|
54
|
+
models = @controller.instance_variable_get("@#{plural_name}")
|
55
|
+
assert_equal model.offset(13).limit(10).sort(required_orders).to_sql, models.to_sql
|
36
56
|
end
|
37
57
|
|
38
58
|
test '#index.json params[:include]' do
|
39
59
|
travel_to Time.now do
|
40
60
|
create_model
|
41
|
-
get :index, params: { include: includes }
|
61
|
+
get resource_path(:index, format: :json), params: { limit: 100, include: includes }
|
42
62
|
|
43
63
|
json = JSON.parse(response.body)[0]
|
44
64
|
assert json.is_a?(Hash)
|
45
65
|
includes.each do |included|
|
46
66
|
assert json.key?(included.to_s), "#{included.inspect} not included in response"
|
47
67
|
|
48
|
-
|
68
|
+
models = @controller.instance_variable_get("@#{plural_name}")
|
69
|
+
association = models.first.class.reflect_on_association(included)
|
49
70
|
next if !association
|
50
71
|
|
51
72
|
if ['belongs_to', 'has_one'].include?(association.macro.to_s)
|
52
|
-
|
73
|
+
models = @controller.instance_variable_get("@#{plural_name}")
|
74
|
+
m = models.first.send(included)
|
53
75
|
view_attributes(m) do |key, value|
|
54
76
|
message = "Model / Attribute: #{m.class.name}##{key}"
|
55
77
|
assert_equal json[included.to_s][key.to_s], normalize_to_json(m, key, value), message
|
56
78
|
end
|
57
79
|
else
|
58
|
-
m =
|
80
|
+
m = models.first.send(included).first.try(:reload)
|
59
81
|
|
60
82
|
m_json = if m && m.has_attribute?(:id)
|
61
83
|
json[included.to_s].find { |x| x['id'] == normalize_to_json(m, :id, m.id) }
|
@@ -76,6 +98,9 @@ module StandardAPI
|
|
76
98
|
end
|
77
99
|
|
78
100
|
test '#index.json mask' do
|
101
|
+
# This is just to instance @controller
|
102
|
+
get resource_path(:index, format: :json), params: { limit: 1 }
|
103
|
+
|
79
104
|
# If #current_mask isn't defined by StandardAPI we don't know how to
|
80
105
|
# test other's implementation of #current_mask. Return and don't test.
|
81
106
|
return if @controller.method(:current_mask).owner != StandardAPI
|
@@ -83,7 +108,8 @@ module StandardAPI
|
|
83
108
|
m = create_model
|
84
109
|
@controller.current_mask[plural_name] = { id: m.id }
|
85
110
|
get :index, format: :json
|
86
|
-
|
111
|
+
models = @controller.instance_variable_get("@#{plural_name}")
|
112
|
+
assert_equal model.where(id: m.id).sort(required_orders).to_sql, models.to_sql
|
87
113
|
@controller.current_mask.delete(plural_name)
|
88
114
|
end
|
89
115
|
end
|
@@ -4,9 +4,9 @@ module StandardAPI
|
|
4
4
|
extend ActiveSupport::Testing::Declarative
|
5
5
|
|
6
6
|
test '#new.json' do
|
7
|
-
get :new, format: 'json'
|
7
|
+
get resource_path(:new, format: 'json')
|
8
8
|
assert_response :ok
|
9
|
-
assert
|
9
|
+
assert @controller.instance_variable_get("@#{singular_name}")
|
10
10
|
end
|
11
11
|
|
12
12
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module StandardAPI
|
2
|
+
module TestCase
|
3
|
+
module IndexTests
|
4
|
+
extend ActiveSupport::Testing::Declarative
|
5
|
+
|
6
|
+
test '#schema.json' do
|
7
|
+
create_model
|
8
|
+
|
9
|
+
get resource_path(:schema, format: :json)
|
10
|
+
assert_response :ok
|
11
|
+
json = JSON(@response.body)
|
12
|
+
assert json['columns']
|
13
|
+
model.columns.map do |column|
|
14
|
+
assert json['columns'][column.name]['type']
|
15
|
+
end
|
16
|
+
assert json['limit']
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -6,29 +6,29 @@ module StandardAPI
|
|
6
6
|
test '#show.json' do
|
7
7
|
m = create_model
|
8
8
|
|
9
|
-
get :show,
|
9
|
+
get resource_path(:show, id: m.id, format: :json)
|
10
10
|
assert_response :ok
|
11
|
-
assert_equal m,
|
11
|
+
assert_equal m, @controller.instance_variable_get("@#{singular_name}")
|
12
12
|
assert JSON.parse(response.body).is_a?(Hash)
|
13
13
|
end
|
14
14
|
|
15
15
|
test '#show.json params[:include]' do
|
16
16
|
m = create_model
|
17
|
-
get :show,
|
17
|
+
get resource_path(:show, id: m.id, include: includes, format: :json)
|
18
18
|
|
19
19
|
json = JSON.parse(response.body)
|
20
20
|
includes.each do |included|
|
21
21
|
assert json.key?(included.to_s), "#{included.inspect} not included in response"
|
22
22
|
|
23
|
-
association =
|
23
|
+
association = @controller.instance_variable_get("@#{singular_name}").class.reflect_on_association(included)
|
24
24
|
next if !association
|
25
25
|
|
26
26
|
if ['belongs_to', 'has_one'].include?(association.macro.to_s)
|
27
|
-
view_attributes(
|
27
|
+
view_attributes(@controller.instance_variable_get("@#{singular_name}").send(included)) do |key, value|
|
28
28
|
assert_equal json[included.to_s][key.to_s], value
|
29
29
|
end
|
30
30
|
else
|
31
|
-
m =
|
31
|
+
m = @controller.instance_variable_get("@#{singular_name}").send(included).first.try(:reload)
|
32
32
|
|
33
33
|
m_json = if m && m.has_attribute?(:id)
|
34
34
|
json[included.to_s].find { |x| x['id'] == normalize_to_json(m, :id, m.id) }
|
@@ -48,14 +48,19 @@ module StandardAPI
|
|
48
48
|
end
|
49
49
|
|
50
50
|
test '#show.json mask' do
|
51
|
+
m = create_model
|
52
|
+
|
53
|
+
# This is just to instance @controller
|
54
|
+
get resource_path(:show, id: m.id, format: :json)
|
55
|
+
|
51
56
|
# If #current_mask isn't defined by StandardAPI we don't know how to
|
52
57
|
# test other's implementation of #current_mask. Return and don't test.
|
53
58
|
return if @controller.method(:current_mask).owner != StandardAPI
|
54
59
|
|
55
|
-
|
60
|
+
|
56
61
|
@controller.current_mask[plural_name] = { id: m.id + 1 }
|
57
62
|
assert_raises(ActiveRecord::RecordNotFound) do
|
58
|
-
get :show,
|
63
|
+
get resource_path(:show, id: m.id, format: :json)
|
59
64
|
end
|
60
65
|
@controller.current_mask.delete(plural_name)
|
61
66
|
end
|
@@ -3,17 +3,12 @@ module StandardAPI
|
|
3
3
|
module UpdateTests
|
4
4
|
extend ActiveSupport::Testing::Declarative
|
5
5
|
|
6
|
-
def setup
|
7
|
-
@request.content_type="application/json"
|
8
|
-
super
|
9
|
-
end
|
10
|
-
|
11
6
|
test '#update.json' do
|
12
7
|
m = create_model
|
13
8
|
attrs = attributes_for(singular_name).select{|k,v| !model.readonly_attributes.include?(k.to_s) }
|
14
9
|
create_webmocks(attrs)
|
15
10
|
|
16
|
-
put :update,
|
11
|
+
put resource_path(:update, :id => m.id, :format => 'json'), params: { singular_name => attrs }
|
17
12
|
assert_response :ok, "Updating #{m.class.name} with #{attrs.inspect}"
|
18
13
|
|
19
14
|
view_attributes(m.reload).select { |x| attrs.keys.map(&:to_s).include?(x) }.each do |key, value|
|
@@ -28,13 +23,18 @@ module StandardAPI
|
|
28
23
|
end
|
29
24
|
|
30
25
|
test '#update.html redirects to #show.html' do
|
26
|
+
m = create_model
|
27
|
+
|
28
|
+
# This is just to instance @controller
|
29
|
+
get resource_path(:show, id: m.id, format: :json)
|
30
|
+
|
31
31
|
return if @controller.method(:update).owner != StandardAPI
|
32
32
|
|
33
|
-
m = create_model
|
34
33
|
attrs = attributes_for(singular_name).select{|k,v| !model.readonly_attributes.include?(k.to_s) }
|
35
34
|
create_webmocks(attrs)
|
36
35
|
|
37
|
-
put :update,
|
36
|
+
put resource_path(:update, :id => m.id, :format => 'html'), params: { singular_name => attrs }
|
37
|
+
|
38
38
|
assert_redirected_to m
|
39
39
|
end
|
40
40
|
|
@@ -42,7 +42,8 @@ module StandardAPI
|
|
42
42
|
m = create_model
|
43
43
|
attrs = attributes_for(singular_name, :nested).select{|k,v| !model.readonly_attributes.include?(k.to_s) }
|
44
44
|
create_webmocks(attrs)
|
45
|
-
|
45
|
+
|
46
|
+
put resource_path(:update, :id => m.id, :format => 'json'), params: { singular_name => attrs }
|
46
47
|
assert_response :ok, "Updating #{m.class.name} with #{attrs.inspect}"
|
47
48
|
|
48
49
|
# (m.attribute_names & attrs.keys.map(&:to_s)).each do |test_key|
|
@@ -66,7 +67,7 @@ module StandardAPI
|
|
66
67
|
attrs = attributes_for(singular_name, :invalid).select{|k,v| !model.readonly_attributes.include?(k.to_s) }
|
67
68
|
create_webmocks(attrs)
|
68
69
|
|
69
|
-
put :update,
|
70
|
+
put resource_path(:update, :id => m.id, :format => 'json'), params: { singular_name => attrs }
|
70
71
|
assert_response :bad_request, "Updating #{m.class.name} with invalid attributes #{attrs.inspect}"
|
71
72
|
assert JSON.parse(@response.body)['errors']
|
72
73
|
end
|
@@ -77,23 +78,24 @@ module StandardAPI
|
|
77
78
|
attrs = attributes_for(singular_name, :nested).select{|k,v| !model.readonly_attributes.include?(k) }
|
78
79
|
create_webmocks(attrs)
|
79
80
|
|
80
|
-
put :update,
|
81
|
+
put resource_path(:update, :id => m.id, :format => 'json'), params: { include: includes, singular_name => attrs }
|
81
82
|
assert_response :ok, "Updating #{m.class.name} with #{attrs.inspect}"
|
82
83
|
|
84
|
+
controller_model = @controller.instance_variable_get("@#{singular_name}")
|
83
85
|
json = JSON.parse(response.body)
|
84
86
|
includes.each do |included|
|
85
87
|
assert json.key?(included.to_s), "#{included.inspect} not included in response"
|
86
88
|
|
87
|
-
association =
|
89
|
+
association = controller_model.class.reflect_on_association(included)
|
88
90
|
next if !association
|
89
91
|
|
90
92
|
if ['belongs_to', 'has_one'].include?(association.macro.to_s)
|
91
|
-
view_attributes(
|
92
|
-
message = "Model / Attribute: #{
|
93
|
+
view_attributes(controller_model.send(included)) do |key, value|
|
94
|
+
message = "Model / Attribute: #{controller_model.send(included).class.name}##{key}"
|
93
95
|
assert_equal json[included.to_s][key.to_s], value, message
|
94
96
|
end
|
95
97
|
else
|
96
|
-
m =
|
98
|
+
m = controller_model.send(included).first.try(:reload)
|
97
99
|
m_json = if m && m.has_attribute?(:id)
|
98
100
|
json[included.to_s].find { |x| x['id'] == normalize_to_json(m, :id, m.id) }
|
99
101
|
elsif m
|
@@ -113,14 +115,18 @@ module StandardAPI
|
|
113
115
|
end
|
114
116
|
|
115
117
|
test '#update.json mask' do
|
118
|
+
m = create_model
|
119
|
+
|
120
|
+
# This is just to instance @controller
|
121
|
+
get resource_path(:index, format: :json), params: { limit: 1 }
|
122
|
+
|
116
123
|
# If #current_mask isn't defined by StandardAPI we don't know how to
|
117
124
|
# test other's implementation of #current_mask. Return and don't test.
|
118
125
|
return if @controller.method(:current_mask).owner != StandardAPI
|
119
126
|
|
120
|
-
m = create_model
|
121
127
|
@controller.current_mask[plural_name] = { id: m.id + 1 }
|
122
128
|
assert_raises(ActiveRecord::RecordNotFound) do
|
123
|
-
put :update,
|
129
|
+
put resource_path(:update, :id => m.id, :format => 'json')
|
124
130
|
end
|
125
131
|
@controller.current_mask.delete(plural_name)
|
126
132
|
end
|
@@ -1,23 +1,17 @@
|
|
1
1
|
require 'active_support/test_case'
|
2
2
|
|
3
3
|
require File.expand_path(File.join(__FILE__, '../test_case/calculate_tests'))
|
4
|
-
require File.expand_path(File.join(__FILE__, '../test_case/new_tests'))
|
5
4
|
require File.expand_path(File.join(__FILE__, '../test_case/create_tests'))
|
6
5
|
require File.expand_path(File.join(__FILE__, '../test_case/destroy_tests'))
|
7
6
|
require File.expand_path(File.join(__FILE__, '../test_case/index_tests'))
|
7
|
+
require File.expand_path(File.join(__FILE__, '../test_case/new_tests'))
|
8
|
+
require File.expand_path(File.join(__FILE__, '../test_case/schema_tests'))
|
8
9
|
require File.expand_path(File.join(__FILE__, '../test_case/show_tests'))
|
9
10
|
require File.expand_path(File.join(__FILE__, '../test_case/update_tests'))
|
10
11
|
|
11
12
|
module StandardAPI::TestCase
|
12
13
|
|
13
14
|
def self.included(klass)
|
14
|
-
begin
|
15
|
-
controller_class_name = klass.name.gsub(/Test$/, '')
|
16
|
-
controller_class_name.constantize
|
17
|
-
rescue NameError => e
|
18
|
-
raise e if e.message != "uninitialized constant #{controller_class_name}"
|
19
|
-
end
|
20
|
-
|
21
15
|
[:filters, :orders, :includes].each do |attribute|
|
22
16
|
klass.send(:class_attribute, attribute)
|
23
17
|
end
|
@@ -41,14 +35,13 @@ module StandardAPI::TestCase
|
|
41
35
|
acc
|
42
36
|
end
|
43
37
|
|
44
|
-
|
45
38
|
klass.controller_class.action_methods.each do |action|
|
46
39
|
if const_defined?("StandardAPI::TestCase::#{action.capitalize}Tests") && routes[klass.controller_class.controller_path][action]
|
47
40
|
klass.include("StandardAPI::TestCase::#{action.capitalize}Tests".constantize)
|
48
41
|
end
|
49
42
|
end
|
50
43
|
end
|
51
|
-
|
44
|
+
|
52
45
|
def supports_format(format)
|
53
46
|
count = controller_class.view_paths.count do |path|
|
54
47
|
!Dir.glob("#{path.instance_variable_get(:@path)}/{#{model.name.underscore},application}/**/*.#{format}*").empty?
|
@@ -60,18 +53,33 @@ module StandardAPI::TestCase
|
|
60
53
|
def required_orders
|
61
54
|
controller_class.new.send(:required_orders)
|
62
55
|
end
|
63
|
-
|
64
|
-
def controller_class
|
65
|
-
controller_class_name = self.class.name.gsub(/Test$/, '')
|
66
|
-
controller_class_name.constantize
|
67
|
-
rescue NameError => e
|
68
|
-
raise e if e.message != "uninitialized constant #{controller_class_name}"
|
69
|
-
end
|
70
56
|
|
71
57
|
def model
|
72
58
|
self.class.model
|
73
59
|
end
|
74
60
|
|
61
|
+
def resource_path(action, options={})
|
62
|
+
url_for({
|
63
|
+
controller: model.model_name.plural, action: action
|
64
|
+
}.merge(options))
|
65
|
+
# case action
|
66
|
+
# when :index, :create
|
67
|
+
# send "#{model.model_name.plural.underscore}_path", *args
|
68
|
+
# when :schema, :calculate
|
69
|
+
# send "#{model.model_name.plural.underscore}_#{action}_path", *args
|
70
|
+
# else
|
71
|
+
# send "#{action}_#{model.model_name.underscore}_path", *args
|
72
|
+
# end
|
73
|
+
end
|
74
|
+
|
75
|
+
# def resoruces_path(action, *args)
|
76
|
+
# send "#{model.model_name.plural.underscore}_path", *args
|
77
|
+
# end
|
78
|
+
|
79
|
+
def controller_class
|
80
|
+
self.class.controller_class
|
81
|
+
end
|
82
|
+
|
75
83
|
def create_model(*args)
|
76
84
|
create(model.name.underscore, *args)
|
77
85
|
end
|
@@ -128,6 +136,13 @@ module StandardAPI::TestCase
|
|
128
136
|
klass.instance_variable_set('@normalizers', {})
|
129
137
|
end
|
130
138
|
|
139
|
+
def controller_class
|
140
|
+
controller_class_name = self.name.gsub(/Test$/, '')
|
141
|
+
controller_class_name.constantize
|
142
|
+
rescue NameError => e
|
143
|
+
raise e if e.message != "uninitialized constant #{controller_class_name}"
|
144
|
+
end
|
145
|
+
|
131
146
|
def include_filter_tests
|
132
147
|
model.instance_variable_get('@filters').each do |filter|
|
133
148
|
next if filter[1].is_a?(Proc) # Custom filter
|
@@ -20,11 +20,15 @@ mapping = {
|
|
20
20
|
'geometry' => 'ewkb'
|
21
21
|
}
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
23
|
+
json.set! 'columns' do
|
24
|
+
model.columns.each do |column|
|
25
|
+
json.set! column.name, {
|
26
|
+
type: mapping[column.sql_type],
|
27
|
+
primary_key: column.name == model.primary_key,
|
28
|
+
null: column.null,
|
29
|
+
array: column.array
|
30
|
+
}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
json.set! 'limit', resource_limit
|
File without changes
|
data/lib/standard_api.rb
CHANGED
@@ -8,9 +8,7 @@ require 'active_record/filter'
|
|
8
8
|
require 'active_record/sort'
|
9
9
|
require 'active_support/core_ext/hash/indifferent_access'
|
10
10
|
|
11
|
-
|
12
|
-
end
|
13
|
-
|
11
|
+
require 'standard_api/version'
|
14
12
|
require 'standard_api/orders'
|
15
13
|
require 'standard_api/includes'
|
16
14
|
require 'standard_api/controller'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: standardapi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.0.0.
|
4
|
+
version: 5.0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Bracy
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-11-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -294,13 +294,15 @@ files:
|
|
294
294
|
- lib/standard_api/test_case/destroy_tests.rb
|
295
295
|
- lib/standard_api/test_case/index_tests.rb
|
296
296
|
- lib/standard_api/test_case/new_tests.rb
|
297
|
-
- lib/standard_api/test_case/
|
297
|
+
- lib/standard_api/test_case/schema_tests.rb
|
298
298
|
- lib/standard_api/test_case/show_tests.rb
|
299
299
|
- lib/standard_api/test_case/update_tests.rb
|
300
|
+
- lib/standard_api/version.rb
|
300
301
|
- lib/standard_api/views/application/_record.json.jbuilder
|
301
302
|
- lib/standard_api/views/application/index.json.jbuilder
|
302
303
|
- lib/standard_api/views/application/new.json.jbuilder
|
303
304
|
- lib/standard_api/views/application/schema.json.jbuilder
|
305
|
+
- lib/standard_api/views/application/settings.json.jbuilder
|
304
306
|
- lib/standard_api/views/application/show.json.jbuilder
|
305
307
|
homepage: https://github.com/waratuman/standardapi
|
306
308
|
licenses:
|