Commit c0715b38 authored by Jason Goodman's avatar Jason Goodman Committed by Shinya Maeda

Return new version feature flags to unleash clients

Support both legacy and new feature flags
parent 0a1a71fb
...@@ -50,6 +50,14 @@ module Operations ...@@ -50,6 +50,14 @@ module Operations
def preload_relations def preload_relations
preload(:scopes) preload(:scopes)
end end
def for_unleash_client(project, environment)
includes(strategies: :scopes)
.where(project: project)
.merge(Operations::FeatureFlags::Scope.on_environment(environment))
.reorder(:id)
.references(:operations_scopes)
end
end end
private private
......
# frozen_string_literal: true
module Operations
module FeatureFlags
class Scope < ApplicationRecord
prepend HasEnvironmentScope
self.table_name = 'operations_scopes'
belongs_to :strategy, class_name: 'Operations::FeatureFlags::Strategy'
end
end
end
...@@ -16,6 +16,7 @@ module Operations ...@@ -16,6 +16,7 @@ module Operations
self.table_name = 'operations_strategies' self.table_name = 'operations_strategies'
belongs_to :feature_flag belongs_to :feature_flag
has_many :scopes, class_name: 'Operations::FeatureFlags::Scope'
validates :name, validates :name,
inclusion: { inclusion: {
......
...@@ -72,7 +72,12 @@ module API ...@@ -72,7 +72,12 @@ module API
def feature_flags def feature_flags
return [] unless unleash_app_name.present? return [] unless unleash_app_name.present?
Operations::FeatureFlagScope.for_unleash_client(project, unleash_app_name) if Feature.enabled?(:feature_flags_new_version, project)
Operations::FeatureFlagScope.for_unleash_client(project, unleash_app_name) +
Operations::FeatureFlag.for_unleash_client(project, unleash_app_name)
else
Operations::FeatureFlagScope.for_unleash_client(project, unleash_app_name)
end
end end
end end
end end
......
...@@ -7,7 +7,7 @@ module EE ...@@ -7,7 +7,7 @@ module EE
expose :name expose :name
expose :description, unless: ->(feature) { feature.description.nil? } expose :description, unless: ->(feature) { feature.description.nil? }
expose :active, as: :enabled expose :active, as: :enabled
expose :strategies expose :strategies, using: UnleashStrategy
end end
end end
end end
......
# frozen_string_literal: true
module EE
module API
module Entities
class UnleashStrategy < Grape::Entity
expose :name do |strategy|
if strategy.respond_to?(:name)
strategy.name
else
strategy['name']
end
end
expose :parameters do |strategy|
if strategy.respond_to?(:parameters)
strategy.parameters
else
strategy['parameters']
end
end
end
end
end
end
# frozen_string_literal: true
FactoryBot.define do
factory :operations_scope, class: 'Operations::FeatureFlags::Scope' do
association :strategy, factory: :operations_strategy
sequence(:environment_scope) { |n| "review/patch-#{n}" }
end
end
# frozen_string_literal: true
FactoryBot.define do
factory :operations_strategy, class: 'Operations::FeatureFlags::Strategy' do
association :feature_flag, factory: :operations_feature_flag
name { "default" }
parameters { {} }
end
end
...@@ -213,4 +213,45 @@ describe Operations::FeatureFlag do ...@@ -213,4 +213,45 @@ describe Operations::FeatureFlag do
end end
end end
end end
describe '.for_unleash_client' do
let_it_be(:project) { create(:project) }
let!(:feature_flag) do
create(:operations_feature_flag, project: project,
name: 'feature1', active: true, version: 2)
end
let!(:strategy) do
create(:operations_strategy, feature_flag: feature_flag,
name: 'default', parameters: {})
end
it 'matches wild cards in the scope' do
create(:operations_scope, strategy: strategy, environment_scope: 'review/*')
flags = described_class.for_unleash_client(project, 'review/feature-branch')
expect(flags).to eq([feature_flag])
end
it 'matches wild cards case sensitively' do
create(:operations_scope, strategy: strategy, environment_scope: 'Staging/*')
flags = described_class.for_unleash_client(project, 'staging/feature')
expect(flags).to eq([])
end
it 'returns feature flags ordered by id' do
create(:operations_scope, strategy: strategy, environment_scope: 'production')
feature_flag_b = create(:operations_feature_flag, project: project,
name: 'feature2', active: true, version: 2)
strategy_b = create(:operations_strategy, feature_flag: feature_flag_b,
name: 'default', parameters: {})
create(:operations_scope, strategy: strategy_b, environment_scope: '*')
flags = described_class.for_unleash_client(project, 'production')
expect(flags.map(&:id)).to eq([feature_flag.id, feature_flag_b.id])
end
end
end end
...@@ -153,122 +153,442 @@ describe API::Unleash do ...@@ -153,122 +153,442 @@ describe API::Unleash do
describe "GET #{features_endpoint}" do describe "GET #{features_endpoint}" do
let(:features_url) { features_endpoint.sub(':project_id', project_id.to_s) } let(:features_url) { features_endpoint.sub(':project_id', project_id.to_s) }
let(:client) { create(:operations_feature_flags_client, project: project) } let(:client) { create(:operations_feature_flags_client, project: project) }
let(:feature_flag) { create(:operations_feature_flag, project: project, name: 'feature1', active: true) }
subject { get api(features_url), params: params, headers: headers } subject { get api(features_url), params: params, headers: headers }
it_behaves_like 'authenticated request' it_behaves_like 'authenticated request'
it_behaves_like 'support multiple environments'
context 'with a list of feature flags' do context 'with version 1 (legacy) feature flags' do
let(:headers) { { "UNLEASH-INSTANCEID" => client.token, "UNLEASH-APPNAME" => "production" }} let(:feature_flag) { create(:operations_feature_flag, project: project, name: 'feature1', active: true, version: 1) }
let!(:enable_feature_flag) { create(:operations_feature_flag, project: project, name: 'feature1', active: true) }
let!(:disabled_feature_flag) { create(:operations_feature_flag, project: project, name: 'feature2', active: false) }
it 'responds with a list of features' do it_behaves_like 'support multiple environments'
subject
context 'with a list of feature flags' do
let(:headers) { { "UNLEASH-INSTANCEID" => client.token, "UNLEASH-APPNAME" => "production" } }
let!(:enabled_feature_flag) { create(:operations_feature_flag, project: project, name: 'feature1', active: true, version: 1) }
let!(:disabled_feature_flag) { create(:operations_feature_flag, project: project, name: 'feature2', active: false, version: 1) }
it 'responds with a list of features' do
subject
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['version']).to eq(1)
expect(json_response['features']).not_to be_empty
expect(json_response['features'].map { |f| f['name'] }.sort).to eq(%w[feature1 feature2])
expect(json_response['features'].sort_by {|f| f['name'] }.map { |f| f['enabled'] }).to eq([true, false])
end
it 'matches json schema' do
subject
expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_response_schema('unleash/unleash', dir: 'ee')
end
end
it 'returns a feature flag strategy' do
create(:operations_feature_flag_scope,
feature_flag: feature_flag,
environment_scope: 'sandbox',
active: true,
strategies: [{ name: "gradualRolloutUserId",
parameters: { groupId: "default", percentage: "50" } }])
headers = { "UNLEASH-INSTANCEID" => client.token, "UNLEASH-APPNAME" => "sandbox" }
get api(features_url), headers: headers
expect(response).to have_gitlab_http_status(:ok) expect(response).to have_gitlab_http_status(:ok)
expect(json_response['version']).to eq(1) expect(json_response['features'].first['enabled']).to eq(true)
expect(json_response['features']).not_to be_empty strategies = json_response['features'].first['strategies']
expect(json_response['features'].map { |f| f['name'] }.sort).to eq(%w[feature1 feature2]) expect(strategies).to eq([{
expect(json_response['features'].sort_by {|f| f['name'] }.map { |f| f['enabled'] }).to eq([true, false]) "name" => "gradualRolloutUserId",
"parameters" => {
"percentage" => "50",
"groupId" => "default"
}
}])
end end
it 'matches json schema' do it 'returns a default strategy for a scope' do
subject create(:operations_feature_flag_scope, feature_flag: feature_flag, environment_scope: 'sandbox', active: true)
headers = { "UNLEASH-INSTANCEID" => client.token, "UNLEASH-APPNAME" => "sandbox" }
get api(features_url), headers: headers
expect(response).to have_gitlab_http_status(:ok) expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_response_schema('unleash/unleash', dir: 'ee') expect(json_response['features'].first['enabled']).to eq(true)
strategies = json_response['features'].first['strategies']
expect(strategies).to eq([{ "name" => "default", "parameters" => {} }])
end end
end
it 'returns a feature flag strategy' do it 'returns multiple strategies for a feature flag' do
create(:operations_feature_flag_scope, create(:operations_feature_flag_scope,
feature_flag: feature_flag, feature_flag: feature_flag,
environment_scope: 'sandbox', environment_scope: 'staging',
active: true, active: true,
strategies: [{ name: "gradualRolloutUserId", strategies: [{ name: "userWithId", parameters: { userIds: "max,fred" } },
parameters: { groupId: "default", percentage: "50" } }]) { name: "gradualRolloutUserId",
headers = { "UNLEASH-INSTANCEID" => client.token, "UNLEASH-APPNAME" => "sandbox" } parameters: { groupId: "default", percentage: "50" } }])
headers = { "UNLEASH-INSTANCEID" => client.token, "UNLEASH-APPNAME" => "staging" }
get api(features_url), headers: headers get api(features_url), headers: headers
expect(response).to have_gitlab_http_status(:ok) expect(response).to have_gitlab_http_status(:ok)
expect(json_response['features'].first['enabled']).to eq(true) expect(json_response['features'].first['enabled']).to eq(true)
strategies = json_response['features'].first['strategies'] strategies = json_response['features'].first['strategies'].sort_by { |s| s['name'] }
expect(strategies).to eq([{ expect(strategies).to eq([{
"name" => "gradualRolloutUserId", "name" => "gradualRolloutUserId",
"parameters" => { "parameters" => {
"percentage" => "50", "percentage" => "50",
"groupId" => "default" "groupId" => "default"
} }
}]) }, {
end "name" => "userWithId",
"parameters" => {
"userIds" => "max,fred"
}
}])
end
it 'returns a default strategy for a scope' do it 'returns a disabled feature when the flag is disabled' do
create(:operations_feature_flag_scope, feature_flag: feature_flag, environment_scope: 'sandbox', active: true) flag = create(:operations_feature_flag, project: project, name: 'test_feature', active: false, version: 1)
headers = { "UNLEASH-INSTANCEID" => client.token, "UNLEASH-APPNAME" => "sandbox" } create(:operations_feature_flag_scope, feature_flag: flag, environment_scope: 'production', active: true)
headers = { "UNLEASH-INSTANCEID" => client.token, "UNLEASH-APPNAME" => "production" }
get api(features_url), headers: headers get api(features_url), headers: headers
expect(response).to have_gitlab_http_status(:ok) expect(response).to have_gitlab_http_status(:ok)
expect(json_response['features'].first['enabled']).to eq(true) expect(json_response['features'].first['enabled']).to eq(false)
strategies = json_response['features'].first['strategies'] end
expect(strategies).to eq([{ "name" => "default", "parameters" => {} }])
end
it 'returns multiple strategies for a feature flag' do context "with an inactive scope" do
create(:operations_feature_flag_scope, let!(:scope) { create(:operations_feature_flag_scope, feature_flag: feature_flag, environment_scope: 'production', active: false, strategies: [{ name: "default", parameters: {} }]) }
feature_flag: feature_flag, let(:headers) { { "UNLEASH-INSTANCEID" => client.token, "UNLEASH-APPNAME" => "production" } }
environment_scope: 'staging',
active: true,
strategies: [{ name: "userWithId", parameters: { userIds: "max,fred" } },
{ name: "gradualRolloutUserId",
parameters: { groupId: "default", percentage: "50" } }])
headers = { "UNLEASH-INSTANCEID" => client.token, "UNLEASH-APPNAME" => "staging" }
get api(features_url), headers: headers it 'returns a disabled feature' do
get api(features_url), headers: headers
expect(response).to have_gitlab_http_status(:ok) expect(response).to have_gitlab_http_status(:ok)
expect(json_response['features'].first['enabled']).to eq(true) feature_json = json_response['features'].first
strategies = json_response['features'].first['strategies'].sort_by { |s| s['name'] } expect(feature_json['enabled']).to eq(false)
expect(strategies).to eq([{ expect(feature_json['strategies']).to eq([{ 'name' => 'default', 'parameters' => {} }])
"name" => "gradualRolloutUserId", end
"parameters" => { end
"percentage" => "50",
"groupId" => "default"
}
}, {
"name" => "userWithId",
"parameters" => {
"userIds" => "max,fred"
}
}])
end end
it 'returns a disabled feature when the flag is disabled' do context 'with version 2 feature flags' do
flag = create(:operations_feature_flag, project: project, name: 'test_feature', active: false) it 'does not return any flags when the feature flag is disabled' do
create(:operations_feature_flag_scope, feature_flag: flag, environment_scope: 'production', active: true) stub_feature_flags(feature_flags_new_version: false)
headers = { "UNLEASH-INSTANCEID" => client.token, "UNLEASH-APPNAME" => "production" } feature_flag = create(:operations_feature_flag, project: project,
name: 'feature1', active: true, version: 2)
strategy = create(:operations_strategy, feature_flag: feature_flag,
name: 'default', parameters: {})
create(:operations_scope, strategy: strategy, environment_scope: 'production')
get api(features_url), headers: headers get api(features_url), headers: { 'UNLEASH-INSTANCEID' => client.token, 'UNLEASH-APPNAME' => 'production' }
expect(response).to have_gitlab_http_status(:ok) expect(response).to have_gitlab_http_status(:ok)
expect(json_response['features'].first['enabled']).to eq(false) expect(json_response['features']).to eq([])
end
it 'does not return a flag without any strategies' do
create(:operations_feature_flag, project: project,
name: 'feature1', active: true, version: 2)
get api(features_url), headers: { 'UNLEASH-INSTANCEID' => client.token, 'UNLEASH-APPNAME' => 'production' }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['features']).to be_empty
end
it 'returns a flag with a default strategy' do
feature_flag = create(:operations_feature_flag, project: project,
name: 'feature1', active: true, version: 2)
strategy = create(:operations_strategy, feature_flag: feature_flag,
name: 'default', parameters: {})
create(:operations_scope, strategy: strategy, environment_scope: 'production')
get api(features_url), headers: { 'UNLEASH-INSTANCEID' => client.token, 'UNLEASH-APPNAME' => 'production' }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['features']).to eq([{
'name' => 'feature1',
'enabled' => true,
'strategies' => [{
'name' => 'default',
'parameters' => {}
}]
}])
end
it 'returns a flag with a userWithId strategy' do
feature_flag = create(:operations_feature_flag, project: project,
name: 'feature1', active: true, version: 2)
strategy = create(:operations_strategy, feature_flag: feature_flag,
name: 'userWithId', parameters: { userIds: 'user123,user456' })
create(:operations_scope, strategy: strategy, environment_scope: 'production')
get api(features_url), headers: { 'UNLEASH-INSTANCEID' => client.token, 'UNLEASH-APPNAME' => 'production' }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['features']).to eq([{
'name' => 'feature1',
'enabled' => true,
'strategies' => [{
'name' => 'userWithId',
'parameters' => { 'userIds' => 'user123,user456' }
}]
}])
end
it 'returns a flag with multiple strategies' do
feature_flag = create(:operations_feature_flag, project: project,
name: 'feature1', active: true, version: 2)
strategy_a = create(:operations_strategy, feature_flag: feature_flag,
name: 'userWithId', parameters: { userIds: 'user_a,user_b' })
strategy_b = create(:operations_strategy, feature_flag: feature_flag,
name: 'gradualRolloutUserId', parameters: { groupId: 'default', percentage: '45' })
create(:operations_scope, strategy: strategy_a, environment_scope: 'production')
create(:operations_scope, strategy: strategy_b, environment_scope: 'production')
get api(features_url), headers: { 'UNLEASH-INSTANCEID' => client.token, 'UNLEASH-APPNAME' => 'production' }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['features'].map { |f| f['name'] }.sort).to eq(['feature1'])
features_json = json_response['features'].map do |feature|
feature.merge(feature.slice('strategies').transform_values { |v| v.sort_by { |s| s['name'] } })
end
expect(features_json).to eq([{
'name' => 'feature1',
'enabled' => true,
'strategies' => [{
'name' => 'gradualRolloutUserId',
'parameters' => { 'groupId' => 'default', 'percentage' => '45' }
}, {
'name' => 'userWithId',
'parameters' => { 'userIds' => 'user_a,user_b' }
}]
}])
end
it 'returns only flags matching the environment scope' do
feature_flag_a = create(:operations_feature_flag, project: project,
name: 'feature1', active: true, version: 2)
strategy_a = create(:operations_strategy, feature_flag: feature_flag_a)
create(:operations_scope, strategy: strategy_a, environment_scope: 'production')
feature_flag_b = create(:operations_feature_flag, project: project,
name: 'feature2', active: true, version: 2)
strategy_b = create(:operations_strategy, feature_flag: feature_flag_b)
create(:operations_scope, strategy: strategy_b, environment_scope: 'staging')
get api(features_url), headers: { 'UNLEASH-INSTANCEID' => client.token, 'UNLEASH-APPNAME' => 'staging' }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['features'].map { |f| f['name'] }.sort).to eq(['feature2'])
expect(json_response['features']).to eq([{
'name' => 'feature2',
'enabled' => true,
'strategies' => [{
'name' => 'default',
'parameters' => {}
}]
}])
end
it 'returns only strategies matching the environment scope' do
feature_flag = create(:operations_feature_flag, project: project,
name: 'feature1', active: true, version: 2)
strategy_a = create(:operations_strategy, feature_flag: feature_flag,
name: 'userWithId', parameters: { userIds: 'user2,user8,user4' })
create(:operations_scope, strategy: strategy_a, environment_scope: 'production')
strategy_b = create(:operations_strategy, feature_flag: feature_flag,
name: 'default', parameters: {})
create(:operations_scope, strategy: strategy_b, environment_scope: 'staging')
get api(features_url), headers: { 'UNLEASH-INSTANCEID' => client.token, 'UNLEASH-APPNAME' => 'production' }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['features']).to eq([{
'name' => 'feature1',
'enabled' => true,
'strategies' => [{
'name' => 'userWithId',
'parameters' => { 'userIds' => 'user2,user8,user4' }
}]
}])
end
it 'returns only flags for the given project' do
project_b = create(:project)
feature_flag_a = create(:operations_feature_flag, project: project, name: 'feature_a', active: true, version: 2)
strategy_a = create(:operations_strategy, feature_flag: feature_flag_a)
create(:operations_scope, strategy: strategy_a, environment_scope: 'sandbox')
feature_flag_b = create(:operations_feature_flag, project: project_b, name: 'feature_b', active: true, version: 2)
strategy_b = create(:operations_strategy, feature_flag: feature_flag_b)
create(:operations_scope, strategy: strategy_b, environment_scope: 'sandbox')
get api(features_url), headers: { 'UNLEASH-INSTANCEID' => client.token, 'UNLEASH-APPNAME' => 'sandbox' }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['features']).to eq([{
'name' => 'feature_a',
'enabled' => true,
'strategies' => [{
'name' => 'default',
'parameters' => {}
}]
}])
end
it 'returns all strategies with a matching scope' do
feature_flag = create(:operations_feature_flag, project: project,
name: 'feature1', active: true, version: 2)
strategy_a = create(:operations_strategy, feature_flag: feature_flag,
name: 'userWithId', parameters: { userIds: 'user2,user8,user4' })
create(:operations_scope, strategy: strategy_a, environment_scope: '*')
strategy_b = create(:operations_strategy, feature_flag: feature_flag,
name: 'default', parameters: {})
create(:operations_scope, strategy: strategy_b, environment_scope: 'review/*')
strategy_c = create(:operations_strategy, feature_flag: feature_flag,
name: 'gradualRolloutUserId', parameters: { groupId: 'default', percentage: '15' })
create(:operations_scope, strategy: strategy_c, environment_scope: 'review/patch-1')
get api(features_url), headers: { 'UNLEASH-INSTANCEID' => client.token, 'UNLEASH-APPNAME' => 'review/patch-1' }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['features'].first['strategies'].sort_by { |s| s['name'] }).to eq([{
'name' => 'default',
'parameters' => {}
}, {
'name' => 'gradualRolloutUserId',
'parameters' => { 'groupId' => 'default', 'percentage' => '15' }
}, {
'name' => 'userWithId',
'parameters' => { 'userIds' => 'user2,user8,user4' }
}])
end
it 'returns a strategy with more than one matching scope' do
feature_flag = create(:operations_feature_flag, project: project,
name: 'feature1', active: true, version: 2)
strategy = create(:operations_strategy, feature_flag: feature_flag,
name: 'default', parameters: {})
create(:operations_scope, strategy: strategy, environment_scope: 'production')
create(:operations_scope, strategy: strategy, environment_scope: '*')
get api(features_url), headers: { 'UNLEASH-INSTANCEID' => client.token, 'UNLEASH-APPNAME' => 'production' }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['features']).to eq([{
'name' => 'feature1',
'enabled' => true,
'strategies' => [{
'name' => 'default',
'parameters' => {}
}]
}])
end
it 'returns a disabled flag with a matching scope' do
feature_flag = create(:operations_feature_flag, project: project,
name: 'myfeature', active: false, version: 2)
strategy = create(:operations_strategy, feature_flag: feature_flag,
name: 'default', parameters: {})
create(:operations_scope, strategy: strategy, environment_scope: 'production')
get api(features_url), headers: { 'UNLEASH-INSTANCEID' => client.token, 'UNLEASH-APPNAME' => 'production' }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['features']).to eq([{
'name' => 'myfeature',
'enabled' => false,
'strategies' => [{
'name' => 'default',
'parameters' => {}
}]
}])
end
end end
context "with an inactive scope" do context 'when mixing version 1 and version 2 feature flags' do
let!(:scope) { create(:operations_feature_flag_scope, feature_flag: feature_flag, environment_scope: 'production', active: false, strategies: [{ name: "default", parameters: {} }]) } it 'returns only version 1 flags when the new flags are disabled' do
let(:headers) { { "UNLEASH-INSTANCEID" => client.token, "UNLEASH-APPNAME" => "production" } } stub_feature_flags(feature_flags_new_version: false)
feature_flag_a = create(:operations_feature_flag, project: project,
name: 'feature_a', active: true, version: 2)
strategy = create(:operations_strategy, feature_flag: feature_flag_a,
name: 'userWithId', parameters: { userIds: 'user8' })
create(:operations_scope, strategy: strategy, environment_scope: 'staging')
feature_flag_b = create(:operations_feature_flag, project: project,
name: 'feature_b', active: true, version: 1)
create(:operations_feature_flag_scope, feature_flag: feature_flag_b,
active: true, strategies: [{ name: 'default', parameters: {} }], environment_scope: 'staging')
get api(features_url), headers: { 'UNLEASH-INSTANCEID' => client.token, 'UNLEASH-APPNAME' => 'staging' }
it 'returns a disabled feature' do expect(response).to have_gitlab_http_status(:ok)
get api(features_url), headers: headers expect(json_response['features'].sort_by {|f| f['name']}).to eq([{
'name' => 'feature_b',
'enabled' => true,
'strategies' => [{
'name' => 'default',
'parameters' => {}
}]
}])
end
it 'returns both types of flags when both match' do
feature_flag_a = create(:operations_feature_flag, project: project,
name: 'feature_a', active: true, version: 2)
strategy = create(:operations_strategy, feature_flag: feature_flag_a,
name: 'userWithId', parameters: { userIds: 'user8' })
create(:operations_scope, strategy: strategy, environment_scope: 'staging')
feature_flag_b = create(:operations_feature_flag, project: project,
name: 'feature_b', active: true, version: 1)
create(:operations_feature_flag_scope, feature_flag: feature_flag_b,
active: true, strategies: [{ name: 'default', parameters: {} }], environment_scope: 'staging')
get api(features_url), headers: { 'UNLEASH-INSTANCEID' => client.token, 'UNLEASH-APPNAME' => 'staging' }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['features'].sort_by {|f| f['name']}).to eq([{
'name' => 'feature_a',
'enabled' => true,
'strategies' => [{
'name' => 'userWithId',
'parameters' => { 'userIds' => 'user8' }
}]
}, {
'name' => 'feature_b',
'enabled' => true,
'strategies' => [{
'name' => 'default',
'parameters' => {}
}]
}])
end
it 'returns legacy flags when only legacy flags match' do
feature_flag_a = create(:operations_feature_flag, project: project,
name: 'feature_a', active: true, version: 2)
strategy = create(:operations_strategy, feature_flag: feature_flag_a,
name: 'userWithId', parameters: { userIds: 'user8' })
create(:operations_scope, strategy: strategy, environment_scope: 'production')
feature_flag_b = create(:operations_feature_flag, project: project,
name: 'feature_b', active: true, version: 1)
create(:operations_feature_flag_scope, feature_flag: feature_flag_b,
active: true, strategies: [{ name: 'default', parameters: {} }], environment_scope: 'staging')
get api(features_url), headers: { 'UNLEASH-INSTANCEID' => client.token, 'UNLEASH-APPNAME' => 'staging' }
expect(response).to have_gitlab_http_status(:ok) expect(response).to have_gitlab_http_status(:ok)
feature_json = json_response['features'].first expect(json_response['features']).to eq([{
expect(feature_json['enabled']).to eq(false) 'name' => 'feature_b',
expect(feature_json['strategies']).to eq([{ 'name' => 'default', 'parameters' => {} }]) 'enabled' => true,
'strategies' => [{
'name' => 'default',
'parameters' => {}
}]
}])
end end
end end
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment