endpoint-flux 1.1.4
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/.gitignore +36 -0
- data/CONTRIBUTING.md +18 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +37 -0
- data/README.md +607 -0
- data/circle.yml +14 -0
- data/endpoint_flux.gemspec +18 -0
- data/lib/endpoint_flux.rb +20 -0
- data/lib/endpoint_flux/class_loader.rb +58 -0
- data/lib/endpoint_flux/config.rb +85 -0
- data/lib/endpoint_flux/config/interceptor.rb +23 -0
- data/lib/endpoint_flux/config/middleware.rb +38 -0
- data/lib/endpoint_flux/config/rescue_from.rb +28 -0
- data/lib/endpoint_flux/endpoint.rb +81 -0
- data/lib/endpoint_flux/exceptions.rb +10 -0
- data/lib/endpoint_flux/exceptions/base.rb +21 -0
- data/lib/endpoint_flux/exceptions/forbidden.rb +12 -0
- data/lib/endpoint_flux/exceptions/not_found.rb +12 -0
- data/lib/endpoint_flux/exceptions/service_unavailable.rb +12 -0
- data/lib/endpoint_flux/exceptions/unauthorized.rb +12 -0
- data/lib/endpoint_flux/exceptions/validation.rb +13 -0
- data/lib/endpoint_flux/middlewares.rb +8 -0
- data/lib/endpoint_flux/middlewares/authenticator/skip.rb +11 -0
- data/lib/endpoint_flux/middlewares/authorizator/skip.rb +11 -0
- data/lib/endpoint_flux/middlewares/decorator/add_status.rb +12 -0
- data/lib/endpoint_flux/middlewares/decorator/skip.rb +11 -0
- data/lib/endpoint_flux/middlewares/policy/skip.rb +11 -0
- data/lib/endpoint_flux/middlewares/validator/empty.rb +12 -0
- data/lib/endpoint_flux/rails/concerns/endpoint_controller.rb +43 -0
- data/lib/endpoint_flux/request.rb +17 -0
- data/lib/endpoint_flux/response.rb +30 -0
- data/lib/endpoint_flux/version.rb +3 -0
- data/spec/lib/class_loader_spec.rb +31 -0
- data/spec/lib/config/default_middlewares_spec.rb +21 -0
- data/spec/lib/config/endpoints_namespace_spec.rb +13 -0
- data/spec/lib/config/flow_spec.rb +8 -0
- data/spec/lib/config/interceptor_spec.rb +34 -0
- data/spec/lib/config/middleware_spec.rb +62 -0
- data/spec/lib/config/rescue_from_spec.rb +45 -0
- data/spec/lib/endpoint/flow_spec.rb +43 -0
- data/spec/lib/endpoint/middlewares_spec.rb +110 -0
- data/spec/lib/endpoint/perform_spec.rb +61 -0
- data/spec/lib/endpoint/rescue_from_spec.rb +61 -0
- data/spec/lib/endpoint_flux/rails/concerns/endpoint_controller_spec.rb +75 -0
- data/spec/lib/endpoint_flux/request_spec.rb +44 -0
- data/spec/lib/exceptions/forbidden_spec.rb +12 -0
- data/spec/lib/exceptions/not_found_spec.rb +12 -0
- data/spec/lib/exceptions/service_unavailable_spec.rb +12 -0
- data/spec/lib/exceptions/unauthorized_spec.rb +12 -0
- data/spec/lib/exceptions/validation_spec.rb +14 -0
- data/spec/lib/middlewares/authenticator/skip_spec.rb +5 -0
- data/spec/lib/middlewares/authorizator/skip_spec.rb +5 -0
- data/spec/lib/middlewares/decorator/add_status_spec.rb +17 -0
- data/spec/lib/middlewares/decorator/skip_spec.rb +5 -0
- data/spec/lib/middlewares/policy/skip_spec.rb +5 -0
- data/spec/lib/middlewares/shared_examples.rb +19 -0
- data/spec/lib/middlewares/validator/empty_spec.rb +15 -0
- data/spec/lib/response_spec.rb +131 -0
- data/spec/spec_helper.rb +52 -0
- metadata +157 -0
@@ -0,0 +1,110 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe EndpointFlux::Endpoint do
|
4
|
+
let(:klass) { class_double('Sample') }
|
5
|
+
|
6
|
+
before do
|
7
|
+
EndpointFlux.config EndpointFlux::Config.new
|
8
|
+
|
9
|
+
klass.include EndpointFlux::Endpoint
|
10
|
+
end
|
11
|
+
|
12
|
+
context 'with exceptions' do
|
13
|
+
it 'fails with wrong string' do
|
14
|
+
klass.flow [:validator]
|
15
|
+
|
16
|
+
expect do
|
17
|
+
klass.validator 'some_not_existing_class'
|
18
|
+
end.to raise_error('You must provide block or existing klass')
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'fails whit wrong class passed' do
|
22
|
+
stub_const 'EndpointFlux::Middlewares::Validator::SampleMiddleware', Class.new
|
23
|
+
|
24
|
+
klass.flow [:validator]
|
25
|
+
|
26
|
+
expect { klass.validator 'sample_middleware' }.to raise_error(
|
27
|
+
'The [EndpointFlux::Middlewares::Validator::SampleMiddleware] '\
|
28
|
+
'class should define perform class method'
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'when wrong param passed' do
|
33
|
+
it do
|
34
|
+
klass.flow [:validator]
|
35
|
+
|
36
|
+
expect { klass.validator 1334 }.to raise_error(
|
37
|
+
'You must provide block or existing klass'
|
38
|
+
)
|
39
|
+
end
|
40
|
+
|
41
|
+
it do
|
42
|
+
stub_const 'SampleMiddleware', Class.new
|
43
|
+
|
44
|
+
klass.flow [:validator]
|
45
|
+
|
46
|
+
expect { klass.validator SampleMiddleware }.to raise_error(
|
47
|
+
'You must provide block or existing klass'
|
48
|
+
)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe 'middlewares' do
|
54
|
+
before do
|
55
|
+
stub_const 'SomeNamespace::MiddlewareName::SampleMiddleware', Class.new
|
56
|
+
SomeNamespace::MiddlewareName::SampleMiddleware.class_eval do
|
57
|
+
def self.perform(*args)
|
58
|
+
args
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
EndpointFlux.config.middlewares_namespaces << 'some_namespace'
|
63
|
+
end
|
64
|
+
|
65
|
+
before do
|
66
|
+
klass.flow [:middleware_name]
|
67
|
+
end
|
68
|
+
|
69
|
+
let(:middleware) { klass.middleware_name.first }
|
70
|
+
|
71
|
+
it 'sets middleware with options' do
|
72
|
+
klass.middleware_name 'sample_middleware', some: :option
|
73
|
+
|
74
|
+
expect(middleware.klass).to be(SomeNamespace::MiddlewareName::SampleMiddleware)
|
75
|
+
expect(middleware.options).to eq(some: :option)
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'sets middleware' do
|
79
|
+
klass.middleware_name 'sample_middleware'
|
80
|
+
|
81
|
+
expect(middleware.klass).to be(SomeNamespace::MiddlewareName::SampleMiddleware)
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'does not add twice' do
|
85
|
+
klass.middleware_name 'sample_middleware'
|
86
|
+
klass.middleware_name 'sample_middleware'
|
87
|
+
|
88
|
+
middleware = klass.middleware_name.first
|
89
|
+
|
90
|
+
expect(middleware.klass).to be(SomeNamespace::MiddlewareName::SampleMiddleware)
|
91
|
+
end
|
92
|
+
|
93
|
+
context 'block' do
|
94
|
+
let(:block) { proc {} }
|
95
|
+
|
96
|
+
it 'sets middleware' do
|
97
|
+
klass.middleware_name(&block)
|
98
|
+
|
99
|
+
expect(middleware.handler).to be == block
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'does not adds twice' do
|
103
|
+
klass.middleware_name(&block)
|
104
|
+
klass.middleware_name(&block)
|
105
|
+
|
106
|
+
expect(middleware.handler).to be == block
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe EndpointFlux::Endpoint do
|
4
|
+
let(:klass) { stub_const 'Sample', Class.new }
|
5
|
+
let(:middleware_request) { EndpointFlux::Request.new(headers: {}, params: params) }
|
6
|
+
let(:middleware_response) { EndpointFlux::Response.new }
|
7
|
+
|
8
|
+
before do
|
9
|
+
EndpointFlux.config EndpointFlux::Config.new
|
10
|
+
|
11
|
+
klass.include EndpointFlux::Endpoint
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '#perform' do
|
15
|
+
before do
|
16
|
+
stub_const 'EndpointFlux::Middlewares::Validator::SampleValidator', Class.new
|
17
|
+
EndpointFlux::Middlewares::Validator::SampleValidator.class_eval do
|
18
|
+
def self.perform(request, response, _)
|
19
|
+
request.params = {}
|
20
|
+
[request, response, {}]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
let(:params) { { some: :val } }
|
26
|
+
|
27
|
+
it 'checks if middleware exists' do
|
28
|
+
klass.flow [:validator]
|
29
|
+
|
30
|
+
expect { klass.perform(middleware_request) }
|
31
|
+
.to raise_error('No middleware registred for [:validator]')
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'middleware passed as string' do
|
35
|
+
it 'runs middleware passed as string' do
|
36
|
+
klass.flow [:validator]
|
37
|
+
klass.validator 'sample_validator'
|
38
|
+
|
39
|
+
request, response = klass.perform(middleware_request)
|
40
|
+
|
41
|
+
expect(request.params).to eq({})
|
42
|
+
expect(response.body).to eq({})
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'default middleware' do
|
47
|
+
before do
|
48
|
+
klass.flow [:validator]
|
49
|
+
|
50
|
+
EndpointFlux.config.default_middlewares :validator, 'sample_validator'
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'uses default if not defined' do
|
54
|
+
request, response = klass.perform(middleware_request)
|
55
|
+
|
56
|
+
expect(request.params).to eq({})
|
57
|
+
expect(response.body).to eq({})
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe EndpointFlux::Endpoint do
|
4
|
+
let(:klass) { stub_const 'Sample', Class.new }
|
5
|
+
let(:middleware_request) { EndpointFlux::Request.new(headers: {}, params: {}) }
|
6
|
+
let(:middleware_response) { EndpointFlux::Response.new }
|
7
|
+
|
8
|
+
before do
|
9
|
+
EndpointFlux.config EndpointFlux::Config.new
|
10
|
+
|
11
|
+
klass.include EndpointFlux::Endpoint
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '#rescue_from' do
|
15
|
+
let(:sample_exception) { stub_const 'SampleException', Class.new(Exception) }
|
16
|
+
let!(:sample_validator) do
|
17
|
+
stub_const 'EndpointFlux::Middlewares::Validator::Sample', Class.new
|
18
|
+
EndpointFlux::Middlewares::Validator::Sample.class_eval do
|
19
|
+
def self.perform(*)
|
20
|
+
raise SampleException, 'bla bla'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
EndpointFlux::Middlewares::Validator::Sample
|
24
|
+
end
|
25
|
+
let!(:sample_decorator) do
|
26
|
+
stub_const 'EndpointFlux::Middlewares::Decorator::Sample', Class.new
|
27
|
+
EndpointFlux::Middlewares::Decorator::Sample.class_eval do
|
28
|
+
def self.perform(request, response, options)
|
29
|
+
response.body[:decorator] = true
|
30
|
+
[request, response, options]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
EndpointFlux::Middlewares::Decorator::Sample
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'fails if exception not found' do
|
37
|
+
expect do
|
38
|
+
EndpointFlux.config.rescue_from 'NonExsistingClasss' do |_, attrs|
|
39
|
+
# code
|
40
|
+
end
|
41
|
+
end.to raise_error('The [NonExsistingClasss] should be a string representing a class')
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'default middleware' do
|
45
|
+
before do
|
46
|
+
klass.flow %i[validator decorator]
|
47
|
+
klass.validator 'sample'
|
48
|
+
klass.decorator 'sample'
|
49
|
+
|
50
|
+
EndpointFlux.config.rescue_from sample_exception do |_, attrs|
|
51
|
+
[attrs[0], attrs[1], { status: false }]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'uses default if not defined' do
|
56
|
+
_, response = klass.perform(middleware_request)
|
57
|
+
expect(response.body[:status]).to be_falsey
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module ActiveSupport
|
2
|
+
module Concern ; end
|
3
|
+
end
|
4
|
+
|
5
|
+
require 'spec_helper'
|
6
|
+
require 'endpoint_flux/rails/concerns/endpoint_controller'
|
7
|
+
require 'ostruct'
|
8
|
+
|
9
|
+
class RemoteIpDummyClass
|
10
|
+
include EndpointFlux::Rails::Concerns::EndpointController
|
11
|
+
|
12
|
+
def headers
|
13
|
+
{}
|
14
|
+
end
|
15
|
+
|
16
|
+
def request
|
17
|
+
OpenStruct.new(
|
18
|
+
headers: { 'authorization' => 'authorization header' },
|
19
|
+
remote_ip: '172.18.0.1',
|
20
|
+
env: { 'HTTP_X_FORWARDED_FOR' => '172.18.0.2' }
|
21
|
+
)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class LocalIpDummyClass
|
26
|
+
include EndpointFlux::Rails::Concerns::EndpointController
|
27
|
+
|
28
|
+
def headers
|
29
|
+
{}
|
30
|
+
end
|
31
|
+
|
32
|
+
def request
|
33
|
+
OpenStruct.new(
|
34
|
+
headers: { 'authorization' => 'authorization header' },
|
35
|
+
remote_ip: '127.0.0.1',
|
36
|
+
env: { 'HTTP_X_FORWARDED_FOR' => '172.18.0.2' }
|
37
|
+
)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
RSpec.describe EndpointFlux::Rails::Concerns::EndpointController do
|
42
|
+
describe '#request_object' do
|
43
|
+
before do
|
44
|
+
allow(subject).to receive(:endpoint_params).and_return({})
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'remote ip' do
|
48
|
+
subject { RemoteIpDummyClass.new }
|
49
|
+
|
50
|
+
it 'sets property as remote_ip' do
|
51
|
+
expect(
|
52
|
+
::EndpointFlux::Request
|
53
|
+
).to receive(:new).with(headers: { 'Authorization' => 'authorization header' },
|
54
|
+
params: subject.endpoint_params,
|
55
|
+
remote_ip: subject.request.remote_ip)
|
56
|
+
|
57
|
+
subject.request_object
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'local ip' do
|
62
|
+
subject { LocalIpDummyClass.new }
|
63
|
+
|
64
|
+
it 'sets property as HTTP_X_FORWARDED_FOR' do
|
65
|
+
expect(
|
66
|
+
::EndpointFlux::Request
|
67
|
+
).to receive(:new).with(headers: { 'Authorization' => 'authorization header' },
|
68
|
+
params: subject.endpoint_params,
|
69
|
+
remote_ip: subject.request.env['HTTP_X_FORWARDED_FOR'])
|
70
|
+
|
71
|
+
subject.request_object
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe EndpointFlux::Request do
|
4
|
+
it { should respond_to :headers }
|
5
|
+
it { should respond_to :remote_ip }
|
6
|
+
it { should respond_to :params }
|
7
|
+
it { should respond_to :namespace }
|
8
|
+
it { should respond_to :endpoint }
|
9
|
+
it { should respond_to :scope }
|
10
|
+
|
11
|
+
describe '#initialize' do
|
12
|
+
context 'when all params specified' do
|
13
|
+
let(:params) { { param: :val } }
|
14
|
+
let(:headers) { { header: :val } }
|
15
|
+
let(:remote_ip) { '127.0.0.1' }
|
16
|
+
let(:namespace) { 'namespace' }
|
17
|
+
|
18
|
+
it 'should set args' do
|
19
|
+
request = EndpointFlux::Request.new(
|
20
|
+
params: params,
|
21
|
+
headers: headers,
|
22
|
+
remote_ip: remote_ip,
|
23
|
+
namespace: namespace
|
24
|
+
)
|
25
|
+
|
26
|
+
expect(request.params).to eq params
|
27
|
+
expect(request.headers).to eq headers
|
28
|
+
expect(request.remote_ip).to eq remote_ip
|
29
|
+
expect(request.namespace).to eq namespace
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'when params missed' do
|
33
|
+
it 'should set default values' do
|
34
|
+
request = EndpointFlux::Request.new
|
35
|
+
|
36
|
+
expect(request.params).to be_empty
|
37
|
+
expect(request.headers).to be_empty
|
38
|
+
expect(request.remote_ip).to eq ''
|
39
|
+
expect(request.namespace).to be_nil
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe EndpointFlux::Exceptions::Validation do
|
4
|
+
describe '#to_hash' do
|
5
|
+
let(:messages) { {name: 'not valid'} }
|
6
|
+
it 'returns correct hash' do
|
7
|
+
expect(EndpointFlux::Exceptions::Validation.new(messages).to_hash).to eq(
|
8
|
+
status: 422,
|
9
|
+
message: 'validation errors',
|
10
|
+
errors: messages
|
11
|
+
)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
RSpec.describe EndpointFlux::Middlewares::Decorator::AddStatus do
|
2
|
+
describe '#perform' do
|
3
|
+
let(:params) { { some: 'value' } }
|
4
|
+
let(:body) { { status: 200 } }
|
5
|
+
let(:request) { EndpointFlux::Request.new(headers: {}, params: params) }
|
6
|
+
let(:response) { EndpointFlux::Response.new(headers: {}, body: body) }
|
7
|
+
|
8
|
+
it 'returns response with status in body' do
|
9
|
+
middleware_request, middleware_response = subject.perform(request, response, {})
|
10
|
+
|
11
|
+
expect(middleware_request.headers).to eq({})
|
12
|
+
expect(middleware_request.params).to eq(params)
|
13
|
+
expect(middleware_response.headers).to eq({})
|
14
|
+
expect(middleware_response.body).to eq(body)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|