diff options
Diffstat (limited to 'spec')
22 files changed, 104 insertions, 1100 deletions
diff --git a/spec/controllers/groups/uploads_controller_spec.rb b/spec/controllers/groups/uploads_controller_spec.rb index 6649e8f057c..7795fff5541 100644 --- a/spec/controllers/groups/uploads_controller_spec.rb +++ b/spec/controllers/groups/uploads_controller_spec.rb @@ -76,31 +76,17 @@ RSpec.describe Groups::UploadsController do context 'when uploader class does not match the upload' do let(:uploader_class) { FileUploader } - it 'responds with status 200 but logs a deprecation message' do - expect(Gitlab::AppJsonLogger).to receive(:info).with( - message: 'Deprecated usage of build_uploader_from_params', - uploader_class: uploader_class.name, - path: filename, - exists: true - ) - + it 'responds with status 404' do show_upload - expect(response).to have_gitlab_http_status(:ok) + expect(response).to have_gitlab_http_status(:not_found) end end context 'when filename does not match' do let(:invalid_filename) { 'invalid_filename.jpg' } - it 'responds with status 404 and logs a deprecation message' do - expect(Gitlab::AppJsonLogger).to receive(:info).with( - message: 'Deprecated usage of build_uploader_from_params', - uploader_class: uploader_class.name, - path: invalid_filename, - exists: false - ) - + it 'responds with status 404' do get :show, params: params.merge(secret: secret, filename: invalid_filename) expect(response).to have_gitlab_http_status(:not_found) diff --git a/spec/deprecation_warnings.rb b/spec/deprecation_warnings.rb index 45fed5fecca..abdd13ee8e7 100644 --- a/spec/deprecation_warnings.rb +++ b/spec/deprecation_warnings.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require_relative '../lib/gitlab/utils' +require 'gitlab/utils/all' return if Gitlab::Utils.to_boolean(ENV['SILENCE_DEPRECATIONS'], default: false) # Enable deprecation warnings by default and make them more visible diff --git a/spec/fast_spec_helper.rb b/spec/fast_spec_helper.rb index 03c8919912c..47a90efab1e 100644 --- a/spec/fast_spec_helper.rb +++ b/spec/fast_spec_helper.rb @@ -18,13 +18,12 @@ RSpec.configure(&:disable_monkey_patching!) require 'active_support/all' require 'pry' +require 'gitlab/utils/all' require_relative 'rails_autoload' require_relative '../config/settings' require_relative 'support/rspec' require_relative '../lib/gitlab' -require_relative '../lib/gitlab/utils' -require_relative '../lib/gitlab/utils/strong_memoize' require_relative 'simplecov_env' SimpleCovEnv.start! diff --git a/spec/features/markdown/sandboxed_mermaid_spec.rb b/spec/features/markdown/sandboxed_mermaid_spec.rb index f8a535191da..87696eb82e5 100644 --- a/spec/features/markdown/sandboxed_mermaid_spec.rb +++ b/spec/features/markdown/sandboxed_mermaid_spec.rb @@ -16,8 +16,9 @@ RSpec.describe 'Sandboxed Mermaid rendering', :js, feature_category: :team_plann MERMAID end - let_it_be(:expected) do - %(<iframe src="/-/sandbox/mermaid" sandbox="allow-scripts allow-popups" frameborder="0" scrolling="no") + let(:expected) do + src = "http://#{Capybara.current_session.server.host}:#{Capybara.current_session.server.port}/-/sandbox/mermaid" + %(<iframe src="#{src}" sandbox="allow-scripts allow-popups" frameborder="0" scrolling="no") end context 'in an issue' do diff --git a/spec/frontend/behaviors/markdown/render_sandboxed_mermaid_spec.js b/spec/frontend/behaviors/markdown/render_sandboxed_mermaid_spec.js index de0e5063e49..88312a780d1 100644 --- a/spec/frontend/behaviors/markdown/render_sandboxed_mermaid_spec.js +++ b/spec/frontend/behaviors/markdown/render_sandboxed_mermaid_spec.js @@ -9,7 +9,7 @@ import renderMermaid, { describe('Mermaid diagrams renderer', () => { // Finders - const findMermaidIframes = () => document.querySelectorAll('iframe[src="/-/sandbox/mermaid"]'); + const findMermaidIframes = () => document.querySelectorAll('iframe[src*="/-/sandbox/mermaid"]'); const findDangerousMermaidAlert = () => createWrapper(document.querySelector('[data-testid="alert-warning"]')); diff --git a/spec/frontend/issuable/components/status_box_spec.js b/spec/frontend/issuable/components/status_box_spec.js index d26f287d90c..0d47595c9e6 100644 --- a/spec/frontend/issuable/components/status_box_spec.js +++ b/spec/frontend/issuable/components/status_box_spec.js @@ -18,6 +18,8 @@ describe('Merge request status box component', () => { ${'merge_request'} | ${'Merged'} | ${'merged'} | ${'issuable-status-badge-merged'} | ${'info'} | ${'merge'} ${'issue'} | ${'Open'} | ${'opened'} | ${'issuable-status-badge-open'} | ${'success'} | ${'issues'} ${'issue'} | ${'Closed'} | ${'closed'} | ${'issuable-status-badge-closed'} | ${'info'} | ${'issue-closed'} + ${'epic'} | ${'Open'} | ${'opened'} | ${'issuable-status-badge-open'} | ${'success'} | ${'epic'} + ${'epic'} | ${'Closed'} | ${'closed'} | ${'issuable-status-badge-closed'} | ${'info'} | ${'epic-closed'} `( 'with issuableType set to "$issuableType" and state set to "$initialState"', ({ issuableType, badgeText, initialState, badgeClass, badgeVariant, badgeIcon }) => { diff --git a/spec/frontend/issuable/popover/components/issue_popover_spec.js b/spec/frontend/issuable/popover/components/issue_popover_spec.js index a7605016039..0596433ce9a 100644 --- a/spec/frontend/issuable/popover/components/issue_popover_spec.js +++ b/spec/frontend/issuable/popover/components/issue_popover_spec.js @@ -26,7 +26,7 @@ describe('Issue Popover', () => { apolloProvider: createMockApollo([[issueQuery, queryResponse]]), propsData: { target: document.createElement('a'), - projectPath: 'foo/bar', + namespacePath: 'foo/bar', iid: '1', cachedTitle: 'Cached title', }, diff --git a/spec/frontend/issuable/popover/components/mr_popover_spec.js b/spec/frontend/issuable/popover/components/mr_popover_spec.js index 5b29ecfc0ba..4ed783da853 100644 --- a/spec/frontend/issuable/popover/components/mr_popover_spec.js +++ b/spec/frontend/issuable/popover/components/mr_popover_spec.js @@ -64,7 +64,7 @@ describe('MR Popover', () => { apolloProvider: createMockApollo([[mergeRequestQuery, queryResponse]]), propsData: { target: document.createElement('a'), - projectPath: 'foo/bar', + namespacePath: 'foo/bar', iid: '1', cachedTitle: 'Cached Title', }, diff --git a/spec/frontend/issuable/popover/index_spec.js b/spec/frontend/issuable/popover/index_spec.js index b1aa7f0f0b0..bf9dce4867f 100644 --- a/spec/frontend/issuable/popover/index_spec.js +++ b/spec/frontend/issuable/popover/index_spec.js @@ -1,6 +1,6 @@ import { setHTMLFixture } from 'helpers/fixtures'; import * as createDefaultClient from '~/lib/graphql'; -import initIssuablePopovers from '~/issuable/popover/index'; +import initIssuablePopovers, * as popover from '~/issuable/popover/index'; createDefaultClient.default = jest.fn(); @@ -9,6 +9,7 @@ describe('initIssuablePopovers', () => { let mr2; let mr3; let issue1; + let workItem1; beforeEach(() => { setHTMLFixture(` @@ -24,30 +25,69 @@ describe('initIssuablePopovers', () => { <div id="four" class="gfm-issue" title="title" data-iid="1" data-project-path="group/project" data-reference-type="issue"> MR3 </div> + <div id="five" class="gfm-work_item" title="title" data-iid="1" data-project-path="group/project" data-reference-type="work_item"> + MR3 + </div> `); mr1 = document.querySelector('#one'); mr2 = document.querySelector('#two'); mr3 = document.querySelector('#three'); issue1 = document.querySelector('#four'); - - mr1.addEventListener = jest.fn(); - mr2.addEventListener = jest.fn(); - mr3.addEventListener = jest.fn(); - issue1.addEventListener = jest.fn(); + workItem1 = document.querySelector('#five'); }); - it('does not add the same event listener twice', () => { - initIssuablePopovers([mr1, mr1, mr2, issue1]); + describe('init function', () => { + beforeEach(() => { + mr1.addEventListener = jest.fn(); + mr2.addEventListener = jest.fn(); + mr3.addEventListener = jest.fn(); + issue1.addEventListener = jest.fn(); + workItem1.addEventListener = jest.fn(); + }); + + it('does not add the same event listener twice', () => { + initIssuablePopovers([mr1, mr1, mr2, issue1, workItem1]); + + expect(mr1.addEventListener).toHaveBeenCalledTimes(1); + expect(mr2.addEventListener).toHaveBeenCalledTimes(1); + expect(issue1.addEventListener).toHaveBeenCalledTimes(1); + expect(workItem1.addEventListener).toHaveBeenCalledTimes(1); + }); - expect(mr1.addEventListener).toHaveBeenCalledTimes(1); - expect(mr2.addEventListener).toHaveBeenCalledTimes(1); - expect(issue1.addEventListener).toHaveBeenCalledTimes(1); + it('does not add listener if it does not have the necessary data attributes', () => { + initIssuablePopovers([mr1, mr2, mr3]); + + expect(mr3.addEventListener).not.toHaveBeenCalled(); + }); }); - it('does not add listener if it does not have the necessary data attributes', () => { - initIssuablePopovers([mr1, mr2, mr3]); + describe('mount function', () => { + const expectedMountObject = { + apolloProvider: expect.anything(), + iid: '1', + namespacePath: 'group/project', + title: 'title', + }; + + beforeEach(() => { + jest.spyOn(popover, 'handleIssuablePopoverMount').mockImplementation(jest.fn()); + }); + + it('calls popover mount function with components for Issue, MR, and Work Item', () => { + initIssuablePopovers([mr1, issue1, workItem1], popover.handleIssuablePopoverMount); + + [mr1, issue1, workItem1].forEach(async (el) => { + await el.dispatchEvent(new Event('mouseenter', { target: el })); - expect(mr3.addEventListener).not.toHaveBeenCalled(); + expect(popover.handleIssuablePopoverMount).toHaveBeenCalledWith( + expect.objectContaining({ + ...expectedMountObject, + referenceType: el.dataset.referenceType, + target: el, + }), + ); + }); + }); }); }); diff --git a/spec/frontend/lib/utils/datetime/date_format_utility_spec.js b/spec/frontend/lib/utils/datetime/date_format_utility_spec.js index e7a6367eeac..65018fe1625 100644 --- a/spec/frontend/lib/utils/datetime/date_format_utility_spec.js +++ b/spec/frontend/lib/utils/datetime/date_format_utility_spec.js @@ -152,3 +152,18 @@ describe('formatUtcOffset', () => { expect(utils.formatUtcOffset(offset)).toEqual(expected); }); }); + +describe('humanTimeframe', () => { + it.each` + startDate | dueDate | returnValue + ${'2021-1-1'} | ${'2021-2-28'} | ${'Jan 1 – Feb 28, 2021'} + ${'2021-1-1'} | ${'2022-2-28'} | ${'Jan 1, 2021 – Feb 28, 2022'} + ${'2021-1-1'} | ${null} | ${'Jan 1, 2021 – No due date'} + ${null} | ${'2021-2-28'} | ${'No start date – Feb 28, 2021'} + `( + 'returns string "$returnValue" when startDate is $startDate and dueDate is $dueDate', + ({ startDate, dueDate, returnValue }) => { + expect(utils.humanTimeframe(startDate, dueDate)).toBe(returnValue); + }, + ); +}); diff --git a/spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb b/spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb index 1c23a619b38..5f2994165f2 100644 --- a/spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb +++ b/spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb @@ -436,6 +436,7 @@ RSpec.describe Gitlab::SidekiqLogging::StructuredLogger do call_subject(job, 'test_queue') do job['deferred'] = true job['deferred_by'] = :feature_flag + job['deferred_count'] = 1 end end end diff --git a/spec/lib/gitlab/sidekiq_middleware/defer_jobs_spec.rb b/spec/lib/gitlab/sidekiq_middleware/defer_jobs_spec.rb index 195a79c22ec..88ba228b66b 100644 --- a/spec/lib/gitlab/sidekiq_middleware/defer_jobs_spec.rb +++ b/spec/lib/gitlab/sidekiq_middleware/defer_jobs_spec.rb @@ -43,6 +43,13 @@ RSpec.describe Gitlab::SidekiqMiddleware::DeferJobs, feature_category: :scalabil expect(TestDeferredWorker).to receive(:perform_in).with(described_class::DELAY, *job['args']) expect { |b| subject.call(TestDeferredWorker.new, job, queue, &b) }.not_to yield_control end + + it 'increments the defer_count' do + (1..5).each do |count| + subject.call(TestDeferredWorker.new, job, queue) + expect(job).to include('deferred_count' => count) + end + end end context 'for other workers' do @@ -51,7 +58,7 @@ RSpec.describe Gitlab::SidekiqMiddleware::DeferJobs, feature_category: :scalabil end end - it 'increments the counter' do + it 'increments the metric counter' do subject.call(TestDeferredWorker.new, job, queue) counter = ::Gitlab::Metrics.registry.get(:sidekiq_jobs_deferred_total) diff --git a/spec/lib/gitlab/utils/strong_memoize_spec.rb b/spec/lib/gitlab/utils/strong_memoize_spec.rb deleted file mode 100644 index ea8083e7d7f..00000000000 --- a/spec/lib/gitlab/utils/strong_memoize_spec.rb +++ /dev/null @@ -1,374 +0,0 @@ -# frozen_string_literal: true - -require 'fast_spec_helper' -require 'rspec-benchmark' -require 'rspec-parameterized' -require 'active_support/testing/time_helpers' - -RSpec.configure do |config| - config.include RSpec::Benchmark::Matchers -end - -RSpec.describe Gitlab::Utils::StrongMemoize, feature_category: :shared do - include ActiveSupport::Testing::TimeHelpers - - let(:klass) do - strong_memoize_class = described_class - - Struct.new(:value) do - include strong_memoize_class - - def self.method_added_list - @method_added_list ||= [] - end - - def self.method_added(name) - method_added_list << name - end - - def method_name - strong_memoize(:method_name) do # rubocop: disable Gitlab/StrongMemoizeAttr - trace << value - value - end - end - - def method_name_with_expiration - strong_memoize_with_expiration(:method_name_with_expiration, 1) do - trace << value - value - end - end - - def method_name_attr - trace << value - value - end - strong_memoize_attr :method_name_attr - - def enabled? - trace << value - value - end - strong_memoize_attr :enabled? - - def method_name_with_args(*args) - strong_memoize_with(:method_name_with_args, args) do - trace << [value, args] - value - end - end - - def trace - @trace ||= [] - end - - protected - - def private_method; end - private :private_method - strong_memoize_attr :private_method - - public - - def protected_method; end - protected :protected_method - strong_memoize_attr :protected_method - - private - - def public_method; end - public :public_method - strong_memoize_attr :public_method - end - end - - subject(:object) { klass.new(value) } - - shared_examples 'caching the value' do - let(:member_name) { described_class.normalize_key(method_name) } - - it 'only calls the block once' do - value0 = object.send(method_name) - value1 = object.send(method_name) - - expect(value0).to eq(value) - expect(value1).to eq(value) - expect(object.trace).to contain_exactly(value) - end - - it 'returns and defines the instance variable for the exact value' do - returned_value = object.send(method_name) - memoized_value = object.instance_variable_get(:"@#{member_name}") - - expect(returned_value).to eql(value) - expect(memoized_value).to eql(value) - end - end - - describe '#strong_memoize' do - [nil, false, true, 'value', 0, [0]].each do |value| - context "with value #{value}" do - let(:value) { value } - let(:method_name) { :method_name } - - it_behaves_like 'caching the value' - - it 'raises exception for invalid type as key' do - expect { object.strong_memoize(10) { 20 } }.to raise_error /Invalid type of '10'/ - end - - it 'raises exception for invalid characters in key' do - expect { object.strong_memoize(:enabled?) { 20 } } - .to raise_error /is not allowed as an instance variable name/ - end - end - end - - context "memory allocation", type: :benchmark do - let(:value) { 'aaa' } - - before do - object.method_name # warmup - end - - [:method_name, "method_name"].each do |argument| - context "for #{argument.class}" do - it 'does allocate exactly one string when fetching value' do - expect do - object.strong_memoize(argument) { 10 } - end.to perform_allocation(1) - end - - it 'does allocate exactly one string when storing value' do - object.clear_memoization(:method_name) # clear to force set - - expect do - object.strong_memoize(argument) { 10 } - end.to perform_allocation(1) - end - end - end - end - end - - describe '#strong_memoize_with_expiration' do - [nil, false, true, 'value', 0, [0]].each do |value| - context "with value #{value}" do - let(:value) { value } - let(:method_name) { :method_name_with_expiration } - - it_behaves_like 'caching the value' - - it 'raises exception for invalid type as key' do - expect { object.strong_memoize_with_expiration(10, 1) { 20 } }.to raise_error /Invalid type of '10'/ - end - - it 'raises exception for invalid characters in key' do - expect { object.strong_memoize_with_expiration(:enabled?, 1) { 20 } } - .to raise_error /is not allowed as an instance variable name/ - end - end - end - - context 'value memoization test' do - let(:value) { 'value' } - - it 'caches the value for specified number of seconds' do - object.method_name_with_expiration - object.method_name_with_expiration - - expect(object.trace.count).to eq(1) - - travel_to(Time.current + 2.seconds) do - object.method_name_with_expiration - - expect(object.trace.count).to eq(2) - end - end - end - end - - describe '#strong_memoize_with' do - [nil, false, true, 'value', 0, [0]].each do |value| - context "with value #{value}" do - let(:value) { value } - - it 'only calls the block once' do - value0 = object.method_name_with_args(1) - value1 = object.method_name_with_args(1) - value2 = object.method_name_with_args([2, 3]) - value3 = object.method_name_with_args([2, 3]) - - expect(value0).to eq(value) - expect(value1).to eq(value) - expect(value2).to eq(value) - expect(value3).to eq(value) - - expect(object.trace).to contain_exactly([value, [1]], [value, [[2, 3]]]) - end - - it 'returns and defines the instance variable for the exact value' do - returned_value = object.method_name_with_args(1, 2, 3) - memoized_value = object.instance_variable_get(:@method_name_with_args) - - expect(returned_value).to eql(value) - expect(memoized_value).to eql({ [[1, 2, 3]] => value }) - end - end - end - end - - describe '#strong_memoized?' do - shared_examples 'memoization check' do |method_name| - context "for #{method_name}" do - let(:value) { :anything } - - subject { object.strong_memoized?(method_name) } - - it 'returns false if the value is uncached' do - is_expected.to be(false) - end - - it 'returns true if the value is cached' do - object.public_send(method_name) - - is_expected.to be(true) - end - end - end - - it_behaves_like 'memoization check', :method_name - it_behaves_like 'memoization check', :enabled? - end - - describe '#clear_memoization' do - shared_examples 'clearing memoization' do |method_name| - let(:member_name) { described_class.normalize_key(method_name) } - let(:value) { 'mepmep' } - - it 'removes the instance variable' do - object.public_send(method_name) - - object.clear_memoization(method_name) - - expect(object.instance_variable_defined?(:"@#{member_name}")).to be(false) - end - end - - it_behaves_like 'clearing memoization', :method_name - it_behaves_like 'clearing memoization', :enabled? - end - - describe '.strong_memoize_attr' do - [nil, false, true, 'value', 0, [0]].each do |value| - context "with value '#{value}'" do - let(:value) { value } - - context 'memoized after method definition' do - let(:method_name) { :method_name_attr } - - it_behaves_like 'caching the value' - - it 'calls the existing .method_added' do - expect(klass.method_added_list).to include(:method_name_attr) - end - - it 'retains method arity' do - expect(klass.instance_method(method_name).arity).to eq(0) - end - end - end - end - - describe 'method visibility' do - it 'sets private visibility' do - expect(klass.private_instance_methods).to include(:private_method) - expect(klass.protected_instance_methods).not_to include(:private_method) - expect(klass.public_instance_methods).not_to include(:private_method) - end - - it 'sets protected visibility' do - expect(klass.private_instance_methods).not_to include(:protected_method) - expect(klass.protected_instance_methods).to include(:protected_method) - expect(klass.public_instance_methods).not_to include(:protected_method) - end - - it 'sets public visibility' do - expect(klass.private_instance_methods).not_to include(:public_method) - expect(klass.protected_instance_methods).not_to include(:public_method) - expect(klass.public_instance_methods).to include(:public_method) - end - end - - context "when method doesn't exist" do - let(:klass) do - strong_memoize_class = described_class - - Struct.new(:value) do - include strong_memoize_class - end - end - - subject { klass.strong_memoize_attr(:nonexistent_method) } - - it 'fails when strong-memoizing a nonexistent method' do - expect { subject }.to raise_error(NameError, %r{undefined method `nonexistent_method' for class}) - end - end - - context 'when memoized method has parameters' do - it 'raises an error' do - expected_message = /Using `strong_memoize_attr` on methods with parameters is not supported/ - - expect do - strong_memoize_class = described_class - - Class.new do - include strong_memoize_class - - def method_with_parameters(params); end - strong_memoize_attr :method_with_parameters - end - end.to raise_error(RuntimeError, expected_message) - end - end - end - - describe '.normalize_key' do - using RSpec::Parameterized::TableSyntax - - subject { described_class.normalize_key(input) } - - where(:input, :output, :valid) do - :key | :key | true - "key" | "key" | true - :key? | "key?" | true - "key?" | "key?" | true - :key! | "key!" | true - "key!" | "key!" | true - # invalid cases caught elsewhere - :"ke?y" | :"ke?y" | false - "ke?y" | "ke?y" | false - :"ke!y" | :"ke!y" | false - "ke!y" | "ke!y" | false - end - - with_them do - let(:ivar) { "@#{output}" } - - it { is_expected.to eq(output) } - - if params[:valid] - it 'is a valid ivar name' do - expect { instance_variable_defined?(ivar) }.not_to raise_error - end - else - it 'raises a NameError error' do - expect { instance_variable_defined?(ivar) } - .to raise_error(NameError, /not allowed as an instance/) - end - end - end - end -end diff --git a/spec/lib/gitlab/utils_spec.rb b/spec/lib/gitlab/utils_spec.rb deleted file mode 100644 index 7b9504366ec..00000000000 --- a/spec/lib/gitlab/utils_spec.rb +++ /dev/null @@ -1,477 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Gitlab::Utils do - using RSpec::Parameterized::TableSyntax - - delegate :to_boolean, :boolean_to_yes_no, :slugify, :which, - :ensure_array_from_string, :bytes_to_megabytes, - :append_path, :remove_leading_slashes, :allowlisted?, - :decode_path, :ms_to_round_sec, to: :described_class - - describe '.allowlisted?' do - let(:allowed_paths) { ['/home/foo', '/foo/bar', '/etc/passwd'] } - - it 'returns true if path is allowed' do - expect(allowlisted?('/foo/bar', allowed_paths)).to be(true) - end - - it 'returns false if path is not allowed' do - expect(allowlisted?('/test/test', allowed_paths)).to be(false) - end - end - - describe '.decode_path' do - it 'returns path unencoded for singled-encoded paths' do - expect(decode_path('%2Fhome%2Fbar%3Fasd%3Dqwe')).to eq('/home/bar?asd=qwe') - end - - it 'returns path when it is unencoded' do - expect(decode_path('/home/bar?asd=qwe')).to eq('/home/bar?asd=qwe') - end - - [ - '..%252F..%252F..%252Fetc%252Fpasswd', - '%25252Fresult%25252Fchosennickname%25253D%252522jj%252522' - ].each do |multiple_encoded_path| - it 'raises an exception when the path is multiple-encoded' do - expect { decode_path(multiple_encoded_path) }.to raise_error(/path #{multiple_encoded_path} is not allowed/) - end - end - end - - describe '.slugify' do - { - 'TEST' => 'test', - 'project_with_underscores' => 'project-with-underscores', - 'namespace/project' => 'namespace-project', - 'a' * 70 => 'a' * 63, - 'test_trailing_' => 'test-trailing' - }.each do |original, expected| - it "slugifies #{original} to #{expected}" do - expect(slugify(original)).to eq(expected) - end - end - end - - describe '.ms_to_round_sec' do - where(:original, :expected) do - 1999.8999 | 1.9999 - 12384 | 12.384 - 333 | 0.333 - 1333.33333333 | 1.333333 - end - - with_them do - it "returns rounded seconds" do - expect(ms_to_round_sec(original)).to eq(expected) - end - end - end - - describe '.nlbr' do - it 'replaces new lines with <br>' do - expect(described_class.nlbr("<b>hello</b>\n<i>world</i>")).to eq("hello<br>world") - end - end - - describe '.remove_line_breaks' do - where(:original, :expected) do - "foo\nbar\nbaz" | "foobarbaz" - "foo\r\nbar\r\nbaz" | "foobarbaz" - "foobar" | "foobar" - end - - with_them do - it "replace line breaks with an empty string" do - expect(described_class.remove_line_breaks(original)).to eq(expected) - end - end - end - - describe '.to_boolean' do - it 'accepts booleans' do - expect(to_boolean(true)).to be(true) - expect(to_boolean(false)).to be(false) - end - - it 'converts a valid value to a boolean' do - expect(to_boolean(true)).to be(true) - expect(to_boolean('true')).to be(true) - expect(to_boolean('YeS')).to be(true) - expect(to_boolean('t')).to be(true) - expect(to_boolean('1')).to be(true) - expect(to_boolean(1)).to be(true) - expect(to_boolean('ON')).to be(true) - - expect(to_boolean('FaLse')).to be(false) - expect(to_boolean('F')).to be(false) - expect(to_boolean('NO')).to be(false) - expect(to_boolean('n')).to be(false) - expect(to_boolean('0')).to be(false) - expect(to_boolean(0)).to be(false) - expect(to_boolean('oFF')).to be(false) - end - - it 'converts an invalid value to nil' do - expect(to_boolean('fals')).to be_nil - expect(to_boolean('yeah')).to be_nil - expect(to_boolean('')).to be_nil - expect(to_boolean(nil)).to be_nil - end - - it 'accepts a default value, and does not return it when a valid value is given' do - expect(to_boolean(true, default: false)).to be(true) - expect(to_boolean('true', default: false)).to be(true) - expect(to_boolean('YeS', default: false)).to be(true) - expect(to_boolean('t', default: false)).to be(true) - expect(to_boolean('1', default: 'any value')).to be(true) - expect(to_boolean('ON', default: 42)).to be(true) - - expect(to_boolean('FaLse', default: true)).to be(false) - expect(to_boolean('F', default: true)).to be(false) - expect(to_boolean('NO', default: true)).to be(false) - expect(to_boolean('n', default: true)).to be(false) - expect(to_boolean('0', default: 'any value')).to be(false) - expect(to_boolean('oFF', default: 42)).to be(false) - end - - it 'accepts a default value, and returns it when an invalid value is given' do - expect(to_boolean('fals', default: true)).to eq(true) - expect(to_boolean('yeah', default: false)).to eq(false) - expect(to_boolean('', default: 'any value')).to eq('any value') - expect(to_boolean(nil, default: 42)).to eq(42) - end - end - - describe '.boolean_to_yes_no' do - it 'converts booleans to Yes or No' do - expect(boolean_to_yes_no(true)).to eq('Yes') - expect(boolean_to_yes_no(false)).to eq('No') - end - end - - describe '.which' do - before do - stub_env('PATH', '/sbin:/usr/bin:/home/joe/bin') - end - - it 'finds the full path to an executable binary in order of appearance' do - expect(File).to receive(:executable?).with('/sbin/tool').ordered.and_return(false) - expect(File).to receive(:executable?).with('/usr/bin/tool').ordered.and_return(true) - expect(File).not_to receive(:executable?).with('/home/joe/bin/tool') - - expect(which('tool')).to eq('/usr/bin/tool') - end - end - - describe '.ensure_array_from_string' do - it 'returns the same array if given one' do - arr = ['a', 4, true, { test: 1 }] - - expect(ensure_array_from_string(arr)).to eq(arr) - end - - it 'turns comma-separated strings into arrays' do - str = 'seven, eight, 9, 10' - - expect(ensure_array_from_string(str)).to eq(%w[seven eight 9 10]) - end - end - - describe '.bytes_to_megabytes' do - it 'converts bytes to megabytes' do - bytes = 1.megabyte - - expect(bytes_to_megabytes(bytes)).to eq(1) - end - end - - describe '.append_path' do - where(:host, :path, :result) do - 'http://test/' | '/foo/bar' | 'http://test/foo/bar' - 'http://test/' | '//foo/bar' | 'http://test/foo/bar' - 'http://test//' | '/foo/bar' | 'http://test/foo/bar' - 'http://test' | 'foo/bar' | 'http://test/foo/bar' - 'http://test//' | '' | 'http://test/' - 'http://test//' | nil | 'http://test/' - '' | '/foo/bar' | '/foo/bar' - nil | '/foo/bar' | '/foo/bar' - end - - with_them do - it 'makes sure there is only one slash as path separator' do - expect(append_path(host, path)).to eq(result) - end - end - end - - describe '.remove_leading_slashes' do - where(:str, :result) do - '/foo/bar' | 'foo/bar' - '//foo/bar' | 'foo/bar' - '/foo/bar/' | 'foo/bar/' - 'foo/bar' | 'foo/bar' - '' | '' - nil | '' - end - - with_them do - it 'removes leading slashes' do - expect(remove_leading_slashes(str)).to eq(result) - end - end - end - - describe '.ensure_utf8_size' do - context 'string is has less bytes than expected' do - it 'backfills string with null characters' do - transformed = described_class.ensure_utf8_size('a' * 10, bytes: 32) - - expect(transformed.bytesize).to eq 32 - expect(transformed).to eq(('a' * 10) + ('0' * 22)) - end - end - - context 'string size is exactly the one that is expected' do - it 'returns original value' do - transformed = described_class.ensure_utf8_size('a' * 32, bytes: 32) - - expect(transformed).to eq 'a' * 32 - expect(transformed.bytesize).to eq 32 - end - end - - context 'when string contains a few multi-byte UTF characters' do - it 'backfills string with null characters' do - transformed = described_class.ensure_utf8_size('❤' * 6, bytes: 32) - - expect(transformed).to eq '❤❤❤❤❤❤' + ('0' * 14) - expect(transformed.bytesize).to eq 32 - end - end - - context 'when string has multiple multi-byte UTF chars exceeding 32 bytes' do - it 'truncates string to 32 characters and backfills it if needed' do - transformed = described_class.ensure_utf8_size('❤' * 18, bytes: 32) - - expect(transformed).to eq(('❤' * 10) + ('0' * 2)) - expect(transformed.bytesize).to eq 32 - end - end - end - - describe '.deep_indifferent_access' do - let(:hash) do - { "variables" => [{ "key" => "VAR1", "value" => "VALUE2" }] } - end - - subject { described_class.deep_indifferent_access(hash) } - - it 'allows to access hash keys with symbols' do - expect(subject[:variables]).to be_a(Array) - end - - it 'allows to access array keys with symbols' do - expect(subject[:variables].first[:key]).to eq('VAR1') - end - end - - describe '.deep_symbolized_access' do - let(:hash) do - { "variables" => [{ "key" => "VAR1", "value" => "VALUE2" }] } - end - - subject { described_class.deep_symbolized_access(hash) } - - it 'allows to access hash keys with symbols' do - expect(subject[:variables]).to be_a(Array) - end - - it 'allows to access array keys with symbols' do - expect(subject[:variables].first[:key]).to eq('VAR1') - end - end - - describe '.try_megabytes_to_bytes' do - context 'when the size can be converted to megabytes' do - it 'returns the size in megabytes' do - size = described_class.try_megabytes_to_bytes(1) - - expect(size).to eq(1.megabytes) - end - end - - context 'when the size can not be converted to megabytes' do - it 'returns the input size' do - size = described_class.try_megabytes_to_bytes('foo') - - expect(size).to eq('foo') - end - end - end - - describe '.string_to_ip_object' do - it 'returns nil when string is nil' do - expect(described_class.string_to_ip_object(nil)).to eq(nil) - end - - it 'returns nil when string is invalid IP' do - expect(described_class.string_to_ip_object('invalid ip')).to eq(nil) - expect(described_class.string_to_ip_object('')).to eq(nil) - end - - it 'returns IP object when string is valid IP' do - expect(described_class.string_to_ip_object('192.168.1.1')).to eq(IPAddr.new('192.168.1.1')) - expect(described_class.string_to_ip_object('::ffff:a9fe:a864')).to eq(IPAddr.new('::ffff:a9fe:a864')) - expect(described_class.string_to_ip_object('[::ffff:a9fe:a864]')).to eq(IPAddr.new('::ffff:a9fe:a864')) - expect(described_class.string_to_ip_object('127.0.0.0/28')).to eq(IPAddr.new('127.0.0.0/28')) - expect(described_class.string_to_ip_object('1:0:0:0:0:0:0:0/124')).to eq(IPAddr.new('1:0:0:0:0:0:0:0/124')) - end - end - - describe ".safe_downcase!" do - where(:str, :result) do - "test" | "test" - "Test" | "test" - "test" | "test" - "Test" | "test" - end - - with_them do - it "downcases the string" do - expect(described_class.safe_downcase!(str)).to eq(result) - end - end - end - - describe '.parse_url' do - it 'returns Addressable::URI object' do - expect(described_class.parse_url('http://gitlab.com')).to be_instance_of(Addressable::URI) - end - - it 'returns nil when URI cannot be parsed' do - expect(described_class.parse_url('://gitlab.com')).to be nil - end - - it 'returns nil with invalid parameter' do - expect(described_class.parse_url(1)).to be nil - end - end - - describe '.add_url_parameters' do - subject { described_class.add_url_parameters(url, params) } - - where(:url, :params, :expected_url) do - nil | nil | '' - nil | { b: 3, a: 2 } | '?a=2&b=3' - 'https://gitlab.com' | nil | 'https://gitlab.com' - 'https://gitlab.com' | { b: 3, a: 2 } | 'https://gitlab.com?a=2&b=3' - 'https://gitlab.com?a=1#foo' | { b: 3, 'a': 2 } | 'https://gitlab.com?a=2&b=3#foo' - 'https://gitlab.com?a=1#foo' | [[:b, 3], [:a, 2]] | 'https://gitlab.com?a=2&b=3#foo' - end - - with_them do - it { is_expected.to eq(expected_url) } - end - end - - describe '.removes_sensitive_data_from_url' do - it 'returns string object' do - expect(described_class.removes_sensitive_data_from_url('http://gitlab.com')).to be_instance_of(String) - end - - it 'returns nil when URI cannot be parsed' do - expect(described_class.removes_sensitive_data_from_url('://gitlab.com')).to be nil - end - - it 'returns nil with invalid parameter' do - expect(described_class.removes_sensitive_data_from_url(1)).to be nil - end - - it 'returns string with filtered access_token param' do - expect(described_class.removes_sensitive_data_from_url('http://gitlab.com/auth.html#access_token=secret_token')).to eq('http://gitlab.com/auth.html#access_token=filtered') - end - - it 'returns string with filtered access_token param but other params preserved' do - expect(described_class.removes_sensitive_data_from_url('http://gitlab.com/auth.html#access_token=secret_token&token_type=Bearer&state=test')) - .to include('&token_type=Bearer', '&state=test') - end - end - - describe 'multiple_key_invert' do - it 'invert keys with array values' do - hash = { - dast: [:vulnerabilities_count, :scanned_resources_count], - sast: [:vulnerabilities_count] - } - expect(described_class.multiple_key_invert(hash)).to eq({ - vulnerabilities_count: [:dast, :sast], - scanned_resources_count: [:dast] - }) - end - end - - describe '.stable_sort_by' do - subject(:sorted_list) { described_class.stable_sort_by(list) { |obj| obj[:priority] } } - - context 'when items have the same priority' do - let(:list) do - [ - { name: 'obj 1', priority: 1 }, - { name: 'obj 2', priority: 1 }, - { name: 'obj 3', priority: 1 } - ] - end - - it 'does not change order in cases of ties' do - expect(sorted_list).to eq(list) - end - end - - context 'when items have different priorities' do - let(:list) do - [ - { name: 'obj 1', priority: 2 }, - { name: 'obj 2', priority: 1 }, - { name: 'obj 3', priority: 3 } - ] - end - - it 'sorts items like the regular sort_by' do - expect(sorted_list).to eq( - [ - { name: 'obj 2', priority: 1 }, - { name: 'obj 1', priority: 2 }, - { name: 'obj 3', priority: 3 } - ]) - end - end - end - - describe '.valid_brackets?' do - where(:input, :allow_nested, :valid) do - 'no brackets' | true | true - 'no brackets' | false | true - 'user[avatar]' | true | true - 'user[avatar]' | false | true - 'user[avatar][friends]' | true | true - 'user[avatar][friends]' | false | true - 'user[avatar[image[url]]]' | true | true - 'user[avatar[image[url]]]' | false | false - 'user[avatar[]friends]' | true | true - 'user[avatar[]friends]' | false | false - 'user[avatar]]' | true | false - 'user[avatar]]' | false | false - 'user][avatar]]' | true | false - 'user][avatar]]' | false | false - 'user[avatar' | true | false - 'user[avatar' | false | false - end - - with_them do - it { expect(described_class.valid_brackets?(input, allow_nested: allow_nested)).to eq(valid) } - end - end -end diff --git a/spec/lib/gitlab/version_info_spec.rb b/spec/lib/gitlab/version_info_spec.rb deleted file mode 100644 index 99c7a762392..00000000000 --- a/spec/lib/gitlab/version_info_spec.rb +++ /dev/null @@ -1,193 +0,0 @@ -# frozen_string_literal: true - -require 'fast_spec_helper' - -RSpec.describe Gitlab::VersionInfo do - before do - @unknown = described_class.new - @v0_0_1 = described_class.new(0, 0, 1) - @v0_1_0 = described_class.new(0, 1, 0) - @v1_0_0 = described_class.new(1, 0, 0) - @v1_0_1 = described_class.new(1, 0, 1) - @v1_0_1_b1 = described_class.new(1, 0, 1, '-b1') - @v1_0_1_rc1 = described_class.new(1, 0, 1, '-rc1') - @v1_0_1_rc2 = described_class.new(1, 0, 1, '-rc2') - @v1_1_0 = described_class.new(1, 1, 0) - @v1_1_0_beta1 = described_class.new(1, 1, 0, '-beta1') - @v2_0_0 = described_class.new(2, 0, 0) - @v13_10_1_1574_89 = described_class.parse("v13.10.1~beta.1574.gf6ea9389", parse_suffix: true) - @v13_10_1_1575_89 = described_class.parse("v13.10.1~beta.1575.gf6ea9389", parse_suffix: true) - @v13_10_1_1575_90 = described_class.parse("v13.10.1~beta.1575.gf6ea9390", parse_suffix: true) - end - - describe '>' do - it { expect(@v2_0_0).to be > @v1_1_0 } - it { expect(@v1_1_0).to be > @v1_0_1 } - it { expect(@v1_0_1_b1).to be > @v1_0_0 } - it { expect(@v1_0_1_rc1).to be > @v1_0_0 } - it { expect(@v1_0_1_rc1).to be > @v1_0_1_b1 } - it { expect(@v1_0_1_rc2).to be > @v1_0_1_rc1 } - it { expect(@v1_0_1).to be > @v1_0_1_rc1 } - it { expect(@v1_0_1).to be > @v1_0_1_rc2 } - it { expect(@v1_0_1).to be > @v1_0_0 } - it { expect(@v1_0_0).to be > @v0_1_0 } - it { expect(@v1_1_0_beta1).to be > @v1_0_1_rc2 } - it { expect(@v1_1_0).to be > @v1_1_0_beta1 } - it { expect(@v0_1_0).to be > @v0_0_1 } - end - - describe '>=' do - it { expect(@v2_0_0).to be >= described_class.new(2, 0, 0) } - it { expect(@v2_0_0).to be >= @v1_1_0 } - it { expect(@v1_0_1_rc2).to be >= @v1_0_1_rc1 } - end - - describe '<' do - it { expect(@v0_0_1).to be < @v0_1_0 } - it { expect(@v0_1_0).to be < @v1_0_0 } - it { expect(@v1_0_0).to be < @v1_0_1 } - it { expect(@v1_0_1).to be < @v1_1_0 } - it { expect(@v1_0_0).to be < @v1_0_1_rc2 } - it { expect(@v1_0_1_rc1).to be < @v1_0_1 } - it { expect(@v1_0_1_rc1).to be < @v1_0_1_rc2 } - it { expect(@v1_0_1_rc2).to be < @v1_0_1 } - it { expect(@v1_1_0).to be < @v2_0_0 } - it { expect(@v13_10_1_1574_89).to be < @v13_10_1_1575_89 } - it { expect(@v13_10_1_1575_89).to be < @v13_10_1_1575_90 } - end - - describe '<=' do - it { expect(@v0_0_1).to be <= described_class.new(0, 0, 1) } - it { expect(@v0_0_1).to be <= @v0_1_0 } - it { expect(@v1_0_1_b1).to be <= @v1_0_1_rc1 } - it { expect(@v1_0_1_rc1).to be <= @v1_0_1_rc2 } - it { expect(@v1_1_0_beta1).to be <= @v1_1_0 } - end - - describe '==' do - it { expect(@v0_0_1).to eq(described_class.new(0, 0, 1)) } - it { expect(@v0_1_0).to eq(described_class.new(0, 1, 0)) } - it { expect(@v1_0_0).to eq(described_class.new(1, 0, 0)) } - it { expect(@v1_0_1_rc1).to eq(described_class.new(1, 0, 1, '-rc1')) } - end - - describe '!=' do - it { expect(@v0_0_1).not_to eq(@v0_1_0) } - it { expect(@v1_0_1_rc1).not_to eq(@v1_0_1_rc2) } - end - - describe '.unknown' do - it { expect(@unknown).not_to be @v0_0_1 } - it { expect(@unknown).not_to be described_class.new } - it { expect { @unknown > @v0_0_1 }.to raise_error(ArgumentError) } - it { expect { @unknown < @v0_0_1 }.to raise_error(ArgumentError) } - end - - describe '.parse' do - it { expect(described_class.parse(described_class.new(1, 0, 0))).to eq(@v1_0_0) } - it { expect(described_class.parse("1.0.0")).to eq(@v1_0_0) } - it { expect(described_class.parse("1.0.0.1")).to eq(@v1_0_0) } - it { expect(described_class.parse("1.0.0-ee")).to eq(@v1_0_0) } - it { expect(described_class.parse("1.0.0-rc1")).to eq(@v1_0_0) } - it { expect(described_class.parse("1.0.0-rc1-ee")).to eq(@v1_0_0) } - it { expect(described_class.parse("git 1.0.0b1")).to eq(@v1_0_0) } - it { expect(described_class.parse("git 1.0b1")).not_to be_valid } - it { expect(described_class.parse("1.1.#{'1' * described_class::MAX_VERSION_LENGTH}")).not_to be_valid } - it { expect(described_class.parse(nil)).not_to be_valid } - - context 'with parse_suffix: true' do - let(:versions) do - <<-VERSIONS.lines - 0.0.1 - 0.1.0 - 1.0.0 - 1.0.1-b1 - 1.0.1-rc1 - 1.0.1-rc2 - 1.0.1 - 1.1.0-beta1 - 1.1.0 - 2.0.0 - v13.10.0-pre - v13.10.0-rc1 - v13.10.0-rc2 - v13.10.0 - v13.10.1~beta.1574.gf6ea9389 - v13.10.1~beta.1575.gf6ea9389 - v13.10.1-rc1 - v13.10.1-rc2 - v13.10.1 - VERSIONS - end - - let(:parsed_versions) do - versions.map(&:strip).map { |version| described_class.parse(version, parse_suffix: true) } - end - - it 'versions are returned in a correct order' do - expect(parsed_versions.shuffle.sort).to eq(parsed_versions) - end - end - end - - describe '.to_s' do - it { expect(@v1_0_0.to_s).to eq("1.0.0") } - it { expect(@v1_0_1_rc1.to_s).to eq("1.0.1-rc1") } - it { expect(@unknown.to_s).to eq("Unknown") } - end - - describe '.to_json' do - let(:correct_version) do - "{\"major\":1,\"minor\":0,\"patch\":1}" - end - - let(:unknown_version) do - "{\"major\":0,\"minor\":0,\"patch\":0}" - end - - it { expect(@v1_0_1.to_json).to eq(correct_version) } - it { expect(@v1_0_1_rc2.to_json).to eq(correct_version) } - it { expect(@unknown.to_json).to eq(unknown_version) } - end - - describe '.hash' do - it { expect(described_class.parse("1.0.0").hash).to eq(@v1_0_0.hash) } - it { expect(described_class.parse("1.0.0.1").hash).to eq(@v1_0_0.hash) } - it { expect(described_class.parse("1.0.1b1").hash).to eq(@v1_0_1.hash) } - it { expect(described_class.parse("1.0.1-rc1", parse_suffix: true).hash).to eq(@v1_0_1_rc1.hash) } - end - - describe '.eql?' do - it { expect(described_class.parse("1.0.0").eql?(@v1_0_0)).to be_truthy } - it { expect(described_class.parse("1.0.0.1").eql?(@v1_0_0)).to be_truthy } - it { expect(@v1_0_1_rc1.eql?(@v1_0_1_rc1)).to be_truthy } - it { expect(@v1_0_1_rc1.eql?(@v1_0_1_rc2)).to be_falsey } - it { expect(@v1_0_1_rc1.eql?(@v1_0_1)).to be_falsey } - it { expect(@v1_0_1.eql?(@v1_0_0)).to be_falsey } - it { expect(@v1_1_0.eql?(@v1_0_0)).to be_falsey } - it { expect(@v1_0_0.eql?(@v1_0_0)).to be_truthy } - it { expect([@v1_0_0, @v1_1_0, @v1_0_0, @v1_0_1_rc1, @v1_0_1_rc1].uniq).to eq [@v1_0_0, @v1_1_0, @v1_0_1_rc1] } - end - - describe '.same_minor_version?' do - it { expect(@v0_1_0.same_minor_version?(@v0_0_1)).to be_falsey } - it { expect(@v1_0_1.same_minor_version?(@v1_0_0)).to be_truthy } - it { expect(@v1_0_1_rc1.same_minor_version?(@v1_0_0)).to be_truthy } - it { expect(@v1_0_0.same_minor_version?(@v1_0_1)).to be_truthy } - it { expect(@v1_1_0.same_minor_version?(@v1_0_0)).to be_falsey } - it { expect(@v2_0_0.same_minor_version?(@v1_0_0)).to be_falsey } - end - - describe '.without_patch' do - it { expect(@v0_1_0.without_patch).to eq(@v0_1_0) } - it { expect(@v1_0_0.without_patch).to eq(@v1_0_0) } - it { expect(@v1_0_1.without_patch).to eq(@v1_0_0) } - it { expect(@v1_0_1_rc1.without_patch).to eq(@v1_0_0) } - end - - describe 'MAX_VERSION_LENGTH' do - subject { described_class::MAX_VERSION_LENGTH } - - it { is_expected.to eq(128) } - end -end diff --git a/spec/simplecov_env.rb b/spec/simplecov_env.rb index bea312369f7..af722f45ae5 100644 --- a/spec/simplecov_env.rb +++ b/spec/simplecov_env.rb @@ -3,7 +3,7 @@ require 'simplecov' require 'simplecov-cobertura' require 'simplecov-lcov' -require_relative '../lib/gitlab/utils' +require 'gitlab/utils/all' module SimpleCovEnv extend self diff --git a/spec/support/ability_check.rb b/spec/support/ability_check.rb index 213944506bb..5b56b9925f6 100644 --- a/spec/support/ability_check.rb +++ b/spec/support/ability_check.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require 'gitlab/utils/strong_memoize' +require 'gitlab/utils/all' module Support module AbilityCheck diff --git a/spec/support/formatters/json_formatter.rb b/spec/support/formatters/json_formatter.rb index e9d65af710a..f477d5e9e6a 100644 --- a/spec/support/formatters/json_formatter.rb +++ b/spec/support/formatters/json_formatter.rb @@ -26,11 +26,15 @@ module Support hash[:exceptions] = exceptions.map do |exception| hash = { class: exception.class.name, - message: exception.message, - message_lines: strip_ansi_codes(notification.message_lines), - backtrace: notification.formatted_backtrace + message: exception.message } + hash[:backtrace] = notification.formatted_backtrace if notification.respond_to?(:backtrace) + + if notification.respond_to?(:message_lines) + hash[:message_lines] = strip_ansi_codes(notification.message_lines) + end + if loglinking hash.merge!( correlation_id: exception.message[match_data_after(loglinking::CORRELATION_ID_TITLE)], diff --git a/spec/support/helpers/gitaly_setup.rb b/spec/support/helpers/gitaly_setup.rb index 7db9e0aaf09..06390406efc 100644 --- a/spec/support/helpers/gitaly_setup.rb +++ b/spec/support/helpers/gitaly_setup.rb @@ -10,8 +10,7 @@ require 'securerandom' require 'socket' require 'logger' require 'fileutils' - -require_relative '../../../lib/gitlab/utils' +require 'gitlab/utils/all' module GitalySetup extend self diff --git a/spec/support/rspec.rb b/spec/support/rspec.rb index b34f8fe9a22..4479e679d67 100644 --- a/spec/support/rspec.rb +++ b/spec/support/rspec.rb @@ -8,6 +8,7 @@ require_relative "helpers/stub_object_storage" require_relative "helpers/fast_rails_root" require 'gitlab/rspec/all' +require 'gitlab/utils/all' RSpec::Expectations.configuration.on_potential_false_positives = :raise diff --git a/spec/support/shared_contexts/lib/gitlab/sidekiq_logging/structured_logger_shared_context.rb b/spec/support/shared_contexts/lib/gitlab/sidekiq_logging/structured_logger_shared_context.rb index 1b50ef3fcff..b3b376ff6fe 100644 --- a/spec/support/shared_contexts/lib/gitlab/sidekiq_logging/structured_logger_shared_context.rb +++ b/spec/support/shared_contexts/lib/gitlab/sidekiq_logging/structured_logger_shared_context.rb @@ -69,7 +69,8 @@ RSpec.shared_context 'structured_logger' do end_payload.merge( 'message' => 'TestWorker JID-da883554ee4fe414012f5f42: deferred: 0.0 sec', 'job_status' => 'deferred', - 'job_deferred_by' => :feature_flag + 'job_deferred_by' => :feature_flag, + 'deferred_count' => 1 ) end diff --git a/spec/support/shared_examples/controllers/uploads_actions_shared_examples.rb b/spec/support/shared_examples/controllers/uploads_actions_shared_examples.rb index 0792ac14e47..772e03950da 100644 --- a/spec/support/shared_examples/controllers/uploads_actions_shared_examples.rb +++ b/spec/support/shared_examples/controllers/uploads_actions_shared_examples.rb @@ -94,14 +94,6 @@ RSpec.shared_examples 'handle uploads' do expect(response).to have_gitlab_http_status(:not_found) end - - it 'is a working exploit without the validation' do - allow_any_instance_of(FileUploader).to receive(:secret) { secret } - - show_upload - - expect(response).to have_gitlab_http_status(:ok) - end end context 'when accessing a specific upload via different model' do |