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/audit_event_type_spec.rb')
-rw-r--r--spec/bin/audit_event_type_spec.rb293
1 files changed, 293 insertions, 0 deletions
diff --git a/spec/bin/audit_event_type_spec.rb b/spec/bin/audit_event_type_spec.rb
new file mode 100644
index 00000000000..d4b1ebf08de
--- /dev/null
+++ b/spec/bin/audit_event_type_spec.rb
@@ -0,0 +1,293 @@
+# frozen_string_literal: true
+
+require 'fast_spec_helper'
+require 'rspec-parameterized'
+
+load File.expand_path('../../bin/audit-event-type', __dir__)
+
+RSpec.describe 'bin/audit-event-type' do
+ using RSpec::Parameterized::TableSyntax
+
+ describe AuditEventTypeCreator do
+ let(:argv) { %w[test_audit_event -d test -g govern::compliance -s -t -i https://url -m http://url] }
+ let(:options) { AuditEventTypeOptionParser.parse(argv) }
+ let(:creator) { described_class.new(options) }
+ let(:existing_audit_event_types) do
+ { 'existing_audit_event_type' => File.join('config', 'audit_events', 'types', 'existing_audit_event_type.yml') }
+ end
+
+ before do
+ allow(creator).to receive(:all_audit_event_type_names) { existing_audit_event_types }
+ allow(creator).to receive(:branch_name).and_return('feature-branch')
+ allow(creator).to receive(:editor).and_return(nil)
+
+ # ignore writes
+ allow(File).to receive(:write).and_return(true)
+
+ # ignore stdin
+ allow(Readline).to receive(:readline).and_raise('EOF')
+ end
+
+ subject(:create_audit_event_type) { creator.execute }
+
+ it 'properly creates an audit event type' do
+ expect(File).to receive(:write).with(
+ File.join('config', 'audit_events', 'types', 'test_audit_event.yml'),
+ anything)
+
+ expect do
+ create_audit_event_type
+ end.to output(/name: test_audit_event/).to_stdout
+ end
+
+ context 'when running on master' do
+ it 'requires feature branch' do
+ expect(creator).to receive(:branch_name).and_return('master')
+
+ expect { create_audit_event_type }.to raise_error(AuditEventTypeHelpers::Abort, /Create a branch first/)
+ end
+ end
+
+ context 'with invalid audit event type names' do
+ where(:argv, :ex) do
+ %w[.invalid.audit.type] | /Provide a name for the audit event type that is/
+ %w[existing_audit_event_type] | /already exists!/
+ end
+
+ with_them do
+ it do
+ expect { create_audit_event_type }.to raise_error(ex)
+ end
+ end
+ end
+ end
+
+ describe AuditEventTypeOptionParser do
+ describe '.parse' do
+ where(:param, :argv, :result) do
+ :name | %w[foo] | 'foo'
+ :amend | %w[foo --amend] | true
+ :force | %w[foo -f] | true
+ :force | %w[foo --force] | true
+ :description | %w[foo -d desc] | 'desc'
+ :description | %w[foo --description desc] | 'desc'
+ :group | %w[foo -g govern::compliance] | 'govern::compliance'
+ :group | %w[foo --group govern::compliance] | 'govern::compliance'
+ :milestone | %w[foo -M 15.6] | '15.6'
+ :milestone | %w[foo --milestone 15.6] | '15.6'
+ :saved_to_database | %w[foo -s] | true
+ :saved_to_database | %w[foo --saved-to-database] | true
+ :saved_to_database | %w[foo --no-saved-to-database] | false
+ :streamed | %w[foo -t] | true
+ :streamed | %w[foo --streamed] | true
+ :streamed | %w[foo --no-streamed] | false
+ :dry_run | %w[foo -n] | true
+ :dry_run | %w[foo --dry-run] | true
+ :ee | %w[foo -e] | true
+ :ee | %w[foo --ee] | true
+ :jh | %w[foo -j] | true
+ :jh | %w[foo --jh] | true
+ :introduced_by_mr | %w[foo -m https://url] | 'https://url'
+ :introduced_by_mr | %w[foo --introduced-by-mr https://url] | 'https://url'
+ :introduced_by_issue | %w[foo -i https://url] | 'https://url'
+ :introduced_by_issue | %w[foo --introduced-by-issue https://url] | 'https://url'
+ end
+
+ with_them do
+ it do
+ options = described_class.parse(Array(argv))
+
+ expect(options.public_send(param)).to eq(result)
+ end
+ end
+
+ it 'raises an error when name of the audit event type is missing' do
+ expect do
+ expect do
+ described_class.parse(%w[--amend])
+ end.to output(/Name for the type of audit event is required/).to_stdout
+ end.to raise_error(AuditEventTypeHelpers::Abort)
+ end
+
+ it 'parses -h' do
+ expect do
+ expect { described_class.parse(%w[foo -h]) }.to output(%r{Usage: bin/audit-event-type}).to_stdout
+ end.to raise_error(AuditEventTypeHelpers::Done)
+ end
+ end
+
+ describe '.read_description' do
+ let(:description) { 'This is a test description for an audit event type.' }
+
+ it 'reads description from stdin' do
+ expect(Readline).to receive(:readline).and_return(description)
+ expect do
+ expect(described_class.read_description).to eq('This is a test description for an audit event type.')
+ end.to output(/Specify a human-readable description of how this event is triggered:/).to_stdout
+ end
+
+ context 'when description is empty' do
+ let(:description) { '' }
+
+ it 'shows error message and retries' do
+ expect(Readline).to receive(:readline).and_return(description)
+ expect(Readline).to receive(:readline).and_raise('EOF')
+
+ expect do
+ expect { described_class.read_description }.to raise_error(/EOF/)
+ end.to output(/Specify a human-readable description of how this event is triggered:/)
+ .to_stdout.and output(/description is a required field/).to_stderr
+ end
+ end
+ end
+
+ describe '.read_group' do
+ let(:group) { 'govern::compliance' }
+
+ it 'reads group from stdin' do
+ expect(Readline).to receive(:readline).and_return(group)
+ expect do
+ expect(described_class.read_group).to eq('govern::compliance')
+ end.to output(/Specify the group introducing the audit event type, like `govern::compliance`:/).to_stdout
+ end
+
+ context 'when group is empty' do
+ let(:group) { '' }
+
+ it 'shows error message and retries' do
+ expect(Readline).to receive(:readline).and_return(group)
+ 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 introducing the audit event type, like `govern::compliance`:/)
+ .to_stdout.and output(/group is a required field/).to_stderr
+ end
+ end
+ end
+
+ describe '.read_saved_to_database' do
+ let(:saved_to_database) { 'true' }
+
+ it 'reads saved_to_database from stdin' do
+ expect(Readline).to receive(:readline).and_return(saved_to_database)
+ expect do
+ expect(described_class.read_saved_to_database).to eq(true)
+ end.to output(/Specify whether to persist events to database and JSON logs \[yes, no\]:/).to_stdout
+ end
+
+ context 'when saved_to_database is invalid' do
+ let(:saved_to_database) { 'non boolean value' }
+
+ it 'shows error message and retries' do
+ expect(Readline).to receive(:readline).and_return(saved_to_database)
+ expect(Readline).to receive(:readline).and_raise('EOF')
+
+ expect do
+ expect { described_class.read_saved_to_database }.to raise_error(/EOF/)
+ end.to output(/Specify whether to persist events to database and JSON logs \[yes, no\]:/)
+ .to_stdout.and output(/saved_to_database is a required boolean field/).to_stderr
+ end
+ end
+ end
+
+ describe '.read_streamed' do
+ let(:streamed) { 'true' }
+
+ it 'reads streamed from stdin' do
+ expect(Readline).to receive(:readline).and_return(streamed)
+ expect do
+ expect(described_class.read_streamed).to eq(true)
+ end.to output(/Specify if events should be streamed to external services \(if configured\) \[yes, no\]:/)
+ .to_stdout
+ end
+
+ context 'when streamed is invalid' do
+ let(:streamed) { 'non boolean value' }
+
+ it 'shows error message and retries' do
+ expect(Readline).to receive(:readline).and_return(streamed)
+ expect(Readline).to receive(:readline).and_raise('EOF')
+
+ expect do
+ expect { described_class.read_streamed }.to raise_error(/EOF/)
+ end.to output(/Specify if events should be streamed to external services \(if configured\) \[yes, no\]:/)
+ .to_stdout.and output(/streamed is a required boolean field/).to_stderr
+ end
+ end
+ end
+
+ describe '.read_introduced_by_mr' do
+ let(:url) { 'https://merge-request' }
+
+ it 'reads introduced_by_mr from stdin' do
+ expect(Readline).to receive(:readline).and_return(url)
+ expect do
+ expect(described_class.read_introduced_by_mr).to eq('https://merge-request')
+ end.to output(/URL to GitLab merge request that added this type of audit event:/).to_stdout
+ end
+
+ context 'when URL is empty' do
+ let(:url) { '' }
+
+ it 'does not raise an error' do
+ expect(Readline).to receive(:readline).and_return(url)
+
+ expect do
+ expect(described_class.read_introduced_by_mr).to be_nil
+ end.to output(/URL to GitLab merge request that added this type of audit event:/).to_stdout
+ end
+ end
+
+ context 'when URL is invalid' do
+ let(:url) { 'invalid' }
+
+ 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_mr }.to raise_error(/EOF/)
+ end.to output(/URL to GitLab merge request that added this type of audit event:/)
+ .to_stdout.and output(/URL needs to start with https/).to_stderr
+ end
+ end
+ end
+
+ describe '.read_introduced_by_issue' do
+ let(:url) { 'https://issue' }
+
+ it 'reads type from stdin' do
+ expect(Readline).to receive(:readline).and_return(url)
+ expect do
+ expect(described_class.read_introduced_by_issue).to eq('https://issue')
+ end.to output(/URL to GitLab issue that added this type of audit event:/).to_stdout
+ end
+
+ context 'when URL is invalid' 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')
+
+ expect do
+ expect { described_class.read_introduced_by_issue }.to raise_error(/EOF/)
+ end.to output(/URL to GitLab issue that added this type of audit event:/)
+ .to_stdout.and output(/URL needs to start with https/).to_stderr
+ end
+ end
+ end
+
+ describe '.read_milestone' do
+ before do
+ allow(File).to receive(:read).with('VERSION').and_return('15.6.0-pre')
+ allow(File).to receive(:read).and_call_original
+ end
+
+ it 'returns the correct milestone from the VERSION file' do
+ expect(described_class.read_milestone).to eq('15.6')
+ end
+ end
+ end
+end