summaryrefslogtreecommitdiff
path: root/spec/requests/api/features_spec.rb
diff options
context:
space:
mode:
authorRémy Coutable <remy@rymai.me>2017-06-21 16:49:51 +0200
committerRémy Coutable <remy@rymai.me>2017-06-27 18:59:51 +0200
commitb4d325c80c63ee9ee2676a57a42fac472b5b20d5 (patch)
tree15e4dea85ab1ae5538ffe35d0c9b0ee2dbfcaadc /spec/requests/api/features_spec.rb
parentcc50decab5b22628eafb6636b3e57f99094c7926 (diff)
downloadgitlab-ce-b4d325c80c63ee9ee2676a57a42fac472b5b20d5.tar.gz
Allow the feature flags to be enabled/disabled with more granularity
This allows to enable/disable a feature flag for a given user, or a given Flipper group (must be declared statically in the `flipper.rb` initializer beforehand). Signed-off-by: Rémy Coutable <remy@rymai.me>
Diffstat (limited to 'spec/requests/api/features_spec.rb')
-rw-r--r--spec/requests/api/features_spec.rb178
1 files changed, 156 insertions, 22 deletions
diff --git a/spec/requests/api/features_spec.rb b/spec/requests/api/features_spec.rb
index f169e6661d1..0ee0749c7a1 100644
--- a/spec/requests/api/features_spec.rb
+++ b/spec/requests/api/features_spec.rb
@@ -4,6 +4,13 @@ describe API::Features do
let(:user) { create(:user) }
let(:admin) { create(:admin) }
+ before do
+ Flipper.unregister_groups
+ Flipper.register(:perf_team) do |actor|
+ actor.respond_to?(:admin) && actor.admin?
+ end
+ end
+
describe 'GET /features' do
let(:expected_features) do
[
@@ -16,6 +23,14 @@ describe API::Features do
'name' => 'feature_2',
'state' => 'off',
'gates' => [{ 'key' => 'boolean', 'value' => false }]
+ },
+ {
+ 'name' => 'feature_3',
+ 'state' => 'conditional',
+ 'gates' => [
+ { 'key' => 'boolean', 'value' => false },
+ { 'key' => 'groups', 'value' => ['perf_team'] }
+ ]
}
]
end
@@ -23,6 +38,7 @@ describe API::Features do
before do
Feature.get('feature_1').enable
Feature.get('feature_2').disable
+ Feature.get('feature_3').enable Feature.group(:perf_team)
end
it 'returns a 401 for anonymous users' do
@@ -47,30 +63,70 @@ describe API::Features do
describe 'POST /feature' do
let(:feature_name) { 'my_feature' }
- it 'returns a 401 for anonymous users' do
- post api("/features/#{feature_name}")
- expect(response).to have_http_status(401)
- end
+ context 'when the feature does not exist' do
+ it 'returns a 401 for anonymous users' do
+ post api("/features/#{feature_name}")
- it 'returns a 403 for users' do
- post api("/features/#{feature_name}", user)
+ expect(response).to have_http_status(401)
+ end
- expect(response).to have_http_status(403)
- end
+ it 'returns a 403 for users' do
+ post api("/features/#{feature_name}", user)
- it 'creates an enabled feature if passed true' do
- post api("/features/#{feature_name}", admin), value: 'true'
+ expect(response).to have_http_status(403)
+ end
- expect(response).to have_http_status(201)
- expect(Feature.get(feature_name)).to be_enabled
- end
+ context 'when passed value=true' do
+ it 'creates an enabled feature' do
+ post api("/features/#{feature_name}", admin), value: 'true'
- it 'creates a feature with the given percentage if passed an integer' do
- post api("/features/#{feature_name}", admin), value: '50'
+ expect(response).to have_http_status(201)
+ expect(json_response).to eq(
+ 'name' => 'my_feature',
+ 'state' => 'on',
+ 'gates' => [{ 'key' => 'boolean', 'value' => true }])
+ end
+
+ it 'creates an enabled feature for the given Flipper group when passed flipper_group=perf_team' do
+ post api("/features/#{feature_name}", admin), value: 'true', flipper_group: 'perf_team'
+
+ expect(response).to have_http_status(201)
+ expect(json_response).to eq(
+ 'name' => 'my_feature',
+ 'state' => 'conditional',
+ 'gates' => [
+ { 'key' => 'boolean', 'value' => false },
+ { 'key' => 'groups', 'value' => ['perf_team'] }
+ ])
+ end
+
+ it 'creates an enabled feature for the given user when passed user=username' do
+ post api("/features/#{feature_name}", admin), value: 'true', user: user.username
- expect(response).to have_http_status(201)
- expect(Feature.get(feature_name).percentage_of_time_value).to be(50)
+ expect(response).to have_http_status(201)
+ expect(json_response).to eq(
+ 'name' => 'my_feature',
+ 'state' => 'conditional',
+ 'gates' => [
+ { 'key' => 'boolean', 'value' => false },
+ { 'key' => 'actors', 'value' => ["User:#{user.id}"] }
+ ])
+ end
+ end
+
+ it 'creates a feature with the given percentage if passed an integer' do
+ post api("/features/#{feature_name}", admin), value: '50'
+
+ expect(response).to have_http_status(201)
+ expect(json_response).to eq(
+ 'name' => 'my_feature',
+ 'state' => 'conditional',
+ 'gates' => [
+ { 'key' => 'boolean', 'value' => false },
+ { 'key' => 'percentage_of_time', 'value' => 50 }
+ ])
+ end
end
context 'when the feature exists' do
@@ -80,11 +136,83 @@ describe API::Features do
feature.disable # This also persists the feature on the DB
end
- it 'enables the feature if passed true' do
- post api("/features/#{feature_name}", admin), value: 'true'
+ context 'when passed value=true' do
+ it 'enables the feature' do
+ post api("/features/#{feature_name}", admin), value: 'true'
- expect(response).to have_http_status(201)
- expect(feature).to be_enabled
+ expect(response).to have_http_status(201)
+ expect(json_response).to eq(
+ 'name' => 'my_feature',
+ 'state' => 'on',
+ 'gates' => [{ 'key' => 'boolean', 'value' => true }])
+ end
+
+ it 'enables the feature for the given Flipper group when passed flipper_group=perf_team' do
+ post api("/features/#{feature_name}", admin), value: 'true', flipper_group: 'perf_team'
+
+ expect(response).to have_http_status(201)
+ expect(json_response).to eq(
+ 'name' => 'my_feature',
+ 'state' => 'conditional',
+ 'gates' => [
+ { 'key' => 'boolean', 'value' => false },
+ { 'key' => 'groups', 'value' => ['perf_team'] }
+ ])
+ end
+
+ it 'enables the feature for the given user when passed user=username' do
+ post api("/features/#{feature_name}", admin), value: 'true', user: user.username
+
+ expect(response).to have_http_status(201)
+ expect(json_response).to eq(
+ 'name' => 'my_feature',
+ 'state' => 'conditional',
+ 'gates' => [
+ { 'key' => 'boolean', 'value' => false },
+ { 'key' => 'actors', 'value' => ["User:#{user.id}"] }
+ ])
+ end
+ end
+
+ context 'when feature is enabled and value=false is passed' do
+ it 'disables the feature' do
+ feature.enable
+ expect(feature).to be_enabled
+
+ post api("/features/#{feature_name}", admin), value: 'false'
+
+ expect(response).to have_http_status(201)
+ expect(json_response).to eq(
+ 'name' => 'my_feature',
+ 'state' => 'off',
+ 'gates' => [{ 'key' => 'boolean', 'value' => false }])
+ end
+
+ it 'disables the feature for the given Flipper group when passed flipper_group=perf_team' do
+ feature.enable(Feature.group(:perf_team))
+ expect(Feature.get(feature_name).enabled?(admin)).to be_truthy
+
+ post api("/features/#{feature_name}", admin), value: 'false', flipper_group: 'perf_team'
+
+ expect(response).to have_http_status(201)
+ expect(json_response).to eq(
+ 'name' => 'my_feature',
+ 'state' => 'off',
+ 'gates' => [{ 'key' => 'boolean', 'value' => false }])
+ end
+
+ it 'disables the feature for the given user when passed user=username' do
+ feature.enable(user)
+ expect(Feature.get(feature_name).enabled?(user)).to be_truthy
+
+ post api("/features/#{feature_name}", admin), value: 'false', user: user.username
+
+ expect(response).to have_http_status(201)
+ expect(json_response).to eq(
+ 'name' => 'my_feature',
+ 'state' => 'off',
+ 'gates' => [{ 'key' => 'boolean', 'value' => false }])
+ end
end
context 'with a pre-existing percentage value' do
@@ -96,7 +224,13 @@ describe API::Features do
post api("/features/#{feature_name}", admin), value: '30'
expect(response).to have_http_status(201)
- expect(Feature.get(feature_name).percentage_of_time_value).to be(30)
+ expect(json_response).to eq(
+ 'name' => 'my_feature',
+ 'state' => 'conditional',
+ 'gates' => [
+ { 'key' => 'boolean', 'value' => false },
+ { 'key' => 'percentage_of_time', 'value' => 30 }
+ ])
end
end
end