standardapi 1.0.23 → 5.0.0.rc1
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 +49 -13
- data/lib/standard_api/helpers.rb +93 -1
- data/lib/standard_api/includes.rb +3 -6
- data/lib/standard_api/middleware/query_encoding.rb +34 -0
- data/lib/standard_api/orders.rb +24 -12
- data/lib/standard_api/railtie.rb +1 -0
- data/lib/standard_api/route_helpers.rb +26 -0
- data/lib/standard_api/test_case/calculate_tests.rb +8 -3
- data/lib/standard_api/test_case/create_tests.rb +22 -6
- data/lib/standard_api/test_case/destroy_tests.rb +2 -2
- data/lib/standard_api/test_case/index_tests.rb +9 -9
- data/lib/standard_api/test_case/new_tests.rb +14 -0
- data/lib/standard_api/test_case/show_tests.rb +3 -4
- data/lib/standard_api/test_case/update_tests.rb +37 -9
- data/lib/standard_api/test_case.rb +4 -4
- data/lib/standard_api/views/application/_record.json.jbuilder +34 -26
- data/lib/standard_api/views/application/index.json.jbuilder +12 -1
- data/lib/standard_api/views/application/new.json.jbuilder +1 -0
- data/lib/standard_api/views/application/schema.json.jbuilder +1 -1
- data/lib/standard_api/views/application/show.json.jbuilder +0 -1
- data/lib/standard_api.rb +1 -1
- metadata +49 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 32b4ca6314bc038faf8b73560d327096f4c4bf53
|
4
|
+
data.tar.gz: 1162cb994c7921a7ffc4eea033a40b0e5f4f50b5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: deaa898296ded369ca9c9b2289eaab9c803977d9f51f5283bf20d546da33b41e9d6fa2c7750195a9c438a87b59434f29fd0eca79421bce83db6774244276456c
|
7
|
+
data.tar.gz: eaeb860e977eee866a9f98ce6ef4b10f697a95a2a6d3e33a286fc390e45102fc287b3139c14ab1a6868b04a115deacabe745c15286f11de76ab86922f6a440c8
|
@@ -2,20 +2,20 @@ module StandardAPI
|
|
2
2
|
module Controller
|
3
3
|
|
4
4
|
def self.included(klass)
|
5
|
-
klass.hide_action :current_mask
|
6
5
|
klass.helper_method :includes, :orders, :model
|
7
6
|
klass.append_view_path(File.join(File.dirname(__FILE__), 'views'))
|
8
7
|
klass.extend(ClassMethods)
|
9
8
|
end
|
10
|
-
|
9
|
+
|
11
10
|
def ping
|
12
|
-
render :
|
11
|
+
render plain: 'pong'
|
13
12
|
end
|
14
13
|
|
15
14
|
def tables
|
16
15
|
controllers = Dir[Rails.root.join('app/controllers/*_controller.rb')].map{ |path| path.match(/(\w+)_controller.rb/)[1].camelize+"Controller" }.map(&:safe_constantize)
|
17
16
|
controllers.select! { |c| c.ancestors.include?(self.class) && c != self.class }
|
18
|
-
controllers.map!(&:model).compact
|
17
|
+
controllers.map!(&:model).compact!
|
18
|
+
controllers.map!(&:table_name)
|
19
19
|
|
20
20
|
render json: controllers
|
21
21
|
end
|
@@ -39,19 +39,43 @@ module StandardAPI
|
|
39
39
|
instance_variable_set("@#{model.model_name.singular}", resources.find(params[:id]))
|
40
40
|
end
|
41
41
|
|
42
|
+
def new
|
43
|
+
instance_variable_set("@#{model.model_name.singular}", model.new) if model
|
44
|
+
end
|
45
|
+
|
42
46
|
def create
|
43
|
-
|
44
|
-
|
47
|
+
record = model.new(model_params)
|
48
|
+
instance_variable_set("@#{model.model_name.singular}", record)
|
49
|
+
|
50
|
+
if record.save
|
51
|
+
if request.format == :html
|
52
|
+
redirect_to record
|
53
|
+
else
|
54
|
+
render :show, status: :created
|
55
|
+
end
|
56
|
+
else
|
57
|
+
render :show, status: :bad_request
|
58
|
+
end
|
45
59
|
end
|
46
60
|
|
47
61
|
def update
|
48
|
-
|
49
|
-
|
62
|
+
record = resources.find(params[:id])
|
63
|
+
instance_variable_set("@#{model.model_name.singular}", record)
|
64
|
+
|
65
|
+
if record.update_attributes(model_params)
|
66
|
+
if request.format == :html
|
67
|
+
redirect_to record
|
68
|
+
else
|
69
|
+
render :show, status: :ok
|
70
|
+
end
|
71
|
+
else
|
72
|
+
render :show, status: :bad_request
|
73
|
+
end
|
50
74
|
end
|
51
75
|
|
52
76
|
def destroy
|
53
77
|
resources.find(params[:id]).destroy!
|
54
|
-
|
78
|
+
head :no_content
|
55
79
|
end
|
56
80
|
|
57
81
|
# Override if you want to support masking
|
@@ -75,15 +99,27 @@ module StandardAPI
|
|
75
99
|
end
|
76
100
|
|
77
101
|
def model_params
|
78
|
-
|
102
|
+
if self.respond_to?("#{model.model_name.singular}_params", true)
|
103
|
+
params.require(model.model_name.singular).permit(self.send("#{model.model_name.singular}_params"))
|
104
|
+
else
|
105
|
+
[]
|
106
|
+
end
|
79
107
|
end
|
80
108
|
|
81
109
|
def model_includes
|
82
|
-
self.
|
110
|
+
if self.respond_to?("#{model.model_name.singular}_includes", true)
|
111
|
+
self.send "#{model.model_name.singular}_includes"
|
112
|
+
else
|
113
|
+
[]
|
114
|
+
end
|
83
115
|
end
|
84
116
|
|
85
117
|
def model_orders
|
86
|
-
self.
|
118
|
+
if self.respond_to?("#{model.model_name.singular}_orders", true)
|
119
|
+
self.send "#{model.model_name.singular}_orders"
|
120
|
+
else
|
121
|
+
[]
|
122
|
+
end
|
87
123
|
end
|
88
124
|
|
89
125
|
def excludes_for(klass)
|
@@ -139,4 +175,4 @@ module StandardAPI
|
|
139
175
|
end
|
140
176
|
|
141
177
|
end
|
142
|
-
end
|
178
|
+
end
|
data/lib/standard_api/helpers.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module StandardAPI
|
2
2
|
module Helpers
|
3
|
-
|
3
|
+
|
4
4
|
def model_partial(record)
|
5
5
|
if lookup_context.exists?(record.model_name.element, record.model_name.plural, true)
|
6
6
|
[record.model_name.plural, record.model_name.element].join('/')
|
@@ -8,6 +8,98 @@ module StandardAPI
|
|
8
8
|
'application/record'
|
9
9
|
end
|
10
10
|
end
|
11
|
+
|
12
|
+
def can_cache?(klass, includes)
|
13
|
+
cache_columns = ['cached_at'] + cached_at_columns_for_includes(includes)
|
14
|
+
if (cache_columns - klass.column_names).empty?
|
15
|
+
true
|
16
|
+
else
|
17
|
+
false
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def cache_key(record, includes)
|
22
|
+
timestamp_keys = ['cached_at'] + cached_at_columns_for_includes(includes)
|
23
|
+
if includes.empty?
|
24
|
+
record.cache_key(*timestamp_keys)
|
25
|
+
else
|
26
|
+
timestamp = record.send(:max_updated_column_timestamp, timestamp_keys)
|
27
|
+
"#{record.model_name.cache_key}/#{record.id}-#{digest_hash(sort_hash(includes))}-#{timestamp.utc.to_s(record.cache_timestamp_format)}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def can_cache_relation?(klass, relation, subincludes)
|
32
|
+
cache_columns = ["#{relation}_cached_at"] + cached_at_columns_for_includes(subincludes).map {|c| "#{relation}_#{c}"}
|
33
|
+
if (cache_columns - klass.column_names).empty?
|
34
|
+
true
|
35
|
+
else
|
36
|
+
false
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def association_cache_key(record, relation, subincludes)
|
41
|
+
timestamp = ["#{relation}_cached_at"] + cached_at_columns_for_includes(subincludes).map {|c| "#{relation}_#{c}"}
|
42
|
+
timestamp.map! { |col| record.send(col) }
|
43
|
+
timestamp = timestamp.max
|
44
|
+
|
45
|
+
case association = record.class.reflect_on_association(relation)
|
46
|
+
when ActiveRecord::Reflection::HasManyReflection, ActiveRecord::Reflection::HasAndBelongsToManyReflection, ActiveRecord::Reflection::HasOneReflection, ActiveRecord::Reflection::ThroughReflection
|
47
|
+
"#{record.model_name.cache_key}/#{record.id}/#{includes_to_cache_key(relation, subincludes)}-#{timestamp.utc.to_s(record.cache_timestamp_format)}"
|
48
|
+
when ActiveRecord::Reflection::BelongsToReflection
|
49
|
+
klass = association.options[:polymorphic] ? record.send(association.foreign_type).constantize : association.klass
|
50
|
+
if subincludes.empty?
|
51
|
+
"#{klass.model_name.cache_key}/#{record.send(association.foreign_key)}-#{timestamp.utc.to_s(klass.cache_timestamp_format)}"
|
52
|
+
else
|
53
|
+
"#{klass.model_name.cache_key}/#{record.send(association.foreign_key)}/#{digest_hash(sort_hash(subincludes))}-#{timestamp.utc.to_s(klass.cache_timestamp_format)}"
|
54
|
+
end
|
55
|
+
else
|
56
|
+
raise ArgumentError, 'Unkown association type'
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def cached_at_columns_for_includes(includes)
|
61
|
+
includes.select{|k,v| ![:where, :limit, :order].include?(k.to_sym) }.map { |k, v|
|
62
|
+
["#{k}_cached_at"] + cached_at_columns_for_includes(v).map{|v| "#{k}_#{v}"}
|
63
|
+
}.flatten
|
64
|
+
end
|
65
|
+
|
66
|
+
def includes_to_cache_key(relation, subincludes)
|
67
|
+
if subincludes.empty?
|
68
|
+
relation.to_s
|
69
|
+
else
|
70
|
+
"#{relation}-#{digest_hash(sort_hash(subincludes))}"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def sort_hash(hash)
|
75
|
+
hash.keys.sort.reduce({}) do |seed, key|
|
76
|
+
if seed[key].is_a?(Hash)
|
77
|
+
seed[key] = sort_hash(hash[key])
|
78
|
+
else
|
79
|
+
seed[key] = hash[key]
|
80
|
+
end
|
81
|
+
seed
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def digest_hash(*hashes)
|
86
|
+
hashes.compact!
|
87
|
+
hashes.map! { |h| sort_hash(h) }
|
88
|
+
|
89
|
+
digest = Digest::MD5.new()
|
90
|
+
hashes.each do |hash|
|
91
|
+
hash.each do |key, value|
|
92
|
+
digest << key.to_s
|
93
|
+
if value.is_a?(Hash)
|
94
|
+
digest << digest_hash(value)
|
95
|
+
else
|
96
|
+
digest << value.to_s
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
digest.hexdigest
|
102
|
+
end
|
11
103
|
|
12
104
|
end
|
13
105
|
end
|
@@ -15,10 +15,10 @@ module StandardAPI
|
|
15
15
|
case includes
|
16
16
|
when Array
|
17
17
|
includes.flatten.compact.each { |v| normalized.merge!(normalize(v)) }
|
18
|
-
when Hash
|
18
|
+
when Hash, ActionController::Parameters
|
19
19
|
includes.each_pair do |k, v|
|
20
20
|
if ['where', 'order'].include?(k.to_s) # Where and order are not normalized
|
21
|
-
normalized[k] = v
|
21
|
+
normalized[k] = v.to_h
|
22
22
|
else
|
23
23
|
normalized[k] = normalize(v)
|
24
24
|
end
|
@@ -55,10 +55,7 @@ module StandardAPI
|
|
55
55
|
permitted[k] = sanitize(v, permit[k] || {}, true)
|
56
56
|
else
|
57
57
|
if [:raise, nil].include?(Rails.configuration.try(:action_on_unpermitted_includes))
|
58
|
-
raise
|
59
|
-
Invalid Include: #{k}"
|
60
|
-
Set config.action_on_unpermitted_includes = :warm to log instead of raise
|
61
|
-
ERR
|
58
|
+
raise ActionController::UnpermittedParameters.new([k])
|
62
59
|
else
|
63
60
|
Rails.logger.try(:warn, "Invalid Include: #{k}")
|
64
61
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'msgpack'
|
2
|
+
|
3
|
+
# QueryEncoding middleware intercepts and parsing the query sting as MessagePack
|
4
|
+
# if the `Query-Encoding` header is set to `application/msgpack`
|
5
|
+
#
|
6
|
+
# Usage:
|
7
|
+
#
|
8
|
+
# require 'standard_api/middleware/query_encoding'
|
9
|
+
#
|
10
|
+
# And in the Rails config
|
11
|
+
#
|
12
|
+
# config.middleware.insert_after Rack::MethodOverride, StandardAPI::Middleware::QueryEncoding
|
13
|
+
module StandardAPI
|
14
|
+
module Middleware
|
15
|
+
class QueryEncoding
|
16
|
+
MSGPACK_MIME_TYPE = "application/msgpack".freeze
|
17
|
+
HTTP_METHOD_OVERRIDE_HEADER = "HTTP_QUERY_ENCODING".freeze
|
18
|
+
|
19
|
+
def initialize(app)
|
20
|
+
@app = app
|
21
|
+
end
|
22
|
+
|
23
|
+
def call(env)
|
24
|
+
if !env[Rack::QUERY_STRING].empty? && env[HTTP_METHOD_OVERRIDE_HEADER] == MSGPACK_MIME_TYPE
|
25
|
+
env[Rack::RACK_REQUEST_QUERY_STRING] = env[Rack::QUERY_STRING]
|
26
|
+
env[Rack::RACK_REQUEST_QUERY_HASH] = MessagePack.unpack(CGI.unescape(env[Rack::QUERY_STRING]))
|
27
|
+
end
|
28
|
+
|
29
|
+
@app.call(env)
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/standard_api/orders.rb
CHANGED
@@ -9,37 +9,49 @@ module StandardAPI
|
|
9
9
|
permitted = []
|
10
10
|
|
11
11
|
case orders
|
12
|
-
when Hash
|
12
|
+
when Hash, ActionController::Parameters
|
13
13
|
orders.each do |key, value|
|
14
14
|
if key.to_s.count('.') == 1
|
15
15
|
key2, key3 = *key.to_s.split('.')
|
16
|
-
permitted
|
16
|
+
permitted << sanitize({key2.to_sym => { key3.to_sym => value } }, permit)
|
17
17
|
elsif permit.include?(key.to_s)
|
18
|
-
value = value.symbolize_keys if value.is_a?(Hash)
|
19
|
-
permitted
|
20
|
-
elsif permit.find { |x| x.is_a?(Hash) && x.has_key?(key.to_s) }
|
21
|
-
subpermit = permit.find { |x| x.is_a?(Hash) && x.has_key?(key.to_s) }[key.to_s]
|
18
|
+
value = value.symbolize_keys if value.is_a?(Hash) || value.is_a?(ActionController::Parameters)
|
19
|
+
permitted << { key.to_sym => value }
|
20
|
+
elsif permit.find { |x| (x.is_a?(Hash) || x.is_a?(ActionController::Parameters)) && x.has_key?(key.to_s) }
|
21
|
+
subpermit = permit.find { |x| (x.is_a?(Hash) || x.is_a?(ActionController::Parameters)) && x.has_key?(key.to_s) }[key.to_s]
|
22
22
|
sanitized_value = sanitize(value, subpermit)
|
23
|
-
permitted
|
23
|
+
permitted << { key.to_sym => sanitized_value }
|
24
24
|
else
|
25
|
-
raise(
|
25
|
+
raise(ActionController::UnpermittedParameters.new([orders]))
|
26
26
|
end
|
27
27
|
end
|
28
28
|
when Array
|
29
|
-
orders.each
|
29
|
+
orders.each do |order|
|
30
|
+
order = sanitize(order, permit)
|
31
|
+
if order.is_a?(Array)
|
32
|
+
permitted += order
|
33
|
+
else
|
34
|
+
permitted << order
|
35
|
+
end
|
36
|
+
end
|
30
37
|
else
|
31
|
-
|
32
38
|
if orders.to_s.count('.') == 1
|
33
39
|
key, value = *orders.to_s.split('.')
|
34
40
|
permitted = sanitize({key.to_sym => value.to_sym}, permit)
|
35
41
|
elsif permit.include?(orders.to_s)
|
36
42
|
permitted = orders
|
37
43
|
else
|
38
|
-
raise(
|
44
|
+
raise(ActionController::UnpermittedParameters.new([orders]))
|
39
45
|
end
|
40
46
|
end
|
41
47
|
|
42
|
-
permitted
|
48
|
+
if permitted.is_a?(Array) && permitted.length == 1
|
49
|
+
permitted.first
|
50
|
+
else
|
51
|
+
permitted
|
52
|
+
end
|
53
|
+
|
54
|
+
# permitted
|
43
55
|
end
|
44
56
|
|
45
57
|
end
|
data/lib/standard_api/railtie.rb
CHANGED
@@ -0,0 +1,26 @@
|
|
1
|
+
module StandardAPI
|
2
|
+
module RouteHelpers
|
3
|
+
|
4
|
+
# Shorthand for adding resources.
|
5
|
+
#
|
6
|
+
# For example
|
7
|
+
#
|
8
|
+
# standard_resources :views
|
9
|
+
#
|
10
|
+
# Is equivilent to:
|
11
|
+
#
|
12
|
+
# resources :api_keys do
|
13
|
+
# get :schema, on: :collection
|
14
|
+
# get :calculate, on: :collection
|
15
|
+
# end
|
16
|
+
def standard_resources(*resources, &block)
|
17
|
+
options = resources.extract_options!.dup
|
18
|
+
|
19
|
+
resources(*resources, options) do
|
20
|
+
get :schema, on: :collection
|
21
|
+
get :calculate, on: :collection
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -7,7 +7,7 @@ module StandardAPI
|
|
7
7
|
m = create_model
|
8
8
|
selects = [{ count: :id}, { maximum: :id }, { minimum: :id }, { average: :id }]
|
9
9
|
|
10
|
-
get :calculate, select: selects, format:
|
10
|
+
get :calculate, params: {select: selects}, format: :json
|
11
11
|
assert_response :ok
|
12
12
|
assert_equal [[model.count(:id), model.maximum(:id), model.minimum(:id), model.average(:id).to_f]], assigns(:calculations)
|
13
13
|
end
|
@@ -19,9 +19,14 @@ module StandardAPI
|
|
19
19
|
selects = [{ count: :id}, { maximum: :id }, { minimum: :id }, { average: :id }]
|
20
20
|
predicate = { id: { gt: m1.id } }
|
21
21
|
|
22
|
-
get :calculate, where: predicate, select: selects, format:
|
22
|
+
get :calculate, params: {where: predicate, select: selects}, format: :json
|
23
23
|
assert_response :ok
|
24
|
-
assert_equal [[
|
24
|
+
assert_equal [[
|
25
|
+
model.filter(predicate).count(:id),
|
26
|
+
model.filter(predicate).maximum(:id),
|
27
|
+
model.filter(predicate).minimum(:id),
|
28
|
+
model.filter(predicate).average(:id).to_f
|
29
|
+
]], assigns(:calculations)
|
25
30
|
end
|
26
31
|
|
27
32
|
test '#calculate.json mask' do
|
@@ -3,12 +3,17 @@ 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
|
+
|
6
11
|
test '#create.json' do
|
7
12
|
attrs = attributes_for(singular_name, :nested).select{|k,v| !model.readonly_attributes.include?(k.to_s) }
|
8
13
|
create_webmocks(attrs)
|
9
14
|
|
10
15
|
assert_difference("#{model.name}.count") do
|
11
|
-
post :create, singular_name => attrs, :
|
16
|
+
post :create, params: {singular_name => attrs}, format: :json
|
12
17
|
assert_response :created
|
13
18
|
assert assigns(singular_name)
|
14
19
|
|
@@ -18,7 +23,11 @@ module StandardAPI
|
|
18
23
|
m = assigns(singular_name)
|
19
24
|
view_attributes(m.reload).select { |x| attrs.keys.map(&:to_s).include?(x) }.each do |key, value|
|
20
25
|
message = "Model / Attribute: #{m.class.name}##{key}"
|
21
|
-
|
26
|
+
if value.is_a?(BigDecimal)
|
27
|
+
assert_equal normalize_to_json(m, key, attrs[key.to_sym]).to_s.to_f, json[key.to_s].to_s.to_f, message
|
28
|
+
else
|
29
|
+
assert_equal normalize_to_json(m, key, attrs[key.to_sym]), json[key.to_s], message
|
30
|
+
end
|
22
31
|
end
|
23
32
|
end
|
24
33
|
end
|
@@ -28,13 +37,12 @@ module StandardAPI
|
|
28
37
|
create_webmocks(attrs)
|
29
38
|
|
30
39
|
assert_difference("#{model.name}.count") do
|
31
|
-
post :create, singular_name => attrs, :
|
40
|
+
post :create, params: {singular_name => attrs}, format: :json
|
32
41
|
assert_response :created
|
33
42
|
assert assigns(singular_name)
|
34
43
|
|
35
44
|
json = JSON.parse(response.body)
|
36
45
|
assert json.is_a?(Hash)
|
37
|
-
|
38
46
|
m = assigns(singular_name).reload
|
39
47
|
view_attributes(m).select { |x| attrs.keys.map(&:to_s).include?(x) }.each do |key, value|
|
40
48
|
message = "Model / Attribute: #{m.class.name}##{key}"
|
@@ -44,11 +52,19 @@ module StandardAPI
|
|
44
52
|
end
|
45
53
|
|
46
54
|
test '#create.json with invalid attributes' do
|
55
|
+
trait = FactoryGirl.factories[singular_name].definition.defined_traits.any? { |x| x.name.to_s == 'invalid' }
|
56
|
+
|
57
|
+
if !trait
|
58
|
+
Rails.logger.try(:warn, "No invalid trait for #{model.name}. Skipping invalid tests")
|
59
|
+
warn("No invalid trait for #{model.name}. Skipping invalid tests")
|
60
|
+
return
|
61
|
+
end
|
62
|
+
|
47
63
|
attrs = attributes_for(singular_name, :invalid).select{|k,v| !model.readonly_attributes.include?(k.to_s) }
|
48
64
|
create_webmocks(attrs)
|
49
65
|
|
50
66
|
assert_difference("#{model.name}.count", 0) do
|
51
|
-
post :create, singular_name => attrs, :
|
67
|
+
post :create, params: {singular_name => attrs}, format: :json
|
52
68
|
assert_response :bad_request
|
53
69
|
json = JSON.parse(response.body)
|
54
70
|
assert json.is_a?(Hash)
|
@@ -62,7 +78,7 @@ module StandardAPI
|
|
62
78
|
create_webmocks(attrs)
|
63
79
|
|
64
80
|
assert_difference("#{model.name}.count") do
|
65
|
-
post :create, singular_name => attrs, include
|
81
|
+
post :create, params: {singular_name => attrs, :include => includes}, format: :json
|
66
82
|
assert_response :created
|
67
83
|
assert assigns(singular_name)
|
68
84
|
|
@@ -7,7 +7,7 @@ module StandardAPI
|
|
7
7
|
m = create_model
|
8
8
|
|
9
9
|
assert_difference("#{model.name}.count", -1) do
|
10
|
-
delete :destroy, id: m.id, format:
|
10
|
+
delete :destroy, params: { id: m.id }, format: :json
|
11
11
|
assert_response :no_content
|
12
12
|
assert_equal '', response.body
|
13
13
|
end
|
@@ -21,7 +21,7 @@ module StandardAPI
|
|
21
21
|
m = create_model
|
22
22
|
@controller.current_mask[plural_name] = { id: m.id + 1 }
|
23
23
|
assert_raises(ActiveRecord::RecordNotFound) do
|
24
|
-
delete :destroy, id: m.id, format:
|
24
|
+
delete :destroy, params: { id: m.id }, format: :json
|
25
25
|
end
|
26
26
|
@controller.current_mask.delete(plural_name)
|
27
27
|
end
|
@@ -4,41 +4,41 @@ module StandardAPI
|
|
4
4
|
extend ActiveSupport::Testing::Declarative
|
5
5
|
|
6
6
|
test '#index.json' do
|
7
|
-
get :index, format:
|
7
|
+
get :index, format: :json
|
8
8
|
assert_response :ok
|
9
|
-
assert_template :index
|
10
9
|
assert_equal model.all.map(&:id).sort, assigns(plural_name).map(&:id).sort
|
11
10
|
assert JSON.parse(response.body).is_a?(Array)
|
12
11
|
end
|
13
12
|
|
14
13
|
test '#index.json params[:limit]' do
|
15
|
-
get :index, limit: 1, format:
|
14
|
+
get :index, params: { limit: 1 }, format: :json
|
16
15
|
assert_equal model.limit(1).to_sql, assigns(plural_name).to_sql
|
17
16
|
end
|
18
17
|
|
19
18
|
test '#index.json params[:where]' do
|
20
19
|
m = create_model
|
21
|
-
|
20
|
+
|
21
|
+
get :index, params: { where: { id: m.id } }, format: :json
|
22
22
|
assert_equal [m], assigns(plural_name)
|
23
23
|
end
|
24
24
|
|
25
25
|
test '#index.json params[:order]' do
|
26
26
|
orders.each do |order|
|
27
27
|
@controller.instance_variable_set('@orders', nil) # Hack for dealing with caching / multiple request per controller life
|
28
|
-
get :index, order: order, format:
|
28
|
+
get :index, params: { order: order }, format: :json
|
29
29
|
assert_equal model.sort(order).to_sql, assigns(plural_name).to_sql
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
33
|
test '#index.json params[:offset]' do
|
34
|
-
get :index, offset: 13, format:
|
34
|
+
get :index, params: { offset: 13 }, format: :json
|
35
35
|
assert_equal model.offset(13).to_sql, assigns(plural_name).to_sql
|
36
36
|
end
|
37
37
|
|
38
38
|
test '#index.json params[:include]' do
|
39
39
|
travel_to Time.now do
|
40
40
|
create_model
|
41
|
-
get :index, include: includes, format:
|
41
|
+
get :index, params: { include: includes }, format: :json
|
42
42
|
|
43
43
|
json = JSON.parse(response.body)[0]
|
44
44
|
assert json.is_a?(Hash)
|
@@ -67,7 +67,7 @@ module StandardAPI
|
|
67
67
|
|
68
68
|
view_attributes(m).each do |key, value|
|
69
69
|
message = "Model / Attribute: #{m.class.name}##{key}"
|
70
|
-
assert_equal m_json[key.to_s], normalize_to_json(m, key, value)
|
70
|
+
assert_equal m_json[key.to_s], normalize_to_json(m, key, value), message
|
71
71
|
end
|
72
72
|
|
73
73
|
end
|
@@ -82,7 +82,7 @@ module StandardAPI
|
|
82
82
|
|
83
83
|
m = create_model
|
84
84
|
@controller.current_mask[plural_name] = { id: m.id }
|
85
|
-
get :index, format:
|
85
|
+
get :index, format: :json
|
86
86
|
assert_equal model.where(id: m.id).to_sql, assigns(plural_name).to_sql
|
87
87
|
@controller.current_mask.delete(plural_name)
|
88
88
|
end
|
@@ -6,16 +6,15 @@ module StandardAPI
|
|
6
6
|
test '#show.json' do
|
7
7
|
m = create_model
|
8
8
|
|
9
|
-
get :show, id: m.id, format:
|
9
|
+
get :show, params: {id: m.id}, format: :json
|
10
10
|
assert_response :ok
|
11
|
-
assert_template :show
|
12
11
|
assert_equal m, assigns(singular_name)
|
13
12
|
assert JSON.parse(response.body).is_a?(Hash)
|
14
13
|
end
|
15
14
|
|
16
15
|
test '#show.json params[:include]' do
|
17
16
|
m = create_model
|
18
|
-
get :show, id: m.id, include: includes, format:
|
17
|
+
get :show, params: {id: m.id, include: includes}, format: :json
|
19
18
|
|
20
19
|
json = JSON.parse(response.body)
|
21
20
|
includes.each do |included|
|
@@ -56,7 +55,7 @@ module StandardAPI
|
|
56
55
|
m = create_model
|
57
56
|
@controller.current_mask[plural_name] = { id: m.id + 1 }
|
58
57
|
assert_raises(ActiveRecord::RecordNotFound) do
|
59
|
-
get :show, id: m.id, format:
|
58
|
+
get :show, params: {id: m.id}, format: :json
|
60
59
|
end
|
61
60
|
@controller.current_mask.delete(plural_name)
|
62
61
|
end
|
@@ -3,26 +3,46 @@ 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
|
+
|
6
11
|
test '#update.json' do
|
7
12
|
m = create_model
|
8
13
|
attrs = attributes_for(singular_name).select{|k,v| !model.readonly_attributes.include?(k.to_s) }
|
9
14
|
create_webmocks(attrs)
|
10
15
|
|
11
|
-
put :update,
|
12
|
-
assert_response :ok
|
16
|
+
put :update, params: {:id => m.id, singular_name => attrs}, format: :json
|
17
|
+
assert_response :ok, "Updating #{m.class.name} with #{attrs.inspect}"
|
13
18
|
|
14
19
|
view_attributes(m.reload).select { |x| attrs.keys.map(&:to_s).include?(x) }.each do |key, value|
|
15
20
|
message = "Model / Attribute: #{m.class.name}##{key}"
|
16
|
-
|
21
|
+
if value.is_a?(BigDecimal)
|
22
|
+
assert_equal normalize_attribute(m, key, attrs[key.to_sym]).to_s.to_f, value.to_s.to_f, message
|
23
|
+
else
|
24
|
+
assert_equal normalize_attribute(m, key, attrs[key.to_sym]), value, message
|
25
|
+
end
|
17
26
|
end
|
18
27
|
assert JSON.parse(@response.body).is_a?(Hash)
|
19
28
|
end
|
20
29
|
|
30
|
+
test '#update.html redirects to #show.html' do
|
31
|
+
return if @controller.method(:update).owner != StandardAPI
|
32
|
+
|
33
|
+
m = create_model
|
34
|
+
attrs = attributes_for(singular_name).select{|k,v| !model.readonly_attributes.include?(k.to_s) }
|
35
|
+
create_webmocks(attrs)
|
36
|
+
|
37
|
+
put :update, params: {:id => m.id, singular_name => attrs}, format: :html
|
38
|
+
assert_redirected_to m
|
39
|
+
end
|
40
|
+
|
21
41
|
test '#update.json with nested attributes' do
|
22
42
|
m = create_model
|
23
43
|
attrs = attributes_for(singular_name, :nested).select{|k,v| !model.readonly_attributes.include?(k.to_s) }
|
24
44
|
create_webmocks(attrs)
|
25
|
-
put :update,
|
45
|
+
put :update, params: {:id => m.id, singular_name => attrs}, format: :json
|
26
46
|
assert_response :ok
|
27
47
|
|
28
48
|
# (m.attribute_names & attrs.keys.map(&:to_s)).each do |test_key|
|
@@ -34,12 +54,20 @@ module StandardAPI
|
|
34
54
|
end
|
35
55
|
|
36
56
|
test '#update.json with invalid attributes' do
|
57
|
+
trait = FactoryGirl.factories[singular_name].definition.defined_traits.any? { |x| x.name.to_s == 'invalid' }
|
58
|
+
|
59
|
+
if !trait
|
60
|
+
Rails.logger.try(:warn, "No invalid trait for #{model.name}. Skipping invalid tests")
|
61
|
+
warn("No invalid trait for #{model.name}. Skipping invalid tests")
|
62
|
+
return
|
63
|
+
end
|
64
|
+
|
37
65
|
m = create_model
|
38
66
|
attrs = attributes_for(singular_name, :invalid).select{|k,v| !model.readonly_attributes.include?(k.to_s) }
|
39
67
|
create_webmocks(attrs)
|
40
68
|
|
41
|
-
put :update,
|
42
|
-
assert_response :bad_request
|
69
|
+
put :update, params: {:id => m.id, singular_name => attrs}, format: :json
|
70
|
+
assert_response :bad_request, "Updating #{m.class.name} with invalid attributes #{attrs.inspect}"
|
43
71
|
assert JSON.parse(@response.body)['errors']
|
44
72
|
end
|
45
73
|
|
@@ -49,7 +77,7 @@ module StandardAPI
|
|
49
77
|
attrs = attributes_for(singular_name, :nested).select{|k,v| !model.readonly_attributes.include?(k) }
|
50
78
|
create_webmocks(attrs)
|
51
79
|
|
52
|
-
put :update,
|
80
|
+
put :update, params: {:id => m.id, :include => includes, singular_name => attrs}, format: :json
|
53
81
|
|
54
82
|
json = JSON.parse(response.body)
|
55
83
|
includes.each do |included|
|
@@ -75,7 +103,7 @@ module StandardAPI
|
|
75
103
|
|
76
104
|
view_attributes(m).each do |key, value|
|
77
105
|
message = "Model / Attribute: #{m.class.name}##{key}"
|
78
|
-
assert_equal m_json[key.to_s], normalize_to_json(m, key, value)
|
106
|
+
assert_equal m_json[key.to_s], normalize_to_json(m, key, value), message
|
79
107
|
end
|
80
108
|
|
81
109
|
end
|
@@ -91,7 +119,7 @@ module StandardAPI
|
|
91
119
|
m = create_model
|
92
120
|
@controller.current_mask[plural_name] = { id: m.id + 1 }
|
93
121
|
assert_raises(ActiveRecord::RecordNotFound) do
|
94
|
-
put :update, id: m.id, format: 'json'
|
122
|
+
put :update, params: {id: m.id}, format: 'json'
|
95
123
|
end
|
96
124
|
@controller.current_mask.delete(plural_name)
|
97
125
|
end
|
@@ -1,6 +1,7 @@
|
|
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'))
|
4
5
|
require File.expand_path(File.join(__FILE__, '../test_case/create_tests'))
|
5
6
|
require File.expand_path(File.join(__FILE__, '../test_case/destroy_tests'))
|
6
7
|
require File.expand_path(File.join(__FILE__, '../test_case/index_tests'))
|
@@ -78,12 +79,11 @@ module StandardAPI::TestCase
|
|
78
79
|
|
79
80
|
def normalize_to_json(record, attribute, value)
|
80
81
|
value = normalize_attribute(record, attribute, value)
|
81
|
-
|
82
82
|
return nil if value.nil?
|
83
83
|
|
84
|
-
if model.
|
84
|
+
if model.columns_hash[attribute].is_a?(ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Decimal)
|
85
85
|
"#{value.to_f}"
|
86
|
-
elsif model.
|
86
|
+
elsif value.is_a?(DateTime) #model.columns_hash[attribute].is_a?(ActiveRecord::AttributeMethods::TimeZoneConversion::TimeZoneConverter)
|
87
87
|
value.in_time_zone.as_json
|
88
88
|
else
|
89
89
|
value.as_json
|
@@ -111,7 +111,7 @@ module StandardAPI::TestCase
|
|
111
111
|
value = m.send(filter[0])
|
112
112
|
|
113
113
|
assert_predicate = -> (predicate) {
|
114
|
-
get :index, where: predicate, format: 'json'
|
114
|
+
get :index, params: {where: predicate}, format: 'json'
|
115
115
|
assert_equal model.filter(predicate).to_sql, assigns(plural_name).to_sql
|
116
116
|
}
|
117
117
|
|
@@ -5,47 +5,55 @@ record.attributes.each do |name, value|
|
|
5
5
|
end
|
6
6
|
|
7
7
|
includes.each do |inc, subinc|
|
8
|
-
next if [
|
9
|
-
|
10
|
-
association = record.class.reflect_on_association(inc)
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
if collection
|
8
|
+
next if [:where, :order, :limit].include?(inc.to_sym)
|
9
|
+
|
10
|
+
case association = record.class.reflect_on_association(inc)
|
11
|
+
when ActiveRecord::Reflection::HasManyReflection, ActiveRecord::Reflection::HasAndBelongsToManyReflection, ActiveRecord::Reflection::ThroughReflection
|
12
|
+
can_cache = can_cache_relation?(record.class, inc, subinc)
|
13
|
+
json.cache_if!(can_cache, can_cache ? association_cache_key(record, inc, subinc) : nil) do
|
15
14
|
partial = model_partial(association.klass)
|
16
15
|
json.set! inc do
|
17
|
-
json.array! record.send(inc), partial: partial, as: partial.split('/').last, locals: { includes: subinc }
|
16
|
+
json.array! record.send(inc).filter(subinc[:where]).limit(subinc[:limit]).sort(subinc[:order]), partial: partial, as: partial.split('/').last, locals: { includes: subinc }
|
18
17
|
end
|
19
|
-
|
20
|
-
|
21
|
-
|
18
|
+
end
|
19
|
+
|
20
|
+
when ActiveRecord::Reflection::BelongsToReflection, ActiveRecord::Reflection::HasOneReflection
|
21
|
+
can_cache = can_cache_relation?(record.class, inc, subinc)
|
22
|
+
if association.is_a?(ActiveRecord::Reflection::BelongsToReflection)
|
23
|
+
can_cache = can_cache && !record.send(association.foreign_key).nil?
|
24
|
+
end
|
25
|
+
json.cache_if!(can_cache, can_cache ? association_cache_key(record, inc, subinc) : nil) do
|
26
|
+
value = record.send(inc)
|
27
|
+
if value.nil?
|
22
28
|
json.set! inc, nil
|
23
29
|
else
|
24
|
-
partial = model_partial(
|
30
|
+
partial = model_partial(value)
|
25
31
|
json.set! inc do
|
26
|
-
json.partial! partial, partial.split('/').last.to_sym =>
|
32
|
+
json.partial! partial, partial.split('/').last.to_sym => value, includes: subinc
|
27
33
|
end
|
28
34
|
end
|
29
35
|
end
|
30
|
-
|
36
|
+
|
31
37
|
else
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
38
|
+
if record.respond_to?(inc)
|
39
|
+
value = record.send(inc)
|
40
|
+
if value.nil?
|
41
|
+
json.set! inc, nil
|
42
|
+
elsif value.is_a?(ActiveModel::Model)
|
43
|
+
json.set! inc do
|
44
|
+
partial = model_partial(value)
|
45
|
+
json.partial! partial, partial.split('/').last.to_sym => value, includes: subinc
|
46
|
+
end
|
47
|
+
else
|
48
|
+
json.set! inc, value.as_json
|
39
49
|
end
|
40
|
-
else
|
41
|
-
# TODO: Test
|
42
|
-
json.set! inc, record.send(inc).as_json
|
43
50
|
end
|
44
|
-
|
45
51
|
end
|
46
52
|
|
47
53
|
end
|
48
54
|
|
49
55
|
if !record.errors.blank?
|
50
|
-
|
56
|
+
errs = record.errors.to_hash
|
57
|
+
errs.default_proc = nil
|
58
|
+
json.set! 'errors', errs
|
51
59
|
end
|
@@ -1 +1,12 @@
|
|
1
|
-
|
1
|
+
if !includes.empty? && can_cache?(model, includes)
|
2
|
+
partial = model_partial(model)
|
3
|
+
record_name = partial.split('/').last.to_sym
|
4
|
+
locals = { record_name => nil, :includes => includes}
|
5
|
+
|
6
|
+
json.cache_collection! instance_variable_get("@#{model.model_name.plural}"), key: proc {|record| cache_key(record, includes) } do |record|
|
7
|
+
locals[record_name] = record
|
8
|
+
json.partial! partial, locals
|
9
|
+
end
|
10
|
+
else
|
11
|
+
json.array! instance_variable_get("@#{model.model_name.plural}"), partial: model_partial(model), as: model_partial(model).split('/').last, includes: includes
|
12
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
json.partial! model_partial(model), model_partial(model).split('/').last.to_sym => instance_variable_get("@#{model.model_name.singular}"), includes: includes
|
data/lib/standard_api.rb
CHANGED
metadata
CHANGED
@@ -1,71 +1,85 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: standardapi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 5.0.0.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Bracy
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-05-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: rails
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 5.0.0.rc1
|
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:
|
26
|
+
version: 5.0.0.rc1
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: activesupport
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 5.0.0.rc1
|
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:
|
40
|
+
version: 5.0.0.rc1
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: actionpack
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: 5.0.0.rc1
|
48
48
|
type: :runtime
|
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:
|
54
|
+
version: 5.0.0.rc1
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: activerecord-sort
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 5.0.0.rc1
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 5.0.0.rc1
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: activerecord-filter
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
58
72
|
requirements:
|
59
73
|
- - "~>"
|
60
74
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
75
|
+
version: 5.0.0.rc1
|
62
76
|
type: :runtime
|
63
77
|
prerelease: false
|
64
78
|
version_requirements: !ruby/object:Gem::Requirement
|
65
79
|
requirements:
|
66
80
|
- - "~>"
|
67
81
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
82
|
+
version: 5.0.0.rc1
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: jbuilder
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -192,6 +206,20 @@ dependencies:
|
|
192
206
|
- - ">="
|
193
207
|
- !ruby/object:Gem::Version
|
194
208
|
version: '0'
|
209
|
+
- !ruby/object:Gem::Dependency
|
210
|
+
name: mocha
|
211
|
+
requirement: !ruby/object:Gem::Requirement
|
212
|
+
requirements:
|
213
|
+
- - ">="
|
214
|
+
- !ruby/object:Gem::Version
|
215
|
+
version: '0'
|
216
|
+
type: :development
|
217
|
+
prerelease: false
|
218
|
+
version_requirements: !ruby/object:Gem::Requirement
|
219
|
+
requirements:
|
220
|
+
- - ">="
|
221
|
+
- !ruby/object:Gem::Version
|
222
|
+
version: '0'
|
195
223
|
description: StandardAPI makes it easy to expose a query interface for your Rails
|
196
224
|
models
|
197
225
|
email:
|
@@ -206,18 +234,22 @@ files:
|
|
206
234
|
- lib/standard_api/controller.rb
|
207
235
|
- lib/standard_api/helpers.rb
|
208
236
|
- lib/standard_api/includes.rb
|
237
|
+
- lib/standard_api/middleware/query_encoding.rb
|
209
238
|
- lib/standard_api/orders.rb
|
210
239
|
- lib/standard_api/railtie.rb
|
240
|
+
- lib/standard_api/route_helpers.rb
|
211
241
|
- lib/standard_api/test_case.rb
|
212
242
|
- lib/standard_api/test_case/calculate_tests.rb
|
213
243
|
- lib/standard_api/test_case/create_tests.rb
|
214
244
|
- lib/standard_api/test_case/destroy_tests.rb
|
215
245
|
- lib/standard_api/test_case/index_tests.rb
|
246
|
+
- lib/standard_api/test_case/new_tests.rb
|
216
247
|
- lib/standard_api/test_case/schema_test.rb
|
217
248
|
- lib/standard_api/test_case/show_tests.rb
|
218
249
|
- lib/standard_api/test_case/update_tests.rb
|
219
250
|
- lib/standard_api/views/application/_record.json.jbuilder
|
220
251
|
- lib/standard_api/views/application/index.json.jbuilder
|
252
|
+
- lib/standard_api/views/application/new.json.jbuilder
|
221
253
|
- lib/standard_api/views/application/schema.json.jbuilder
|
222
254
|
- lib/standard_api/views/application/show.json.jbuilder
|
223
255
|
homepage: https://github.com/waratuman/standardapi
|
@@ -237,12 +269,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
237
269
|
version: '0'
|
238
270
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
239
271
|
requirements:
|
240
|
-
- - "
|
272
|
+
- - ">"
|
241
273
|
- !ruby/object:Gem::Version
|
242
|
-
version:
|
274
|
+
version: 1.3.1
|
243
275
|
requirements: []
|
244
276
|
rubyforge_project:
|
245
|
-
rubygems_version: 2.
|
277
|
+
rubygems_version: 2.5.1
|
246
278
|
signing_key:
|
247
279
|
specification_version: 4
|
248
280
|
summary: StandardAPI makes it easy to expose a query interface for your Rails models
|