rapid_api 0.1.0
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 +7 -0
- data/README.md +120 -0
- data/lib/rapid_api/action_controller/errors.rb +75 -0
- data/lib/rapid_api/action_controller/filterable_params.rb +29 -0
- data/lib/rapid_api/action_controller/macros.rb +28 -0
- data/lib/rapid_api/action_controller/permitted_params.rb +38 -0
- data/lib/rapid_api/action_controller/rest_actions.rb +158 -0
- data/lib/rapid_api/action_controller/scope.rb +44 -0
- data/lib/rapid_api/action_controller.rb +11 -0
- data/lib/rapid_api/auth/concerns/authenticated_controller.rb +54 -0
- data/lib/rapid_api/auth/concerns/jwt_helpers.rb +33 -0
- data/lib/rapid_api/auth/concerns/sessions_controller.rb +49 -0
- data/lib/rapid_api/auth/concerns.rb +11 -0
- data/lib/rapid_api/auth/support/jwt.rb +28 -0
- data/lib/rapid_api/auth/support.rb +9 -0
- data/lib/rapid_api/auth.rb +8 -0
- data/lib/rapid_api/configuration.rb +11 -0
- data/lib/rapid_api/model_adapters/abstract.rb +33 -0
- data/lib/rapid_api/model_adapters/active_record_adapter.rb +49 -0
- data/lib/rapid_api/model_adapters/query_result.rb +22 -0
- data/lib/rapid_api/model_adapters.rb +9 -0
- data/lib/rapid_api/serializer_adapters/abstract.rb +22 -0
- data/lib/rapid_api/serializer_adapters/ams_adapter.rb +20 -0
- data/lib/rapid_api/serializer_adapters.rb +8 -0
- data/lib/rapid_api/version.rb +3 -0
- data/lib/rapid_api.rb +36 -0
- data/test/integration/ams_ar_test.rb +44 -0
- data/test/support/code_climate.rb +2 -0
- data/test/support/models.rb +24 -0
- data/test/support/schema.rb +14 -0
- data/test/support/serializers.rb +7 -0
- data/test/support/test_model_adapter.rb +23 -0
- data/test/support/test_module/test_model_adapter.rb +25 -0
- data/test/support/test_serializer_adapter.rb +10 -0
- data/test/test_helper.rb +28 -0
- data/test/unit/rapid_api/action_controller/errors_test.rb +53 -0
- data/test/unit/rapid_api/action_controller/filterable_params_test.rb +32 -0
- data/test/unit/rapid_api/action_controller/permitted_params_test.rb +30 -0
- data/test/unit/rapid_api/action_controller/rest_actions_test.rb +160 -0
- data/test/unit/rapid_api/action_controller/scope_test.rb +29 -0
- data/test/unit/rapid_api/auth/concerns/authenticated_controller_test.rb +56 -0
- data/test/unit/rapid_api/auth/concerns/sessions_controller_test.rb +55 -0
- data/test/unit/rapid_api/auth/support/jwt_test.rb +28 -0
- data/test/unit/rapid_api/model_adapters/abstract_test.rb +45 -0
- data/test/unit/rapid_api/model_adapters/active_record_adapter_test.rb +121 -0
- data/test/unit/rapid_api/serializer_adapters/abstract_test.rb +27 -0
- data/test/unit/rapid_api/serializer_adapters/ams_adapter_test.rb +31 -0
- data/test/unit/rapid_api/test_configuration.rb +17 -0
- metadata +197 -0
@@ -0,0 +1,33 @@
|
|
1
|
+
module RapidApi
|
2
|
+
module ModelAdapters
|
3
|
+
class Abstract
|
4
|
+
|
5
|
+
attr_accessor :klass
|
6
|
+
|
7
|
+
def initialize(klass)
|
8
|
+
@klass = klass
|
9
|
+
end
|
10
|
+
|
11
|
+
def find(_id, _scope=nil)
|
12
|
+
raise NotImplementedError
|
13
|
+
end
|
14
|
+
|
15
|
+
def find_all(_params=nil, _scope=nil)
|
16
|
+
raise NotImplementedError
|
17
|
+
end
|
18
|
+
|
19
|
+
def create(_params, _scope=nil)
|
20
|
+
raise NotImplementedError
|
21
|
+
end
|
22
|
+
|
23
|
+
def update(_id, _params, _scope=nil)
|
24
|
+
raise NotImplementedError
|
25
|
+
end
|
26
|
+
|
27
|
+
def destroy(_id, _scope=nil)
|
28
|
+
raise NotImplementedError
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module RapidApi
|
2
|
+
module ModelAdapters
|
3
|
+
class ActiveRecordAdapter < Abstract
|
4
|
+
|
5
|
+
def find(id, scope=nil)
|
6
|
+
member = _find_member_with_scope(id, scope)
|
7
|
+
QueryResult.new data: member
|
8
|
+
end
|
9
|
+
|
10
|
+
def find_all(params=nil, scope=nil)
|
11
|
+
params ||= {}
|
12
|
+
scope ||= {}
|
13
|
+
scoped_params = params.merge scope
|
14
|
+
collection = klass.where(scoped_params)
|
15
|
+
QueryResult.new data: collection
|
16
|
+
end
|
17
|
+
|
18
|
+
def create(params, scope=nil)
|
19
|
+
scope ||= {}
|
20
|
+
create_params = params.merge scope
|
21
|
+
member = klass.create create_params
|
22
|
+
_query_result_for_member member
|
23
|
+
end
|
24
|
+
|
25
|
+
def update(id, params, scope=nil)
|
26
|
+
member = _find_member_with_scope(id, scope)
|
27
|
+
member.update_attributes params
|
28
|
+
_query_result_for_member member
|
29
|
+
end
|
30
|
+
|
31
|
+
def destroy(id, scope=nil)
|
32
|
+
member = _find_member_with_scope(id, scope)
|
33
|
+
member.destroy
|
34
|
+
_query_result_for_member member
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def _query_result_for_member(member)
|
40
|
+
QueryResult.new data: member, errors: member.errors
|
41
|
+
end
|
42
|
+
|
43
|
+
def _find_member_with_scope(id, scope)
|
44
|
+
klass.where(scope).where(id: id).first
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module RapidApi
|
2
|
+
module ModelAdapters
|
3
|
+
|
4
|
+
class QueryResult
|
5
|
+
attr_accessor :errors, :data
|
6
|
+
|
7
|
+
def initialize(data: nil, errors: nil)
|
8
|
+
@data = data
|
9
|
+
@errors = errors
|
10
|
+
end
|
11
|
+
|
12
|
+
def has_errors?
|
13
|
+
errors.present?
|
14
|
+
end
|
15
|
+
|
16
|
+
def found?
|
17
|
+
data.present?
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module RapidApi
|
2
|
+
module SerializerAdapters
|
3
|
+
class Abstract
|
4
|
+
|
5
|
+
attr_accessor :klass, :root_key
|
6
|
+
|
7
|
+
def initialize(klass, root_key)
|
8
|
+
@klass = klass
|
9
|
+
@root_key = root_key
|
10
|
+
end
|
11
|
+
|
12
|
+
def serialize(_member)
|
13
|
+
raise NotImplementedError
|
14
|
+
end
|
15
|
+
|
16
|
+
def serialize_collection(_collection)
|
17
|
+
raise NotImplementedError
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module RapidApi
|
2
|
+
module SerializerAdapters
|
3
|
+
class AmsAdapter < Abstract
|
4
|
+
|
5
|
+
def serialize(member)
|
6
|
+
serializer = klass.new(member)
|
7
|
+
serializer.to_json
|
8
|
+
end
|
9
|
+
|
10
|
+
def serialize_collection(collection)
|
11
|
+
array_serializer = ActiveModel::ArraySerializer.new collection, {
|
12
|
+
each_serializer: klass
|
13
|
+
}
|
14
|
+
array_serializer.root = root_key.pluralize
|
15
|
+
array_serializer.to_json
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/rapid_api.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'rapid_api/version'
|
2
|
+
require 'active_support/concern'
|
3
|
+
require 'rapid_api/model_adapters'
|
4
|
+
require 'rapid_api/serializer_adapters'
|
5
|
+
require 'rapid_api/action_controller'
|
6
|
+
require 'rapid_api/auth'
|
7
|
+
require 'rapid_api/configuration'
|
8
|
+
|
9
|
+
module RapidApi
|
10
|
+
|
11
|
+
Configuration.instance.tap do |c|
|
12
|
+
c.model_adapter = ModelAdapters::ActiveRecordAdapter
|
13
|
+
c.serializer_adapter = SerializerAdapters::AmsAdapter
|
14
|
+
c.response_codes = {
|
15
|
+
:ok => :ok,
|
16
|
+
:created => :created,
|
17
|
+
:not_found => :not_found,
|
18
|
+
:unprocessable_entity => :unprocessable_entity,
|
19
|
+
:unauthorized => :unauthorized,
|
20
|
+
:internal_server_error => :internal_server_error
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.config
|
25
|
+
Configuration.instance
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
if defined?(ActionController::Base)
|
31
|
+
ActionController::Base.send :include, RapidApi::ActionController::Macros
|
32
|
+
end
|
33
|
+
|
34
|
+
if defined?(ActionController::API)
|
35
|
+
ActionController::API.send :include, RapidApi::ActionController::Macros
|
36
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require File.expand_path '../../test_helper.rb', __FILE__
|
2
|
+
|
3
|
+
class AmsArTest < ActionController::TestCase
|
4
|
+
class AmsArIntegrationController < ActionController::Base
|
5
|
+
include RapidApi::ActionController::Errors
|
6
|
+
|
7
|
+
rapid_actions model: Brick, serializer: BrickSerializer
|
8
|
+
|
9
|
+
scope_by :user_id do |controller|
|
10
|
+
controller.params['user_id']
|
11
|
+
end
|
12
|
+
|
13
|
+
permit_params :color, :weight, :material
|
14
|
+
end
|
15
|
+
|
16
|
+
tests AmsArIntegrationController
|
17
|
+
|
18
|
+
def setup
|
19
|
+
super
|
20
|
+
DatabaseCleaner.start
|
21
|
+
Brick.delete_all
|
22
|
+
@user1 = User.create
|
23
|
+
@user2 = User.create
|
24
|
+
end
|
25
|
+
|
26
|
+
def teardown
|
27
|
+
DatabaseCleaner.clean
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_index
|
31
|
+
Brick.destroy_all
|
32
|
+
brick1 = @user1.bricks.create color: 'yellow', weight: 10, material: 'gold'
|
33
|
+
brick2 = @user1.bricks.create color: 'red', weight: 1, material: 'clay'
|
34
|
+
brick3 = @user2.bricks.create color: 'magenta', weight: 0, material: 'feathers'
|
35
|
+
get :index, { user_id: @user1.id }
|
36
|
+
assert_equal "{\"bricks\":[{\"color\":\"yellow\",\"weight\":\"10.0\",\"material\":\"gold\"},{\"color\":\"red\",\"weight\":\"1.0\",\"material\":\"clay\"}]}", response.body
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_show
|
40
|
+
brick = Brick.create color: 'red', weight: 1, material: 'clay'
|
41
|
+
get :show, {id: brick.id}
|
42
|
+
assert_equal "{\"brick\":{\"color\":\"red\",\"weight\":\"1.0\",\"material\":\"clay\"}}", response.body
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
require 'database_cleaner'
|
3
|
+
|
4
|
+
ActiveRecord::Base.establish_connection adapter: :sqlite3,
|
5
|
+
database: 'memory'
|
6
|
+
|
7
|
+
DatabaseCleaner.strategy = :transaction
|
8
|
+
|
9
|
+
class Brick < ActiveRecord::Base
|
10
|
+
validates_uniqueness_of :color
|
11
|
+
before_destroy :prevent_destroy
|
12
|
+
belongs_to :user
|
13
|
+
|
14
|
+
def prevent_destroy
|
15
|
+
errors.add(:base, "Destroy prevented") if color == 'prevent_destroy'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class User < ActiveRecord::Base
|
20
|
+
has_many :bricks
|
21
|
+
def find_and_authenticate(params)
|
22
|
+
where(username: params[:username], password: params[:password]).first
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
ActiveRecord::Schema.define do
|
2
|
+
connection.drop_table :bricks if connection.table_exists? :bricks
|
3
|
+
connection.drop_table :users if connection.table_exists? :users
|
4
|
+
create_table :bricks do |t|
|
5
|
+
t.string :color
|
6
|
+
t.decimal :weight
|
7
|
+
t.string :material
|
8
|
+
t.integer :user_id
|
9
|
+
end
|
10
|
+
create_table :users do |t|
|
11
|
+
t.string :username
|
12
|
+
t.string :password
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class TestModelAdapter < RapidApi::ModelAdapters::Abstract
|
2
|
+
|
3
|
+
def find(params, scope)
|
4
|
+
return nil
|
5
|
+
end
|
6
|
+
|
7
|
+
def find_all(params, scope)
|
8
|
+
return nil
|
9
|
+
end
|
10
|
+
|
11
|
+
def create(params, scope)
|
12
|
+
return nil
|
13
|
+
end
|
14
|
+
|
15
|
+
def update(params, scope)
|
16
|
+
return nil
|
17
|
+
end
|
18
|
+
|
19
|
+
def destroy(params, scope)
|
20
|
+
return nil
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module TestModule
|
2
|
+
class TestModelAdapter < RapidApi::ModelAdapters::Abstract
|
3
|
+
|
4
|
+
def find(params)
|
5
|
+
return nil
|
6
|
+
end
|
7
|
+
|
8
|
+
def find_all(params)
|
9
|
+
return nil
|
10
|
+
end
|
11
|
+
|
12
|
+
def create(params)
|
13
|
+
return nil
|
14
|
+
end
|
15
|
+
|
16
|
+
def update(params)
|
17
|
+
return nil
|
18
|
+
end
|
19
|
+
|
20
|
+
def destroy(params)
|
21
|
+
return nil
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'pry'
|
3
|
+
require 'rails'
|
4
|
+
require 'action_controller'
|
5
|
+
require 'action_controller/test_case'
|
6
|
+
require 'rapid_api'
|
7
|
+
require 'minitest/autorun'
|
8
|
+
|
9
|
+
Dir['./test/support/**/*.rb'].each {|f| require f}
|
10
|
+
|
11
|
+
module TestHelper
|
12
|
+
Routes = ActionDispatch::Routing::RouteSet.new
|
13
|
+
Routes.draw do
|
14
|
+
get ':controller(/:action(/:id))'
|
15
|
+
get ':controller(/:action)'
|
16
|
+
end
|
17
|
+
|
18
|
+
ActionController::Base.send :include, Routes.url_helpers
|
19
|
+
end
|
20
|
+
|
21
|
+
ActionController::TestCase.class_eval do
|
22
|
+
def setup
|
23
|
+
@routes = TestHelper::Routes
|
24
|
+
end
|
25
|
+
|
26
|
+
def teardown
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require File.expand_path '../../../../test_helper.rb', __FILE__
|
2
|
+
|
3
|
+
class ActionControllerErrorsTest < ActionController::TestCase
|
4
|
+
|
5
|
+
class TestErroneousController < ActionController::Base
|
6
|
+
include RapidApi::ActionController::Errors
|
7
|
+
|
8
|
+
def unauthenticated_action
|
9
|
+
not_authenticated!
|
10
|
+
end
|
11
|
+
|
12
|
+
def not_found_action
|
13
|
+
not_found!
|
14
|
+
end
|
15
|
+
|
16
|
+
def not_processable_action
|
17
|
+
brick = Brick.create
|
18
|
+
brick.errors.add(:base, 'Sample Error')
|
19
|
+
not_processable!(brick.errors)
|
20
|
+
end
|
21
|
+
|
22
|
+
def server_error_action
|
23
|
+
raise "server error message"
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
tests TestErroneousController
|
29
|
+
|
30
|
+
def test_unauthenticated_error
|
31
|
+
get :unauthenticated_action
|
32
|
+
assert_response :unauthorized
|
33
|
+
assert_equal ['Not Authenticated'], JSON.parse(@controller.response.body)['errors']
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_server_error
|
37
|
+
get :server_error_action
|
38
|
+
assert_response :internal_server_error
|
39
|
+
assert_equal ['Server Error: server error message'], JSON.parse(@controller.response.body)['errors']
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_not_found_error
|
43
|
+
get :not_found_action
|
44
|
+
assert_response :not_found
|
45
|
+
assert_equal ['Not Found'], JSON.parse(@controller.response.body)['errors']
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_not_processable_error
|
49
|
+
get :not_processable_action
|
50
|
+
assert_response :unprocessable_entity
|
51
|
+
assert_equal ['Sample Error'], JSON.parse(@controller.response.body)['errors']['base']
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require File.expand_path '../../../../test_helper.rb', __FILE__
|
2
|
+
|
3
|
+
module ActionController
|
4
|
+
|
5
|
+
class FilterableParamsTest < ActionController::TestCase
|
6
|
+
|
7
|
+
class TestFilterableParamsController < ActionController::Base
|
8
|
+
include RapidApi::ActionController::FilterableParams
|
9
|
+
|
10
|
+
filterable_params :color
|
11
|
+
|
12
|
+
def filterable_bricks
|
13
|
+
render json: filterable_params, status: :ok
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
tests TestFilterableParamsController
|
18
|
+
|
19
|
+
def test_permitted_filterable_params
|
20
|
+
assert :color.in?(@controller.class.permitted_filterable_params), "Attribute not added to filterable params."
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_filterable_params
|
24
|
+
post :filterable_bricks, { color: 'blue', material: 'steel' }
|
25
|
+
body = JSON.parse(@controller.response.body)
|
26
|
+
expected = { 'color' => 'blue' }
|
27
|
+
assert_equal expected, body
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require File.expand_path '../../../../test_helper.rb', __FILE__
|
2
|
+
|
3
|
+
module ActionController
|
4
|
+
|
5
|
+
class PermittedParamsTest < ActionController::TestCase
|
6
|
+
|
7
|
+
class BricksController < ActionController::Base
|
8
|
+
include RapidApi::ActionController::PermittedParams
|
9
|
+
|
10
|
+
permit_params :color
|
11
|
+
|
12
|
+
def permissive_bricks
|
13
|
+
render json: _permitted_params_for(:brick).to_json, status: :ok
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
tests BricksController
|
18
|
+
|
19
|
+
def test_permits_params
|
20
|
+
assert :color.in?(@controller.permitted_params), "Attribute not added to permitted params."
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_permitted_params_for
|
24
|
+
post :permissive_bricks, {brick: {color: 'red', weight: 1}}
|
25
|
+
refute response.body.include?("\"weight\":\"1.0\""), ":attribute should not have been permitted."
|
26
|
+
assert response.body.include?("\"color\":\"red\""), ":attribute should have been permitted."
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|