Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/bin/feature_flag_spec.rb')
-rw-r--r--spec/bin/feature_flag_spec.rb273
1 files changed, 187 insertions, 86 deletions
diff --git a/spec/bin/feature_flag_spec.rb b/spec/bin/feature_flag_spec.rb
index d1e4be5be28..f9caa5549ca 100644
--- a/spec/bin/feature_flag_spec.rb
+++ b/spec/bin/feature_flag_spec.rb
@@ -7,12 +7,28 @@ load File.expand_path('../../bin/feature-flag', __dir__)
RSpec.describe 'bin/feature-flag', feature_category: :feature_flags do
using RSpec::Parameterized::TableSyntax
+ let(:groups) do
+ {
+ geo: { label: 'group::geo' }
+ }
+ end
+
+ before do
+ allow(HTTParty)
+ .to receive(:get)
+ .with(FeatureFlagOptionParser::WWW_GITLAB_COM_GROUPS_JSON, format: :plain)
+ .and_return(groups.to_json)
+ end
+
describe FeatureFlagCreator do
- let(:argv) { %w[feature-flag-name -t development -g group::geo -i https://url -m http://url] }
+ let(:argv) { %w[feature-flag-name -t gitlab_com_derisk -g group::geo -a https://url -i https://url -m http://url -u username -M 16.6] }
let(:options) { FeatureFlagOptionParser.parse(argv) }
let(:creator) { described_class.new(options) }
let(:existing_flags) do
- { 'existing_feature_flag' => File.join('config', 'feature_flags', 'development', 'existing_feature_flag.yml') }
+ {
+ 'existing_feature_flag' =>
+ File.join('config', 'feature_flags', 'gitlab_com_derisk', 'existing_feature_flag.yml')
+ }
end
before do
@@ -31,7 +47,7 @@ RSpec.describe 'bin/feature-flag', feature_category: :feature_flags do
it 'properly creates a feature flag' do
expect(File).to receive(:write).with(
- File.join('config', 'feature_flags', 'development', 'feature_flag_name.yml'),
+ File.join('config', 'feature_flags', 'gitlab_com_derisk', 'feature_flag_name.yml'),
anything)
expect do
@@ -108,85 +124,97 @@ RSpec.describe 'bin/feature-flag', feature_category: :feature_flags do
end
describe '.read_type' do
- let(:type) { 'development' }
+ before do
+ stub_const('FeatureFlagOptionParser::TYPES',
+ development: { description: 'short' },
+ deprecated: { description: 'deprecated', deprecated: true },
+ licensed: { description: 'licensed' }
+ )
+ end
- context 'when there is only a single type defined' do
- before do
- stub_const('FeatureFlagOptionParser::TYPES',
- development: { description: 'short' }
- )
- end
+ context 'when valid type is given' do
+ let(:type) { 'development' }
- it 'returns that type' do
- expect(described_class.read_type).to eq(:development)
+ it 'reads type from stdin' do
+ expect(Readline).to receive(:readline).and_return(type)
+ expect do
+ expect(described_class.read_type).to eq(:development)
+ end.to output(/Specify the feature flag type/).to_stdout
end
end
- context 'when there is deprecated feature flag type' do
- before do
- stub_const('FeatureFlagOptionParser::TYPES',
- development: { description: 'short' },
- deprecated: { description: 'deprecated', deprecated: true }
- )
+ context 'when valid index is given' do
+ it 'picks the type successfully' do
+ expect(Readline).to receive(:readline).and_return('3')
+ expect do
+ expect(described_class.read_type).to eq(:licensed)
+ end.to output(/Specify the feature flag type./).to_stdout
end
+ end
- context 'and deprecated type is given' do
- let(:type) { 'deprecated' }
+ context 'when deprecated type is given' do
+ let(:type) { 'deprecated' }
- it 'shows error message and retries' do
- expect(Readline).to receive(:readline).and_return(type)
- expect(Readline).to receive(:readline).and_raise('EOF')
+ it 'shows error message and retries' do
+ expect(Readline).to receive(:readline).and_return(type)
+ expect(Readline).to receive(:readline).and_raise('EOF')
- expect do
- expect { described_class.read_type }.to raise_error(/EOF/)
- end.to output(/Specify the feature flag type/).to_stdout
- .and output(/Invalid type specified/).to_stderr
- end
+ expect do
+ expect { described_class.read_type }.to raise_error(/EOF/)
+ end.to output(/Specify the feature flag type/).to_stdout
+ .and output(/Invalid type specified/).to_stderr
end
end
- context 'when there are many types defined' do
- before do
- stub_const('FeatureFlagOptionParser::TYPES',
- development: { description: 'short' },
- licensed: { description: 'licensed' }
- )
- end
+ context 'when invalid type is given' do
+ let(:type) { 'invalid' }
- it 'reads type from stdin' do
+ it 'shows error message and retries' do
expect(Readline).to receive(:readline).and_return(type)
+ expect(Readline).to receive(:readline).and_raise('EOF')
+
expect do
- expect(described_class.read_type).to eq(:development)
+ expect { described_class.read_type }.to raise_error(/EOF/)
end.to output(/Specify the feature flag type/).to_stdout
+ .and output(/Invalid type specified/).to_stderr
end
+ end
- context 'when invalid type is given' do
- let(:type) { 'invalid' }
-
- it 'shows error message and retries' do
- expect(Readline).to receive(:readline).and_return(type)
- expect(Readline).to receive(:readline).and_raise('EOF')
+ context 'when invalid index is given' do
+ it 'shows error message and retries' do
+ expect(Readline).to receive(:readline).and_return('12')
+ expect(Readline).to receive(:readline).and_raise('EOF')
- expect do
- expect { described_class.read_type }.to raise_error(/EOF/)
- end.to output(/Specify the feature flag type/).to_stdout
- .and output(/Invalid type specified/).to_stderr
- end
+ expect do
+ expect { described_class.read_type }.to raise_error(/EOF/)
+ end.to output(/Specify the feature flag type/).to_stdout
+ .and output(/Invalid type specified/).to_stderr
end
end
end
describe '.read_group' do
- let(:group) { 'group::geo' }
+ context 'when valid group is given' do
+ let(:group) { 'group::geo' }
- it 'reads type from stdin' do
- expect(Readline).to receive(:readline).and_return(group)
- expect do
- expect(described_class.read_group).to eq('group::geo')
- end.to output(/Specify the group introducing the feature flag/).to_stdout
+ it 'reads group from stdin' do
+ expect(Readline).to receive(:readline).and_return(group)
+ expect do
+ expect(described_class.read_group).to eq('group::geo')
+ end.to output(/Specify the group label to which the feature flag belongs, from the following list/).to_stdout
+ end
end
- context 'invalid group given' do
+ context 'when valid index is given' do
+ it 'picks the group successfully' do
+ expect(Readline).to receive(:readline).and_return('1')
+ expect do
+ expect(described_class.read_group).to eq('group::geo')
+ end.to output(/Specify the group label to which the feature flag belongs, from the following list/).to_stdout
+ end
+ end
+
+ context 'with invalid group given' do
let(:type) { 'invalid' }
it 'shows error message and retries' do
@@ -195,78 +223,151 @@ RSpec.describe 'bin/feature-flag', feature_category: :feature_flags do
expect do
expect { described_class.read_group }.to raise_error(/EOF/)
- end.to output(/Specify the group introducing the feature flag/).to_stdout
- .and output(/The group needs to include/).to_stderr
+ end.to output(/Specify the group label to which the feature flag belongs, from the following list/).to_stdout
+ .and output(/The group label isn't in the above labels list/).to_stderr
+ end
+ end
+
+ context 'when invalid index is given' do
+ it 'shows error message and retries' do
+ expect(Readline).to receive(:readline).and_return('12')
+ expect(Readline).to receive(:readline).and_raise('EOF')
+
+ expect do
+ expect { described_class.read_group }.to raise_error(/EOF/)
+ end.to output(/Specify the group label to which the feature flag belongs, from the following list/).to_stdout
+ .and output(/The group label isn't in the above labels list/).to_stderr
end
end
end
- describe '.read_introduced_by_url' do
- let(:url) { 'https://merge-request' }
+ shared_examples 'read_url' do |method, prompt|
+ context 'with valid URL given' do
+ let(:url) { 'https://merge-request' }
- it 'reads type from stdin' do
- expect(Readline).to receive(:readline).and_return(url)
- expect do
- expect(described_class.read_introduced_by_url).to eq('https://merge-request')
- end.to output(/URL of the MR introducing the feature flag/).to_stdout
+ it 'reads URL from stdin' do
+ expect(Readline).to receive(:readline).and_return(url)
+ expect(HTTParty).to receive(:head).with(url).and_return(instance_double(HTTParty::Response, success?: true))
+
+ expect do
+ expect(described_class.public_send(method)).to eq('https://merge-request')
+ end.to output(/#{prompt}/).to_stdout
+ end
end
- context 'empty URL given' do
+ context 'with invalid URL given' do
+ let(:url) { 'https://invalid' }
+
+ it 'shows error message and retries' do
+ expect(Readline).to receive(:readline).and_return(url)
+ expect(HTTParty).to receive(:head).with(url).and_return(instance_double(HTTParty::Response, success?: false))
+ expect(Readline).to receive(:readline).and_raise('EOF')
+
+ expect do
+ expect { described_class.public_send(method) }.to raise_error(/EOF/)
+ end.to output(/#{prompt}/).to_stdout
+ .and output(/URL '#{url}' isn't valid/).to_stderr
+ end
+ end
+
+ context 'with empty URL given' do
let(:url) { '' }
it 'skips entry' do
expect(Readline).to receive(:readline).and_return(url)
+
expect do
- expect(described_class.read_introduced_by_url).to be_nil
- end.to output(/URL of the MR introducing the feature flag/).to_stdout
+ expect(described_class.public_send(method)).to be_nil
+ end.to output(/#{prompt}/).to_stdout
end
end
- context 'invalid URL given' do
- let(:url) { 'invalid' }
+ context 'with a non-URL given' do
+ let(:url) { 'malformed' }
it 'shows error message and retries' do
expect(Readline).to receive(:readline).and_return(url)
expect(Readline).to receive(:readline).and_raise('EOF')
expect do
- expect { described_class.read_introduced_by_url }.to raise_error(/EOF/)
- end.to output(/URL of the MR introducing the feature flag/).to_stdout
+ expect { described_class.public_send(method) }.to raise_error(/EOF/)
+ end.to output(/#{prompt}/).to_stdout
.and output(/URL needs to start with/).to_stderr
end
end
end
+ describe '.read_feature_issue_url' do
+ it_behaves_like 'read_url', :read_feature_issue_url, 'URL of the original feature issue'
+ end
+
+ describe '.read_introduced_by_url' do
+ it_behaves_like 'read_url', :read_introduced_by_url, 'URL of the MR introducing the feature flag'
+ end
+
describe '.read_rollout_issue_url' do
- let(:options) { double('options', name: 'foo', type: :development) }
- let(:url) { 'https://issue' }
+ let(:options) do
+ FeatureFlagOptionParser::Options.new({
+ name: 'foo',
+ username: 'joe',
+ type: :gitlab_com_derisk,
+ introduced_by_url: 'https://introduced_by_url',
+ feature_issue_url: 'https://feature_issue_url',
+ milestone: '16.6',
+ group: 'group::geo'
+ })
+ end
- it 'reads type from stdin' do
- expect(Readline).to receive(:readline).and_return(url)
- expect do
- expect(described_class.read_rollout_issue_url(options)).to eq('https://issue')
- end.to output(/URL of the rollout issue/).to_stdout
+ context 'with valid URL given' do
+ let(:url) { 'https://rollout_issue_url' }
+
+ it 'reads type from stdin' do
+ expect(described_class).to receive(:copy_to_clipboard!).and_return(true)
+ expect(Readline).to receive(:readline).and_return('') # enter to open the new issue url
+ expect(described_class).to receive(:open_url!).and_return(true)
+ expect(Readline).to receive(:readline).and_return(url)
+ expect(HTTParty).to receive(:head).with(url).and_return(instance_double(HTTParty::Response, success?: true))
+
+ expect do
+ expect(described_class.read_rollout_issue_url(options)).to eq(url)
+ end.to output(/URL of the rollout issue/).to_stdout
+ end
end
- context 'invalid URL given' do
- let(:type) { 'invalid' }
+ context 'with invalid URL given' do
+ let(:url) { 'https://invalid' }
it 'shows error message and retries' do
- expect(Readline).to receive(:readline).and_return(type)
+ expect(described_class).to receive(:copy_to_clipboard!).and_return(true)
+ expect(Readline).to receive(:readline).and_return('') # enter to open the new issue url
+ expect(described_class).to receive(:open_url!).and_return(true)
+ expect(Readline).to receive(:readline).and_return(url)
+ expect(HTTParty).to receive(:head).with(url).and_return(instance_double(HTTParty::Response, success?: false))
expect(Readline).to receive(:readline).and_raise('EOF')
expect do
expect { described_class.read_rollout_issue_url(options) }.to raise_error(/EOF/)
end.to output(/URL of the rollout issue/).to_stdout
- .and output(/URL needs to start/).to_stderr
+ .and output(/URL '#{url}' isn't valid/).to_stderr
end
end
- end
- describe '.read_ee_only' do
- let(:options) { double('options', name: 'foo', type: :development) }
+ context 'with a non-URL given' do
+ let(:url) { 'malformed' }
+
+ it 'shows error message and retries' do
+ expect(described_class).to receive(:copy_to_clipboard!).and_return(true)
+ expect(Readline).to receive(:readline).and_return('') # enter to open the new issue url
+ expect(described_class).to receive(:open_url!).and_return(true)
+ expect(Readline).to receive(:readline).and_return(url)
+ expect(Readline).to receive(:readline).and_raise('EOF')
- it { expect(described_class.read_ee_only(options)).to eq(false) }
+ expect do
+ expect { described_class.read_rollout_issue_url(options) }.to raise_error(/EOF/)
+ end.to output(/URL of the rollout issue/).to_stdout
+ .and output(/URL needs to start/).to_stderr
+ end
+ end
end
end
end