flipper-api 0.10.2 → 0.11.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/flipper-api.gemspec +12 -12
- data/lib/flipper/api/action.rb +12 -10
- data/lib/flipper/api/action_collection.rb +2 -2
- data/lib/flipper/api/error_response.rb +9 -8
- data/lib/flipper/api/json_params.rb +45 -0
- data/lib/flipper/api/middleware.rb +3 -28
- data/lib/flipper/api/v1/actions/actors_gate.rb +1 -9
- data/lib/flipper/api/v1/actions/boolean_gate.rb +1 -1
- data/lib/flipper/api/v1/actions/clear_feature.rb +21 -0
- data/lib/flipper/api/v1/actions/feature.rb +8 -16
- data/lib/flipper/api/v1/actions/features.rb +26 -8
- data/lib/flipper/api/v1/actions/groups_gate.rb +18 -7
- data/lib/flipper/api/v1/actions/percentage_of_actors_gate.rb +6 -24
- data/lib/flipper/api/v1/actions/percentage_of_time_gate.rb +6 -23
- data/lib/flipper/api/v1/decorators/feature.rb +3 -4
- data/lib/flipper/api.rb +11 -27
- data/lib/flipper/version.rb +1 -1
- data/spec/flipper/api/action_spec.rb +30 -36
- data/spec/flipper/api/json_params_spec.rb +81 -0
- data/spec/flipper/api/v1/actions/actors_gate_spec.rb +33 -22
- data/spec/flipper/api/v1/actions/boolean_gate_spec.rb +2 -2
- data/spec/flipper/api/v1/actions/clear_feature_spec.rb +27 -0
- data/spec/flipper/api/v1/actions/feature_spec.rb +28 -30
- data/spec/flipper/api/v1/actions/features_spec.rb +79 -44
- data/spec/flipper/api/v1/actions/groups_gate_spec.rb +92 -10
- data/spec/flipper/api/v1/actions/percentage_of_actors_gate_spec.rb +62 -24
- data/spec/flipper/api/v1/actions/percentage_of_time_gate_spec.rb +34 -15
- data/spec/flipper/api_spec.rb +55 -0
- metadata +15 -7
@@ -1,68 +1,66 @@
|
|
1
1
|
require 'helper'
|
2
2
|
|
3
3
|
RSpec.describe Flipper::Api::Action do
|
4
|
-
let(:action_subclass)
|
4
|
+
let(:action_subclass) do
|
5
5
|
Class.new(described_class) do
|
6
6
|
def noooope
|
7
|
-
raise
|
7
|
+
raise 'should never run this'
|
8
8
|
end
|
9
9
|
|
10
10
|
def get
|
11
|
-
[200, {},
|
11
|
+
[200, {}, 'get']
|
12
12
|
end
|
13
13
|
|
14
14
|
def post
|
15
|
-
[200, {},
|
15
|
+
[200, {}, 'post']
|
16
16
|
end
|
17
17
|
|
18
18
|
def put
|
19
|
-
[200, {},
|
19
|
+
[200, {}, 'put']
|
20
20
|
end
|
21
21
|
|
22
22
|
def delete
|
23
|
-
[200, {},
|
23
|
+
[200, {}, 'delete']
|
24
24
|
end
|
25
25
|
end
|
26
|
-
|
26
|
+
end
|
27
27
|
|
28
28
|
describe 'https verbs' do
|
29
|
-
|
30
29
|
it "won't run method that isn't whitelisted" do
|
31
|
-
fake_request = Struct.new(:request_method, :env, :session).new(
|
30
|
+
fake_request = Struct.new(:request_method, :env, :session).new('NOOOOPE', {}, {})
|
32
31
|
action = action_subclass.new(flipper, fake_request)
|
33
|
-
expect
|
32
|
+
expect do
|
34
33
|
action.run
|
35
|
-
|
34
|
+
end.to raise_error(Flipper::Api::RequestMethodNotSupported)
|
36
35
|
end
|
37
36
|
|
38
|
-
it
|
39
|
-
fake_request = Struct.new(:request_method, :env, :session).new(
|
37
|
+
it 'will run get' do
|
38
|
+
fake_request = Struct.new(:request_method, :env, :session).new('GET', {}, {})
|
40
39
|
action = action_subclass.new(flipper, fake_request)
|
41
|
-
expect(action.run).to eq([200, {},
|
40
|
+
expect(action.run).to eq([200, {}, 'get'])
|
42
41
|
end
|
43
42
|
|
44
|
-
it
|
45
|
-
fake_request = Struct.new(:request_method, :env, :session).new(
|
43
|
+
it 'will run post' do
|
44
|
+
fake_request = Struct.new(:request_method, :env, :session).new('POST', {}, {})
|
46
45
|
action = action_subclass.new(flipper, fake_request)
|
47
|
-
expect(action.run).to eq([200, {},
|
46
|
+
expect(action.run).to eq([200, {}, 'post'])
|
48
47
|
end
|
49
48
|
|
50
|
-
it
|
51
|
-
fake_request = Struct.new(:request_method, :env, :session).new(
|
49
|
+
it 'will run put' do
|
50
|
+
fake_request = Struct.new(:request_method, :env, :session).new('PUT', {}, {})
|
52
51
|
action = action_subclass.new(flipper, fake_request)
|
53
|
-
expect(action.run).to eq([200, {},
|
52
|
+
expect(action.run).to eq([200, {}, 'put'])
|
54
53
|
end
|
55
54
|
|
56
|
-
it
|
57
|
-
fake_request = Struct.new(:request_method, :env, :session).new(
|
55
|
+
it 'will run delete' do
|
56
|
+
fake_request = Struct.new(:request_method, :env, :session).new('DELETE', {}, {})
|
58
57
|
action = action_subclass.new(flipper, fake_request)
|
59
|
-
expect(action.run).to eq([200, {},
|
58
|
+
expect(action.run).to eq([200, {}, 'delete'])
|
60
59
|
end
|
61
60
|
end
|
62
61
|
|
63
62
|
describe '#json_error_response' do
|
64
|
-
describe
|
65
|
-
|
63
|
+
describe ':feature_not_found' do
|
66
64
|
it 'locates and serializes error correctly' do
|
67
65
|
action = action_subclass.new({}, {})
|
68
66
|
response = catch(:halt) do
|
@@ -71,15 +69,12 @@ RSpec.describe Flipper::Api::Action do
|
|
71
69
|
status, headers, body = response
|
72
70
|
parsed_body = JSON.parse(body[0])
|
73
71
|
|
74
|
-
expect(headers[
|
75
|
-
expect(parsed_body
|
76
|
-
expect(parsed_body["message"]).to eq("Feature not found.")
|
77
|
-
expect(parsed_body["more_info"]).to eq("https://github.com/jnunemaker/flipper/tree/master/docs/api#error-code-reference")
|
72
|
+
expect(headers['Content-Type']).to eq('application/json')
|
73
|
+
expect(parsed_body).to eql(api_not_found_response)
|
78
74
|
end
|
79
75
|
end
|
80
76
|
|
81
77
|
describe ':group_not_registered' do
|
82
|
-
|
83
78
|
it 'locates and serializes error correctly' do
|
84
79
|
action = action_subclass.new({}, {})
|
85
80
|
response = catch(:halt) do
|
@@ -88,19 +83,18 @@ RSpec.describe Flipper::Api::Action do
|
|
88
83
|
status, headers, body = response
|
89
84
|
parsed_body = JSON.parse(body[0])
|
90
85
|
|
91
|
-
expect(headers[
|
92
|
-
expect(parsed_body[
|
93
|
-
expect(parsed_body[
|
94
|
-
expect(parsed_body[
|
86
|
+
expect(headers['Content-Type']).to eq('application/json')
|
87
|
+
expect(parsed_body['code']).to eq(2)
|
88
|
+
expect(parsed_body['message']).to eq('Group not registered.')
|
89
|
+
expect(parsed_body['more_info']).to eq(api_error_code_reference_url)
|
95
90
|
end
|
96
91
|
end
|
97
92
|
|
98
93
|
describe 'invalid error key' do
|
99
|
-
|
100
94
|
it 'raises descriptive error' do
|
101
95
|
action = action_subclass.new({}, {})
|
102
96
|
catch(:halt) do
|
103
|
-
expect{ action.json_error_response(:invalid_error_key) }.to raise_error(KeyError)
|
97
|
+
expect { action.json_error_response(:invalid_error_key) }.to raise_error(KeyError)
|
104
98
|
end
|
105
99
|
end
|
106
100
|
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
RSpec.describe Flipper::Api::JsonParams do
|
4
|
+
let(:app) do
|
5
|
+
app = lambda do |env|
|
6
|
+
request = Rack::Request.new(env)
|
7
|
+
[200, { 'Content-Type' => 'application/json' }, [JSON.generate(request.params)]]
|
8
|
+
end
|
9
|
+
builder = Rack::Builder.new
|
10
|
+
builder.use described_class
|
11
|
+
builder.run app
|
12
|
+
builder
|
13
|
+
end
|
14
|
+
|
15
|
+
describe 'json post request' do
|
16
|
+
it 'adds request body to params' do
|
17
|
+
response = post '/',
|
18
|
+
JSON.generate(flipper_id: 'user:2'),
|
19
|
+
'CONTENT_TYPE' => 'application/json'
|
20
|
+
|
21
|
+
params = JSON.parse(response.body)
|
22
|
+
expect(params).to eq('flipper_id' => 'user:2')
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'handles request bodies with multiple params' do
|
26
|
+
response = post '/',
|
27
|
+
JSON.generate(flipper_id: 'user:2', language: 'ruby'),
|
28
|
+
'CONTENT_TYPE' => 'application/json'
|
29
|
+
|
30
|
+
params = JSON.parse(response.body)
|
31
|
+
expect(params).to eq('flipper_id' => 'user:2', 'language' => 'ruby')
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'handles request bodies and single query string params' do
|
35
|
+
response = post '/?language=ruby',
|
36
|
+
JSON.generate(flipper_id: 'user:2'),
|
37
|
+
'CONTENT_TYPE' => 'application/json'
|
38
|
+
|
39
|
+
params = JSON.parse(response.body)
|
40
|
+
expect(params).to eq('flipper_id' => 'user:2', 'language' => 'ruby')
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'handles request bodies and multiple query string params' do
|
44
|
+
response = post '/?language=ruby&framework=rails',
|
45
|
+
JSON.generate(flipper_id: 'user:2'),
|
46
|
+
'CONTENT_TYPE' => 'application/json'
|
47
|
+
|
48
|
+
params = JSON.parse(response.body)
|
49
|
+
expect(params).to eq('flipper_id' => 'user:2', 'language' => 'ruby', 'framework' => 'rails')
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'favors request body params' do
|
53
|
+
response = post '/?language=javascript',
|
54
|
+
JSON.generate(flipper_id: 'user:2', language: 'ruby'),
|
55
|
+
'CONTENT_TYPE' => 'application/json'
|
56
|
+
|
57
|
+
params = JSON.parse(response.body)
|
58
|
+
expect(params).to eq('flipper_id' => 'user:2', 'language' => 'ruby')
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe 'url-encoded request' do
|
63
|
+
it 'handles params the same as a json request' do
|
64
|
+
response = post '/', flipper_id: 'user:2'
|
65
|
+
params = JSON.parse(response.body)
|
66
|
+
expect(params).to eq('flipper_id' => 'user:2')
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'handles single query string params' do
|
70
|
+
response = post '/?language=ruby', flipper_id: 'user:2'
|
71
|
+
params = JSON.parse(response.body)
|
72
|
+
expect(params).to eq('flipper_id' => 'user:2', 'language' => 'ruby')
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'handles multiple query string params' do
|
76
|
+
response = post '/?language=ruby&framework=rails', flipper_id: 'user:2'
|
77
|
+
params = JSON.parse(response.body)
|
78
|
+
expect(params).to eq('flipper_id' => 'user:2', 'language' => 'ruby', 'framework' => 'rails')
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -2,13 +2,12 @@ require 'helper'
|
|
2
2
|
|
3
3
|
RSpec.describe Flipper::Api::V1::Actions::ActorsGate do
|
4
4
|
let(:app) { build_api(flipper) }
|
5
|
+
let(:actor) { Flipper::Api::Actor.new('1') }
|
5
6
|
|
6
7
|
describe 'enable' do
|
7
|
-
let(:actor) { Flipper::Api::Actor.new("1") }
|
8
|
-
|
9
8
|
before do
|
10
9
|
flipper[:my_feature].disable_actor(actor)
|
11
|
-
post '/
|
10
|
+
post '/features/my_feature/actors', flipper_id: actor.flipper_id
|
12
11
|
end
|
13
12
|
|
14
13
|
it 'enables feature for actor' do
|
@@ -19,16 +18,16 @@ RSpec.describe Flipper::Api::V1::Actions::ActorsGate do
|
|
19
18
|
|
20
19
|
it 'returns decorated feature with actor enabled' do
|
21
20
|
gate = json_response['gates'].find { |gate| gate['key'] == 'actors' }
|
22
|
-
expect(gate['value']).to eq([
|
21
|
+
expect(gate['value']).to eq(['1'])
|
23
22
|
end
|
24
23
|
end
|
25
24
|
|
26
25
|
describe 'disable' do
|
27
|
-
let(:actor) { Flipper::Api::Actor.new(
|
26
|
+
let(:actor) { Flipper::Api::Actor.new('1') }
|
28
27
|
|
29
28
|
before do
|
30
29
|
flipper[:my_feature].enable_actor(actor)
|
31
|
-
delete '/
|
30
|
+
delete '/features/my_feature/actors', flipper_id: actor.flipper_id
|
32
31
|
end
|
33
32
|
|
34
33
|
it 'disables feature' do
|
@@ -46,70 +45,82 @@ RSpec.describe Flipper::Api::V1::Actions::ActorsGate do
|
|
46
45
|
describe 'enable missing flipper_id parameter' do
|
47
46
|
before do
|
48
47
|
flipper[:my_feature].enable
|
49
|
-
post '/
|
48
|
+
post '/features/my_feature/actors'
|
50
49
|
end
|
51
50
|
|
52
51
|
it 'returns correct error response' do
|
53
52
|
expect(last_response.status).to eq(422)
|
54
|
-
expect(json_response).to eq(
|
53
|
+
expect(json_response).to eq(api_flipper_id_is_missing_response)
|
55
54
|
end
|
56
55
|
end
|
57
56
|
|
58
57
|
describe 'disable missing flipper_id parameter' do
|
59
58
|
before do
|
60
59
|
flipper[:my_feature].enable
|
61
|
-
delete '/
|
60
|
+
delete '/features/my_feature/actors'
|
62
61
|
end
|
63
62
|
|
64
63
|
it 'returns correct error response' do
|
65
64
|
expect(last_response.status).to eq(422)
|
66
|
-
expect(json_response).to eq(
|
65
|
+
expect(json_response).to eq(api_flipper_id_is_missing_response)
|
67
66
|
end
|
68
67
|
end
|
69
68
|
|
70
69
|
describe 'enable nil flipper_id parameter' do
|
71
70
|
before do
|
72
71
|
flipper[:my_feature].enable
|
73
|
-
post '/
|
72
|
+
post '/features/my_feature/actors', flipper_id: nil
|
74
73
|
end
|
75
74
|
|
76
75
|
it 'returns correct error response' do
|
77
76
|
expect(last_response.status).to eq(422)
|
78
|
-
expect(json_response).to eq(
|
77
|
+
expect(json_response).to eq(api_flipper_id_is_missing_response)
|
79
78
|
end
|
80
79
|
end
|
81
80
|
|
82
81
|
describe 'disable nil flipper_id parameter' do
|
83
82
|
before do
|
84
83
|
flipper[:my_feature].enable
|
85
|
-
delete '/
|
84
|
+
delete '/features/my_feature/actors', flipper_id: nil
|
86
85
|
end
|
87
86
|
|
88
87
|
it 'returns correct error response' do
|
89
88
|
expect(last_response.status).to eq(422)
|
90
|
-
expect(json_response).to eq(
|
89
|
+
expect(json_response).to eq(api_flipper_id_is_missing_response)
|
91
90
|
end
|
92
91
|
end
|
93
92
|
|
94
93
|
describe 'enable missing feature' do
|
95
94
|
before do
|
96
|
-
post '/
|
95
|
+
post '/features/my_feature/actors', flipper_id: actor.flipper_id
|
97
96
|
end
|
98
97
|
|
99
|
-
it '
|
100
|
-
expect(last_response.status).to eq(
|
101
|
-
expect(
|
98
|
+
it 'enables feature for actor' do
|
99
|
+
expect(last_response.status).to eq(200)
|
100
|
+
expect(flipper[:my_feature].enabled?(actor)).to be_truthy
|
101
|
+
expect(flipper[:my_feature].enabled_gate_names).to eq([:actor])
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'returns decorated feature with actor enabled' do
|
105
|
+
gate = json_response['gates'].find { |gate| gate['key'] == 'actors' }
|
106
|
+
expect(gate['value']).to eq(['1'])
|
102
107
|
end
|
103
108
|
end
|
104
109
|
|
105
110
|
describe 'disable missing feature' do
|
106
111
|
before do
|
107
|
-
delete '/
|
112
|
+
delete '/features/my_feature/actors', flipper_id: actor.flipper_id
|
108
113
|
end
|
109
114
|
|
110
|
-
it '
|
111
|
-
expect(last_response.status).to eq(
|
112
|
-
expect(
|
115
|
+
it 'disables feature' do
|
116
|
+
expect(last_response.status).to eq(200)
|
117
|
+
expect(flipper[:my_feature].enabled?(actor)).to be_falsy
|
118
|
+
expect(flipper[:my_feature].enabled_gate_names).to be_empty
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'returns decorated feature with boolean gate disabled' do
|
122
|
+
gate = json_response['gates'].find { |gate| gate['key'] == 'actors' }
|
123
|
+
expect(gate['value']).to be_empty
|
113
124
|
end
|
114
125
|
end
|
115
126
|
end
|
@@ -6,7 +6,7 @@ RSpec.describe Flipper::Api::V1::Actions::BooleanGate do
|
|
6
6
|
describe 'enable' do
|
7
7
|
before do
|
8
8
|
flipper[:my_feature].disable
|
9
|
-
post '/
|
9
|
+
post '/features/my_feature/boolean'
|
10
10
|
end
|
11
11
|
|
12
12
|
it 'enables feature' do
|
@@ -23,7 +23,7 @@ RSpec.describe Flipper::Api::V1::Actions::BooleanGate do
|
|
23
23
|
describe 'disable' do
|
24
24
|
before do
|
25
25
|
flipper[:my_feature].enable
|
26
|
-
delete '/
|
26
|
+
delete '/features/my_feature/boolean'
|
27
27
|
end
|
28
28
|
|
29
29
|
it 'disables feature' do
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
RSpec.describe Flipper::Api::V1::Actions::ClearFeature do
|
4
|
+
let(:app) { build_api(flipper) }
|
5
|
+
|
6
|
+
describe 'clear' do
|
7
|
+
before do
|
8
|
+
Flipper.register(:admins) {}
|
9
|
+
actor_class = Struct.new(:flipper_id)
|
10
|
+
actor22 = actor_class.new('22')
|
11
|
+
|
12
|
+
feature = flipper[:my_feature]
|
13
|
+
feature.enable flipper.boolean
|
14
|
+
feature.enable flipper.group(:admins)
|
15
|
+
feature.enable flipper.actor(actor22)
|
16
|
+
feature.enable flipper.actors(25)
|
17
|
+
feature.enable flipper.time(45)
|
18
|
+
|
19
|
+
delete '/features/my_feature/clear'
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'clears feature' do
|
23
|
+
expect(last_response.status).to eq(204)
|
24
|
+
expect(flipper[:my_feature].off?).to be_truthy
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -7,10 +7,9 @@ RSpec.describe Flipper::Api::V1::Actions::Feature do
|
|
7
7
|
|
8
8
|
describe 'get' do
|
9
9
|
context 'enabled feature' do
|
10
|
-
|
11
10
|
before do
|
12
11
|
flipper[:my_feature].enable
|
13
|
-
get '
|
12
|
+
get '/features/my_feature'
|
14
13
|
end
|
15
14
|
|
16
15
|
it 'responds with correct attributes' do
|
@@ -21,7 +20,7 @@ RSpec.describe Flipper::Api::V1::Actions::Feature do
|
|
21
20
|
{
|
22
21
|
'key' => 'boolean',
|
23
22
|
'name' => 'boolean',
|
24
|
-
'value' => true,
|
23
|
+
'value' => 'true',
|
25
24
|
},
|
26
25
|
{
|
27
26
|
'key' => 'groups',
|
@@ -36,14 +35,14 @@ RSpec.describe Flipper::Api::V1::Actions::Feature do
|
|
36
35
|
{
|
37
36
|
'key' => 'percentage_of_actors',
|
38
37
|
'name' => 'percentage_of_actors',
|
39
|
-
'value' =>
|
38
|
+
'value' => nil,
|
40
39
|
},
|
41
40
|
{
|
42
41
|
'key' => 'percentage_of_time',
|
43
42
|
'name' => 'percentage_of_time',
|
44
|
-
'value' =>
|
45
|
-
}
|
46
|
-
]
|
43
|
+
'value' => nil,
|
44
|
+
},
|
45
|
+
],
|
47
46
|
}
|
48
47
|
|
49
48
|
expect(last_response.status).to eq(200)
|
@@ -54,7 +53,7 @@ RSpec.describe Flipper::Api::V1::Actions::Feature do
|
|
54
53
|
context 'disabled feature' do
|
55
54
|
before do
|
56
55
|
flipper[:my_feature].disable
|
57
|
-
get '
|
56
|
+
get '/features/my_feature'
|
58
57
|
end
|
59
58
|
|
60
59
|
it 'responds with correct attributes' do
|
@@ -65,12 +64,12 @@ RSpec.describe Flipper::Api::V1::Actions::Feature do
|
|
65
64
|
{
|
66
65
|
'key' => 'boolean',
|
67
66
|
'name' => 'boolean',
|
68
|
-
'value' =>
|
67
|
+
'value' => nil,
|
69
68
|
},
|
70
69
|
{
|
71
|
-
'key'=> 'groups',
|
72
|
-
'name'=> 'group',
|
73
|
-
'value'=> [],
|
70
|
+
'key' => 'groups',
|
71
|
+
'name' => 'group',
|
72
|
+
'value' => [],
|
74
73
|
},
|
75
74
|
{
|
76
75
|
'key' => 'actors',
|
@@ -80,14 +79,14 @@ RSpec.describe Flipper::Api::V1::Actions::Feature do
|
|
80
79
|
{
|
81
80
|
'key' => 'percentage_of_actors',
|
82
81
|
'name' => 'percentage_of_actors',
|
83
|
-
'value'=>
|
82
|
+
'value' => nil,
|
84
83
|
},
|
85
84
|
{
|
86
85
|
'key' => 'percentage_of_time',
|
87
86
|
'name' => 'percentage_of_time',
|
88
|
-
'value' =>
|
89
|
-
}
|
90
|
-
]
|
87
|
+
'value' => nil,
|
88
|
+
},
|
89
|
+
],
|
91
90
|
}
|
92
91
|
|
93
92
|
expect(last_response.status).to eq(200)
|
@@ -97,15 +96,17 @@ RSpec.describe Flipper::Api::V1::Actions::Feature do
|
|
97
96
|
|
98
97
|
context 'feature does not exist' do
|
99
98
|
before do
|
100
|
-
get '
|
99
|
+
get '/features/not_a_feature'
|
101
100
|
end
|
102
101
|
|
103
|
-
it '
|
102
|
+
it '404s' do
|
104
103
|
expect(last_response.status).to eq(404)
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
104
|
+
expected = {
|
105
|
+
'code' => 1,
|
106
|
+
'message' => 'Feature not found.',
|
107
|
+
'more_info' => api_error_code_reference_url,
|
108
|
+
}
|
109
|
+
expect(json_response).to eq(expected)
|
109
110
|
end
|
110
111
|
end
|
111
112
|
end
|
@@ -115,7 +116,7 @@ RSpec.describe Flipper::Api::V1::Actions::Feature do
|
|
115
116
|
it 'deletes feature' do
|
116
117
|
flipper[:my_feature].enable
|
117
118
|
expect(flipper.features.map(&:key)).to include('my_feature')
|
118
|
-
delete '
|
119
|
+
delete '/features/my_feature'
|
119
120
|
expect(last_response.status).to eq(204)
|
120
121
|
expect(flipper.features.map(&:key)).not_to include('my_feature')
|
121
122
|
end
|
@@ -123,15 +124,12 @@ RSpec.describe Flipper::Api::V1::Actions::Feature do
|
|
123
124
|
|
124
125
|
context 'feature not found' do
|
125
126
|
before do
|
126
|
-
delete '
|
127
|
+
delete '/features/my_feature'
|
127
128
|
end
|
128
129
|
|
129
|
-
it '
|
130
|
-
expect(last_response.status).to eq(
|
131
|
-
|
132
|
-
|
133
|
-
it 'returns formatted error response body' do
|
134
|
-
expect(json_response).to eq({ "code" => 1, "message" => "Feature not found.", "more_info" => "https://github.com/jnunemaker/flipper/tree/master/docs/api#error-code-reference" })
|
130
|
+
it 'responds with 204' do
|
131
|
+
expect(last_response.status).to eq(204)
|
132
|
+
expect(flipper.features.map(&:key)).not_to include('my_feature')
|
135
133
|
end
|
136
134
|
end
|
137
135
|
end
|