brainstem 2.1.0 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/brainstem.gemspec +1 -0
- data/lib/brainstem/api_docs/introspectors/rails_introspector.rb +7 -5
- data/lib/brainstem/controller_methods.rb +2 -2
- data/lib/brainstem/presenter.rb +1 -1
- data/lib/brainstem/presenter_collection.rb +1 -1
- data/lib/brainstem/query_strategies/filter_and_search.rb +1 -1
- data/lib/brainstem/query_strategies/filter_or_search.rb +1 -1
- data/lib/brainstem/version.rb +1 -1
- data/spec/brainstem/controller_methods_spec.rb +16 -1
- data/spec/dummy/rails.rb +20 -7
- data/spec/spec_helpers/schema.rb +1 -1
- metadata +15 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: be36bdc7fac874075d12f3fc38f599db5b212521
|
4
|
+
data.tar.gz: 34d5b34f8f0ff187174aa72e7cab77de068d31fe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c89e79f9afe533a869501ede83e86ad4cbeba0dbb08c6a29d57b4dbac437e3a7072e672fc807ec517225b67f5aefdc42d0ebaba68cdc713505cd460f02b1a3bb
|
7
|
+
data.tar.gz: d9a506a58f9fd81d58ae3546dd88dce4e7f6fd836661673915402c54ee0d6a3235def1abddafe465cff485daf7e1f911a7b5bdad0b539a623590c6dbe11a3db7
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
+ **2.2.0** - _08/15/2019_
|
4
|
+
### Bugfixes
|
5
|
+
- Add support for API documentation generation in Rails 5.x
|
6
|
+
- Address deprecation warnings for Rails 6 by wrapping raw sql in `Arel.sql`
|
7
|
+
|
3
8
|
+ **2.1.0** - _05/10/2019_
|
4
9
|
### New Features
|
5
10
|
- Add the ability to mark properties as internal for Open API.
|
data/brainstem.gemspec
CHANGED
@@ -212,17 +212,19 @@ module Brainstem
|
|
212
212
|
.classify
|
213
213
|
.constantize rescue nil
|
214
214
|
|
215
|
+
http_methods = (
|
216
|
+
route.verb.is_a?(Regexp) ?
|
217
|
+
route.verb.inspect.gsub(/[\/\$\^]/, '') :
|
218
|
+
route.verb
|
219
|
+
).split("|")
|
220
|
+
|
215
221
|
{
|
216
222
|
alias: route.name,
|
217
223
|
path: route.path.spec.to_s,
|
218
224
|
controller_name: route.defaults[:controller],
|
219
225
|
controller: controller_const,
|
220
226
|
action: route.defaults[:action],
|
221
|
-
http_methods:
|
222
|
-
.fetch(:request_method, nil)
|
223
|
-
.inspect
|
224
|
-
.gsub(/[\/\$\^]/, '')
|
225
|
-
.split("|")
|
227
|
+
http_methods: http_methods
|
226
228
|
}
|
227
229
|
end.compact
|
228
230
|
end
|
@@ -25,7 +25,7 @@ module Brainstem
|
|
25
25
|
# @yield (see PresenterCollection#presenting)
|
26
26
|
# @return (see PresenterCollection#presenting)
|
27
27
|
def brainstem_present(name, options = {}, &block)
|
28
|
-
Brainstem.presenter_collection(options[:namespace]).presenting(name, options.reverse_merge(:params => params), &block)
|
28
|
+
Brainstem.presenter_collection(options[:namespace]).presenting(name, options.reverse_merge(:params => params.to_unsafe_h), &block)
|
29
29
|
end
|
30
30
|
|
31
31
|
# Similar to ControllerMethods#brainstem_present, but always returns all of the given objects, not just those that
|
@@ -36,7 +36,7 @@ module Brainstem
|
|
36
36
|
# only required if the name cannot be inferred.
|
37
37
|
# @return (see PresenterCollection#presenting)
|
38
38
|
def brainstem_present_object(objects, options = {})
|
39
|
-
options.merge!(:params => params, :apply_default_filters => false)
|
39
|
+
options.merge!(:params => params.to_unsafe_h, :apply_default_filters => false)
|
40
40
|
|
41
41
|
if objects.is_a?(ActiveRecord::Relation) || objects.is_a?(Array)
|
42
42
|
raise ActiveRecord::RecordNotFound if objects.empty?
|
data/lib/brainstem/presenter.rb
CHANGED
@@ -232,7 +232,7 @@ module Brainstem
|
|
232
232
|
primary_key = scope.model.primary_key
|
233
233
|
|
234
234
|
if table_name && primary_key
|
235
|
-
"#{scope.connection.quote_table_name(table_name)}.#{scope.connection.quote_column_name(primary_key)} ASC"
|
235
|
+
Arel.sql("#{scope.connection.quote_table_name(table_name)}.#{scope.connection.quote_column_name(primary_key)} ASC")
|
236
236
|
else
|
237
237
|
nil
|
238
238
|
end
|
@@ -35,7 +35,7 @@ module Brainstem
|
|
35
35
|
# @yield Must return a scope on the model +name+, which will then be presented.
|
36
36
|
# @return [Hash] A hash of arrays of hashes. Top-level hash keys are pluralized model names, with values of arrays containing one hash per object that was found by the given given options.
|
37
37
|
def presenting(name, options = {}, &block)
|
38
|
-
options[:params] = HashWithIndifferentAccess.new(options[:params] || {})
|
38
|
+
options[:params] = ActiveSupport::HashWithIndifferentAccess.new(options[:params] || {})
|
39
39
|
check_for_old_options!(options)
|
40
40
|
set_default_filters_option!(options)
|
41
41
|
presented_class = (options[:model] || name)
|
@@ -35,7 +35,7 @@ module Brainstem
|
|
35
35
|
private
|
36
36
|
|
37
37
|
def run_search(scope, includes)
|
38
|
-
search_options = HashWithIndifferentAccess.new(
|
38
|
+
search_options = ActiveSupport::HashWithIndifferentAccess.new(
|
39
39
|
include: includes,
|
40
40
|
limit: @options[:default_max_filter_and_search_page],
|
41
41
|
offset: 0
|
@@ -44,7 +44,7 @@ module Brainstem
|
|
44
44
|
def run_search(scope, includes, sort_name, direction)
|
45
45
|
return scope unless searching?
|
46
46
|
|
47
|
-
search_options = HashWithIndifferentAccess.new(
|
47
|
+
search_options = ActiveSupport::HashWithIndifferentAccess.new(
|
48
48
|
include: includes,
|
49
49
|
order: { sort_order: sort_name, direction: direction },
|
50
50
|
)
|
data/lib/brainstem/version.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'action_controller/metal/strong_parameters'
|
2
3
|
|
3
4
|
describe Brainstem::ControllerMethods do
|
4
5
|
class TasksController
|
@@ -7,15 +8,27 @@ describe Brainstem::ControllerMethods do
|
|
7
8
|
attr_accessor :call_results
|
8
9
|
|
9
10
|
def params
|
10
|
-
{ :a => :b }
|
11
|
+
@params ||= ActionController::Parameters.new({ :a => :b })
|
11
12
|
end
|
12
13
|
end
|
13
14
|
|
15
|
+
before(:all) do
|
16
|
+
ActionController::Parameters.action_on_unpermitted_parameters = :raise
|
17
|
+
end
|
18
|
+
|
14
19
|
describe "#present_object" do
|
15
20
|
before do
|
16
21
|
@controller = TasksController.new
|
17
22
|
end
|
18
23
|
|
24
|
+
describe '#integration' do
|
25
|
+
it 'permits the parameters' do
|
26
|
+
# This would throw an UnpermittedParameters exception if we didn't permit the parameters
|
27
|
+
@controller.brainstem_present_object([Workspace.find(1), Workspace.find(3)])
|
28
|
+
@controller.brainstem_present(Workspace) { Workspace.unscoped }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
19
32
|
describe "calling #present with sensible params" do
|
20
33
|
before do
|
21
34
|
def @controller.brainstem_present(klass, options)
|
@@ -60,7 +73,9 @@ describe Brainstem::ControllerMethods do
|
|
60
73
|
it "adds an only param if there is only one object to present" do
|
61
74
|
@controller.brainstem_present_object(Workspace.find(1))
|
62
75
|
expect(@controller.call_results[:options][:params][:only]).to eq("1")
|
76
|
+
end
|
63
77
|
|
78
|
+
it "doesn't set only if there is more than one object" do
|
64
79
|
@controller.brainstem_present_object(Workspace.all)
|
65
80
|
expect(@controller.call_results[:options][:params][:only]).to be_nil
|
66
81
|
end
|
data/spec/dummy/rails.rb
CHANGED
@@ -4,34 +4,47 @@ silence_warnings do
|
|
4
4
|
FakeRailsApplication = Struct.new(:eager_load!, :routes)
|
5
5
|
FakeRailsRoutesObject = Struct.new(:routes)
|
6
6
|
FakeRailsRoutePathObject = Struct.new(:spec)
|
7
|
-
FakeRailsRoute = Struct.new(:name, :path, :defaults, :
|
7
|
+
FakeRailsRoute = Struct.new(:name, :path, :defaults, :verb)
|
8
8
|
end
|
9
9
|
|
10
10
|
class Rails
|
11
11
|
def self.application
|
12
12
|
@application ||= begin
|
13
|
+
#
|
14
|
+
# For Rails 4.1 & 4.2, the `verb` method on a route returns a regular expression.
|
15
|
+
#
|
13
16
|
route_1 = FakeRailsRoute.new(
|
14
17
|
"fake_descendant",
|
15
18
|
FakeRailsRoutePathObject.new(spec: '/fake_descendant'),
|
16
19
|
{ controller: "fake_descendant", action: "show" },
|
17
|
-
|
20
|
+
/^GET|POST$/
|
18
21
|
)
|
19
22
|
|
20
23
|
route_2 = FakeRailsRoute.new(
|
21
24
|
"route_with_no_controller",
|
22
25
|
FakeRailsRoutePathObject.new(spec: '/fake_descendant'),
|
23
26
|
{ },
|
24
|
-
|
27
|
+
/^PATCH$/
|
25
28
|
)
|
26
29
|
|
30
|
+
#
|
31
|
+
# For Rails 5.x, the `verb` method on a route returns a string.
|
32
|
+
#
|
27
33
|
route_3 = FakeRailsRoute.new(
|
28
34
|
"route_with_invalid_controller",
|
29
35
|
FakeRailsRoutePathObject.new(spec: '/fake_descendant'),
|
30
36
|
{ controller: "invalid_controller", action: "show" },
|
31
|
-
|
37
|
+
'GET'
|
32
38
|
)
|
33
39
|
|
34
|
-
|
40
|
+
route_4 = FakeRailsRoute.new(
|
41
|
+
"another_fake_descendant",
|
42
|
+
FakeRailsRoutePathObject.new(spec: '/another_fake_descendant'),
|
43
|
+
{ controller: "another_fake_descendant", action: "update" },
|
44
|
+
'PUT|PATCH'
|
45
|
+
)
|
46
|
+
|
47
|
+
routes = FakeRailsRoutesObject.new([ route_1, route_2, route_3, route_4 ])
|
35
48
|
|
36
49
|
FakeRailsApplication.new(true, routes)
|
37
50
|
end
|
@@ -54,14 +67,14 @@ class FakeApiEngine
|
|
54
67
|
"fake_descendant",
|
55
68
|
FakeRailsRoutePathObject.new(spec: '/fake_route_1'),
|
56
69
|
{ controller: "fake_descendant", action: "show" },
|
57
|
-
|
70
|
+
/^PUT|PATCH$/
|
58
71
|
)
|
59
72
|
|
60
73
|
route_2 = FakeRailsRoute.new(
|
61
74
|
"fake_descendant",
|
62
75
|
FakeRailsRoutePathObject.new(spec: '/fake_route_2'),
|
63
76
|
{ controller: "fake_descendant", action: "show" },
|
64
|
-
|
77
|
+
'PUT|PATCH'
|
65
78
|
)
|
66
79
|
|
67
80
|
FakeRailsRoutesObject.new([ route_1, route_2 ])
|
data/spec/spec_helpers/schema.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
if ENV['USE_MYSQL']
|
2
|
-
ActiveRecord::Base.establish_connection(:adapter => 'mysql2', :database => 'test', :username => 'root', :password => '', :host => '127.0.0.1')
|
2
|
+
ActiveRecord::Base.establish_connection(:adapter => 'mysql2', :database => 'test', :username => 'root', :password => '', :host => '127.0.0.1', variables: { sql_mode: "STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION" })
|
3
3
|
else
|
4
4
|
ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => ':memory:')
|
5
5
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: brainstem
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mavenlink
|
@@ -192,6 +192,20 @@ dependencies:
|
|
192
192
|
- - ">="
|
193
193
|
- !ruby/object:Gem::Version
|
194
194
|
version: '0'
|
195
|
+
- !ruby/object:Gem::Dependency
|
196
|
+
name: actionpack
|
197
|
+
requirement: !ruby/object:Gem::Requirement
|
198
|
+
requirements:
|
199
|
+
- - ">="
|
200
|
+
- !ruby/object:Gem::Version
|
201
|
+
version: '0'
|
202
|
+
type: :development
|
203
|
+
prerelease: false
|
204
|
+
version_requirements: !ruby/object:Gem::Requirement
|
205
|
+
requirements:
|
206
|
+
- - ">="
|
207
|
+
- !ruby/object:Gem::Version
|
208
|
+
version: '0'
|
195
209
|
description: Brainstem allows you to create rich API presenters that know how to filter,
|
196
210
|
sort, and include associations.
|
197
211
|
email:
|