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.
Files changed (49) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +120 -0
  3. data/lib/rapid_api/action_controller/errors.rb +75 -0
  4. data/lib/rapid_api/action_controller/filterable_params.rb +29 -0
  5. data/lib/rapid_api/action_controller/macros.rb +28 -0
  6. data/lib/rapid_api/action_controller/permitted_params.rb +38 -0
  7. data/lib/rapid_api/action_controller/rest_actions.rb +158 -0
  8. data/lib/rapid_api/action_controller/scope.rb +44 -0
  9. data/lib/rapid_api/action_controller.rb +11 -0
  10. data/lib/rapid_api/auth/concerns/authenticated_controller.rb +54 -0
  11. data/lib/rapid_api/auth/concerns/jwt_helpers.rb +33 -0
  12. data/lib/rapid_api/auth/concerns/sessions_controller.rb +49 -0
  13. data/lib/rapid_api/auth/concerns.rb +11 -0
  14. data/lib/rapid_api/auth/support/jwt.rb +28 -0
  15. data/lib/rapid_api/auth/support.rb +9 -0
  16. data/lib/rapid_api/auth.rb +8 -0
  17. data/lib/rapid_api/configuration.rb +11 -0
  18. data/lib/rapid_api/model_adapters/abstract.rb +33 -0
  19. data/lib/rapid_api/model_adapters/active_record_adapter.rb +49 -0
  20. data/lib/rapid_api/model_adapters/query_result.rb +22 -0
  21. data/lib/rapid_api/model_adapters.rb +9 -0
  22. data/lib/rapid_api/serializer_adapters/abstract.rb +22 -0
  23. data/lib/rapid_api/serializer_adapters/ams_adapter.rb +20 -0
  24. data/lib/rapid_api/serializer_adapters.rb +8 -0
  25. data/lib/rapid_api/version.rb +3 -0
  26. data/lib/rapid_api.rb +36 -0
  27. data/test/integration/ams_ar_test.rb +44 -0
  28. data/test/support/code_climate.rb +2 -0
  29. data/test/support/models.rb +24 -0
  30. data/test/support/schema.rb +14 -0
  31. data/test/support/serializers.rb +7 -0
  32. data/test/support/test_model_adapter.rb +23 -0
  33. data/test/support/test_module/test_model_adapter.rb +25 -0
  34. data/test/support/test_serializer_adapter.rb +10 -0
  35. data/test/test_helper.rb +28 -0
  36. data/test/unit/rapid_api/action_controller/errors_test.rb +53 -0
  37. data/test/unit/rapid_api/action_controller/filterable_params_test.rb +32 -0
  38. data/test/unit/rapid_api/action_controller/permitted_params_test.rb +30 -0
  39. data/test/unit/rapid_api/action_controller/rest_actions_test.rb +160 -0
  40. data/test/unit/rapid_api/action_controller/scope_test.rb +29 -0
  41. data/test/unit/rapid_api/auth/concerns/authenticated_controller_test.rb +56 -0
  42. data/test/unit/rapid_api/auth/concerns/sessions_controller_test.rb +55 -0
  43. data/test/unit/rapid_api/auth/support/jwt_test.rb +28 -0
  44. data/test/unit/rapid_api/model_adapters/abstract_test.rb +45 -0
  45. data/test/unit/rapid_api/model_adapters/active_record_adapter_test.rb +121 -0
  46. data/test/unit/rapid_api/serializer_adapters/abstract_test.rb +27 -0
  47. data/test/unit/rapid_api/serializer_adapters/ams_adapter_test.rb +31 -0
  48. data/test/unit/rapid_api/test_configuration.rb +17 -0
  49. metadata +197 -0
@@ -0,0 +1,9 @@
1
+ require 'rapid_api/auth/support/jwt'
2
+
3
+ module RapidApi
4
+ module Auth
5
+ module Support
6
+
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,8 @@
1
+ require 'rapid_api/auth/concerns'
2
+ require 'rapid_api/auth/support'
3
+
4
+ module RapidApi
5
+ module Auth
6
+
7
+ end
8
+ end
@@ -0,0 +1,11 @@
1
+ module RapidApi
2
+ class Configuration
3
+ include Singleton
4
+
5
+ attr_accessor :model_adapter,
6
+ :serializer_adapter,
7
+ :auth_model,
8
+ :response_codes
9
+
10
+ end
11
+ end
@@ -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,9 @@
1
+ require 'rapid_api/model_adapters/abstract'
2
+ require 'rapid_api/model_adapters/query_result'
3
+ require 'rapid_api/model_adapters/active_record_adapter'
4
+
5
+ module RapidApi
6
+ module ModelAdapters
7
+
8
+ end
9
+ 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
@@ -0,0 +1,8 @@
1
+ require 'rapid_api/serializer_adapters/abstract'
2
+ require 'rapid_api/serializer_adapters/ams_adapter'
3
+
4
+ module RapidApi
5
+ module SerializerAdapters
6
+
7
+ end
8
+ end
@@ -0,0 +1,3 @@
1
+ module RapidApi
2
+ VERSION = "0.1.0"
3
+ 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,2 @@
1
+ # require "codeclimate-test-reporter"
2
+ # CodeClimate::TestReporter.start
@@ -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,7 @@
1
+ require 'active_model_serializers'
2
+
3
+ class BrickSerializer < ActiveModel::Serializer
4
+ attributes :color,
5
+ :weight,
6
+ :material
7
+ 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
@@ -0,0 +1,10 @@
1
+ class TestSerializerAdapter < RapidApi::SerializerAdapters::Abstract
2
+ def serialize(member)
3
+ return nil
4
+ end
5
+
6
+ def serializer_collection(collection)
7
+ return nil
8
+ end
9
+
10
+ end
@@ -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