endpoint-flux 1.1.1
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 +17 -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 +32 -0
- data/lib/endpoint_flux/request.rb +15 -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/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 +153 -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,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
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.shared_context 'perform does not change the params', shared_context: :metadata do
|
4
|
+
describe '#perform' do
|
5
|
+
let(:params) { { some: 'value' } }
|
6
|
+
let(:headers) { { 'Authorization' => 'valid' } }
|
7
|
+
let(:request) { EndpointFlux::Request.new(headers: headers, params: params) }
|
8
|
+
let(:response) { EndpointFlux::Response.new(headers: {}, body: {}) }
|
9
|
+
|
10
|
+
it 'returns not changed params' do
|
11
|
+
middleware_request, middleware_response = subject.perform(request, response, {})
|
12
|
+
|
13
|
+
expect(middleware_request.params).to eq(params)
|
14
|
+
expect(middleware_request.headers).to eq(headers)
|
15
|
+
expect(middleware_response.headers).to eq({})
|
16
|
+
expect(middleware_response.body).to eq({})
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
RSpec.describe EndpointFlux::Middlewares::Validator::Empty do
|
2
|
+
describe '#perform' do
|
3
|
+
let(:params) { { some: 'value' } }
|
4
|
+
let(:request) { EndpointFlux::Request.new(headers: {}, params: params) }
|
5
|
+
let(:response) { EndpointFlux::Response.new }
|
6
|
+
|
7
|
+
it 'returns empty params' do
|
8
|
+
middleware_request, middleware_response = subject.perform(request, response, {})
|
9
|
+
|
10
|
+
expect(middleware_request.params).to eq({})
|
11
|
+
expect(middleware_response.headers).to eq({})
|
12
|
+
expect(middleware_response.body).to eq({})
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe EndpointFlux::Response do
|
4
|
+
subject { EndpointFlux::Response.new(params) }
|
5
|
+
let(:empty_subject) { EndpointFlux::Response.new() }
|
6
|
+
|
7
|
+
describe '#success?' do
|
8
|
+
context 'when valid params given' do
|
9
|
+
Array(200..209).each do |status|
|
10
|
+
let(:params) { { headers: {}, body: {status: status} } }
|
11
|
+
it "returns true for status #{status}" do
|
12
|
+
expect(subject.success?).to be_truthy
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'when wrong params given' do
|
18
|
+
let(:status) { 400 }
|
19
|
+
let(:params) { { headers: {}, body: {status: status} } }
|
20
|
+
it 'returns false for not a success status' do
|
21
|
+
expect(subject.success?).to be_falsey
|
22
|
+
end
|
23
|
+
|
24
|
+
describe 'when Response initialized without params' do
|
25
|
+
it 'returns false for not a success status' do
|
26
|
+
expect(empty_subject.success?).to be_falsey
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe '#invalid?' do
|
33
|
+
let(:params) { { headers: {}, body: {status: status} } }
|
34
|
+
context 'when valid params given' do
|
35
|
+
let(:status) { 422 }
|
36
|
+
|
37
|
+
it 'returns true for status 422' do
|
38
|
+
expect(subject.invalid?).to be_truthy
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'when wrong params given' do
|
43
|
+
let(:status) { 400 }
|
44
|
+
|
45
|
+
it 'returns false for not an invalid status' do
|
46
|
+
expect(subject.invalid?).to be_falsey
|
47
|
+
end
|
48
|
+
|
49
|
+
describe 'when Response initialized without params' do
|
50
|
+
it 'returns false for not an invalid status' do
|
51
|
+
expect(empty_subject.invalid?).to be_falsey
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe '#forbidden?' do
|
58
|
+
let(:params) { { headers: {}, body: {status: status} } }
|
59
|
+
context 'when valid params given' do
|
60
|
+
let(:status) { 403 }
|
61
|
+
|
62
|
+
it 'returns true for status 403' do
|
63
|
+
expect(subject.forbidden?).to be_truthy
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'when wrong params given' do
|
68
|
+
let(:status) { 400 }
|
69
|
+
|
70
|
+
it 'returns false for not a forbidden status' do
|
71
|
+
expect(subject.forbidden?).to be_falsey
|
72
|
+
end
|
73
|
+
|
74
|
+
describe 'when Response initialized without params' do
|
75
|
+
it 'returns false for not a forbidden status' do
|
76
|
+
expect(empty_subject.forbidden?).to be_falsey
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe '#unauthorized?' do
|
83
|
+
let(:params) { { headers: {}, body: {status: status} } }
|
84
|
+
context 'when valid params given' do
|
85
|
+
let(:status) { 401 }
|
86
|
+
|
87
|
+
it 'returns true for status 401' do
|
88
|
+
expect(subject.unauthorized?).to be_truthy
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
context 'when wrong params given' do
|
93
|
+
let(:status) { 400 }
|
94
|
+
|
95
|
+
it 'returns false for not a unauthorized status' do
|
96
|
+
expect(subject.unauthorized?).to be_falsey
|
97
|
+
end
|
98
|
+
|
99
|
+
describe 'when Response initialized without params' do
|
100
|
+
it 'returns false for not a unauthorized status' do
|
101
|
+
expect(empty_subject.unauthorized?).to be_falsey
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
describe '#unauthorized?' do
|
108
|
+
let(:params) { { headers: {}, body: {status: status} } }
|
109
|
+
context 'when valid params given' do
|
110
|
+
let(:status) { 404 }
|
111
|
+
|
112
|
+
it 'returns true for status 404' do
|
113
|
+
expect(subject.not_found?).to be_truthy
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
context 'when wrong params given' do
|
118
|
+
let(:status) { 400 }
|
119
|
+
|
120
|
+
it 'returns false for not a not_found status' do
|
121
|
+
expect(subject.not_found?).to be_falsey
|
122
|
+
end
|
123
|
+
|
124
|
+
describe 'when Response initialized without params' do
|
125
|
+
it 'returns false for not a not_found status' do
|
126
|
+
expect(empty_subject.not_found?).to be_falsey
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|