diff options
Diffstat (limited to 'spec/support_specs')
-rw-r--r-- | spec/support_specs/capybara_slow_finder_spec.rb | 78 | ||||
-rw-r--r-- | spec/support_specs/database/multiple_databases_spec.rb | 22 | ||||
-rw-r--r-- | spec/support_specs/helpers/graphql_helpers_spec.rb | 35 | ||||
-rw-r--r-- | spec/support_specs/helpers/html_escaped_helpers_spec.rb | 29 | ||||
-rw-r--r-- | spec/support_specs/helpers/stub_method_calls_spec.rb | 4 | ||||
-rw-r--r-- | spec/support_specs/matchers/event_store_spec.rb | 126 |
6 files changed, 293 insertions, 1 deletions
diff --git a/spec/support_specs/capybara_slow_finder_spec.rb b/spec/support_specs/capybara_slow_finder_spec.rb new file mode 100644 index 00000000000..b0438a7a78b --- /dev/null +++ b/spec/support_specs/capybara_slow_finder_spec.rb @@ -0,0 +1,78 @@ +# frozen_string_literal: true + +require 'fast_spec_helper' +require 'capybara' +require 'support/capybara_slow_finder' + +RSpec.describe Capybara::Node::Base::SlowFinder do # rubocop:disable RSpec/FilePath + context 'without timeout' do + context 'when element is found' do + let(:slow_finder) do + Class.new do + def synchronize(seconds = nil, errors: nil) + true + end + + prepend Capybara::Node::Base::SlowFinder + end.new + end + + it 'does not raise error' do + expect { slow_finder.synchronize }.not_to raise_error + end + end + + context 'when element is not found' do + let(:slow_finder) do + Class.new do + def synchronize(seconds = nil, errors: nil) + raise Capybara::ElementNotFound + end + + prepend Capybara::Node::Base::SlowFinder + end.new + end + + it 'raises Capybara::ElementNotFound error' do + expect { slow_finder.synchronize }.to raise_error(Capybara::ElementNotFound) + end + end + end + + context 'with timeout' do + let(:timeout) { 0.01 } + + let(:slow_finder) do + Class.new do + def synchronize(seconds = nil, errors: nil) + sleep 0.02 + + raise Capybara::ElementNotFound + end + + prepend Capybara::Node::Base::SlowFinder + end.new + end + + context 'with default timeout' do + it 'raises a timeout error' do + expect(Capybara).to receive(:default_max_wait_time).and_return(timeout) + + expect { slow_finder.synchronize }.to raise_error_element_not_found + end + end + + context 'when passed as paramater' do + it 'raises a timeout error' do + expect { slow_finder.synchronize(timeout) }.to raise_error_element_not_found + end + end + + def raise_error_element_not_found + raise_error( + Capybara::ElementNotFound, + /\n\nTimeout \(#{timeout}s\) reached while running a waiting Capybara finder./ + ) + end + end +end diff --git a/spec/support_specs/database/multiple_databases_spec.rb b/spec/support_specs/database/multiple_databases_spec.rb index b4cfa253813..0b019462077 100644 --- a/spec/support_specs/database/multiple_databases_spec.rb +++ b/spec/support_specs/database/multiple_databases_spec.rb @@ -3,6 +3,28 @@ require 'spec_helper' RSpec.describe 'Database::MultipleDatabases' do + let(:query) do + <<~SQL + WITH cte AS #{Gitlab::Database::AsWithMaterialized.materialized_if_supported} (SELECT 1) SELECT 1; + SQL + end + + it 'preloads database version for ApplicationRecord' do + counts = ActiveRecord::QueryRecorder + .new { ApplicationRecord.connection.execute(query) } + .count + + expect(counts).to eq(1) + end + + it 'preloads database version for Ci::ApplicationRecord' do + counts = ActiveRecord::QueryRecorder + .new { Ci::ApplicationRecord.connection.execute(query) } + .count + + expect(counts).to eq(1) + end + describe '.with_reestablished_active_record_base' do context 'when doing establish_connection' do context 'on ActiveRecord::Base' do diff --git a/spec/support_specs/helpers/graphql_helpers_spec.rb b/spec/support_specs/helpers/graphql_helpers_spec.rb index c02e4adf983..12a6e561257 100644 --- a/spec/support_specs/helpers/graphql_helpers_spec.rb +++ b/spec/support_specs/helpers/graphql_helpers_spec.rb @@ -133,6 +133,23 @@ RSpec.describe GraphqlHelpers do expect(graphql_dig_at(data, :foo, :nodes, :bar, :nodes, :id)).to eq([nil, 2, 3, nil]) end + + it 'supports fields with leading underscore' do + web_path = '/namespace1/project1/-/packages/997' + data = { + 'packages' => { + 'nodes' => [ + { + '_links' => { + 'webPath' => web_path + } + } + ] + } + } + + expect(graphql_dig_at(data, :packages, :nodes, :_links, :web_path)).to match_array([web_path]) + end end describe 'var' do @@ -417,4 +434,22 @@ RSpec.describe GraphqlHelpers do end end end + + describe '.fieldnamerize' do + subject { described_class.fieldnamerize(field) } + + let(:field) { 'merge_request' } + + it 'makes an underscored string look like a fieldname' do + is_expected.to eq('mergeRequest') + end + + context 'when field has a leading underscore' do + let(:field) { :_links } + + it 'skips a transformation' do + is_expected.to eq('_links') + end + end + end end diff --git a/spec/support_specs/helpers/html_escaped_helpers_spec.rb b/spec/support_specs/helpers/html_escaped_helpers_spec.rb index 337f7ecc659..77ca6231881 100644 --- a/spec/support_specs/helpers/html_escaped_helpers_spec.rb +++ b/spec/support_specs/helpers/html_escaped_helpers_spec.rb @@ -40,4 +40,33 @@ RSpec.describe HtmlEscapedHelpers do specify { expect(actual_match).to eq(expected_match) } end end + + describe '#ensure_no_html_escaped_tags!' do + subject { |example| described_class.ensure_no_html_escaped_tags!(content, example) } + + context 'when content contains HTML escaped chars' do + let(:content) { 'See <a href="">Link</a>' } + + it 'raises an exception' do + parts = [ + 'The following string contains HTML escaped tags:', + 'See «<a» href="">Link</a>', + 'This check can be disabled via:', + %(it "raises an exception", :skip_html_escaped_tags_check do) + ] + + regexp = Regexp.new(parts.join('.*'), Regexp::MULTILINE) + + expect { subject }.to raise_error(regexp) + end + end + + context 'when content does not contain HTML escaped tags' do + let(:content) { 'See <a href="">Link</a>' } + + it 'does not raise anything' do + expect(subject).to be_nil + end + end + end end diff --git a/spec/support_specs/helpers/stub_method_calls_spec.rb b/spec/support_specs/helpers/stub_method_calls_spec.rb index 837a2162bcd..7a842f83cd2 100644 --- a/spec/support_specs/helpers/stub_method_calls_spec.rb +++ b/spec/support_specs/helpers/stub_method_calls_spec.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true -require 'spec_helper' +require 'fast_spec_helper' + +require_relative '../../support/helpers/stub_method_calls' RSpec.describe StubMethodCalls do include described_class diff --git a/spec/support_specs/matchers/event_store_spec.rb b/spec/support_specs/matchers/event_store_spec.rb new file mode 100644 index 00000000000..3614d05fde8 --- /dev/null +++ b/spec/support_specs/matchers/event_store_spec.rb @@ -0,0 +1,126 @@ +# frozen_string_literal: true + +require 'fast_spec_helper' +require 'json_schemer' + +load File.expand_path('../../../spec/support/matchers/event_store.rb', __dir__) + +RSpec.describe 'event store matchers', :aggregate_errors do + let(:event_type1) do + Class.new(Gitlab::EventStore::Event) do + def schema + { + 'type' => 'object', + 'properties' => { + 'id' => { 'type' => 'integer' } + }, + 'required' => %w[id] + } + end + end + end + + let(:event_type2) do + Class.new(Gitlab::EventStore::Event) do + def schema + { + 'type' => 'object', + 'properties' => { + 'id' => { 'type' => 'integer' } + }, + 'required' => %w[id] + } + end + end + end + + before do + stub_const('FakeEventType1', event_type1) + stub_const('FakeEventType2', event_type2) + end + + def publishing_event(event_type, data = {}) + ::Gitlab::EventStore.publish(event_type.new(data: data)) + end + + describe 'publish_event' do + it 'requires a block matcher' do + matcher = -> { expect(:anything).to publish_event(:anything) } # rubocop: disable RSpec/ExpectActual + + expect(&matcher).to raise_error( + ArgumentError, + 'publish_event matcher only supports block expectation' + ) + end + + it 'validates the event type' do + valid_event_type = -> do + expect { publishing_event(FakeEventType1, { 'id' => 1 }) } + .to publish_event(FakeEventType1).with('id' => 1) + end + + expect(&valid_event_type).not_to raise_error + + invalid_event_type = -> do + expect { publishing_event(FakeEventType1, { 'id' => 1 }) } + .to publish_event(FakeEventType2).with('id' => 1) + end + + expect(&invalid_event_type).to raise_error <<~MESSAGE + expected FakeEventType2 with {"id"=>1} to be published, but only the following events were published: + - FakeEventType1 with {"id"=>1} + MESSAGE + end + + it 'validates the event data' do + missing_data = -> do + expect { publishing_event(FakeEventType1, { 'id' => 1 }) } + .to publish_event(FakeEventType1) + end + + expect(&missing_data).to raise_error <<~MESSAGE + expected FakeEventType1 with no data to be published, but only the following events were published: + - FakeEventType1 with {"id"=>1} + MESSAGE + + different_data = -> do + expect { publishing_event(FakeEventType1, { 'id' => 1 }) } + .to publish_event(FakeEventType1).with({ 'id' => 2 }) + end + + expect(&different_data).to raise_error <<~MESSAGE + expected FakeEventType1 with {"id"=>2} to be published, but only the following events were published: + - FakeEventType1 with {"id"=>1} + MESSAGE + end + end + + describe 'not_publish_event' do + it 'requires a block matcher' do + matcher = -> { expect(:anything).to not_publish_event(:anything) } # rubocop: disable RSpec/ExpectActual + + expect(&matcher) + .to raise_error(ArgumentError, 'not_publish_event matcher only supports block expectation') + end + + it 'does not permit .with' do + matcher = -> do + expect { publishing_event(FakeEventType1, { 'id' => 1 }) } + .to not_publish_event(FakeEventType2).with({ 'id' => 1 }) + end + + expect(&matcher) + .to raise_error(ArgumentError, 'not_publish_event does not permit .with to avoid ambiguity') + end + + it 'validates the event type' do + matcher = -> do + expect { publishing_event(FakeEventType1, { 'id' => 1 }) } + .to not_publish_event(FakeEventType1) + end + + expect(&matcher) + .to raise_error('expected FakeEventType1 not to be published') + end + end +end |