diff options
Diffstat (limited to 'spec/models/concerns')
-rw-r--r-- | spec/models/concerns/as_cte_spec.rb | 40 | ||||
-rw-r--r-- | spec/models/concerns/cache_markdown_field_spec.rb | 10 | ||||
-rw-r--r-- | spec/models/concerns/ci/artifactable_spec.rb | 4 | ||||
-rw-r--r-- | spec/models/concerns/integrations/has_data_fields_spec.rb | 88 | ||||
-rw-r--r-- | spec/models/concerns/issuable_spec.rb | 8 | ||||
-rw-r--r-- | spec/models/concerns/limitable_spec.rb | 4 | ||||
-rw-r--r-- | spec/models/concerns/pg_full_text_searchable_spec.rb | 11 | ||||
-rw-r--r-- | spec/models/concerns/project_features_compatibility_spec.rb | 2 | ||||
-rw-r--r-- | spec/models/concerns/sensitive_serializable_hash_spec.rb | 26 |
9 files changed, 132 insertions, 61 deletions
diff --git a/spec/models/concerns/as_cte_spec.rb b/spec/models/concerns/as_cte_spec.rb new file mode 100644 index 00000000000..06d9650ec46 --- /dev/null +++ b/spec/models/concerns/as_cte_spec.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe AsCte do + let(:klass) do + Class.new(ApplicationRecord) do + include AsCte + + self.table_name = 'users' + end + end + + let(:query) { klass.where(id: [1, 2, 3]) } + let(:name) { :klass_cte } + + describe '.as_cte' do + subject { query.as_cte(name) } + + it { expect(subject).to be_a(Gitlab::SQL::CTE) } + it { expect(subject.query).to eq(query) } + it { expect(subject.table.name).to eq(name.to_s) } + + context 'with materialized parameter', if: Gitlab::Database::AsWithMaterialized.materialized_supported? do + subject { query.as_cte(name, materialized: materialized).to_arel.to_sql } + + context 'as true' do + let(:materialized) { true } + + it { expect(subject).to match /MATERIALIZE/ } + end + + context 'as false' do + let(:materialized) { false } + + it { expect(subject).not_to match /MATERIALIZE/ } + end + end + end +end diff --git a/spec/models/concerns/cache_markdown_field_spec.rb b/spec/models/concerns/cache_markdown_field_spec.rb index d46f22b2216..a00129b3fdf 100644 --- a/spec/models/concerns/cache_markdown_field_spec.rb +++ b/spec/models/concerns/cache_markdown_field_spec.rb @@ -404,6 +404,16 @@ RSpec.describe CacheMarkdownField, :clean_gitlab_redis_cache do it 'returns false when there are no changes' do expect(thing.attribute_invalidated?(:description_html)).to eq(false) end + + it 'returns false if skip_markdown_cache_validation is true' do + # invalidates the attribute + thing.cached_markdown_version += 1 + thing.description = updated_markdown + + thing.skip_markdown_cache_validation = true + + expect(thing.attribute_invalidated?(:description_html)).to eq(false) + end end context 'when cache version is updated' do diff --git a/spec/models/concerns/ci/artifactable_spec.rb b/spec/models/concerns/ci/artifactable_spec.rb index 62fc689a9ca..b27a4d0dcc1 100644 --- a/spec/models/concerns/ci/artifactable_spec.rb +++ b/spec/models/concerns/ci/artifactable_spec.rb @@ -68,8 +68,8 @@ RSpec.describe Ci::Artifactable do end describe '.expired' do - it 'returns a limited number of expired artifacts' do - expect(Ci::JobArtifact.expired(1).order_id_asc).to eq([recently_expired_artifact]) + it 'returns all expired artifacts' do + expect(Ci::JobArtifact.expired).to contain_exactly(recently_expired_artifact, later_expired_artifact) end end diff --git a/spec/models/concerns/integrations/has_data_fields_spec.rb b/spec/models/concerns/integrations/has_data_fields_spec.rb index b28fef571c6..374c5c33b50 100644 --- a/spec/models/concerns/integrations/has_data_fields_spec.rb +++ b/spec/models/concerns/integrations/has_data_fields_spec.rb @@ -6,84 +6,84 @@ RSpec.describe Integrations::HasDataFields do let(:url) { 'http://url.com' } let(:username) { 'username_one' } let(:properties) do - { url: url, username: username } + { url: url, username: username, jira_issue_transition_automatic: false } end shared_examples 'data fields' do describe '#arg' do - it 'returns an argument correctly' do - expect(service.url).to eq(url) + it 'returns the expected values' do + expect(integration).to have_attributes(properties) end end describe '{arg}_changed?' do it 'returns false when the property has not been assigned a new value' do - service.username = 'new_username' - service.validate - expect(service.url_changed?).to be_falsy + integration.username = 'new_username' + integration.validate + expect(integration.url_changed?).to be_falsy end it 'returns true when the property has been assigned a different value' do - service.url = "http://example.com" - service.validate - expect(service.url_changed?).to be_truthy + integration.url = "http://example.com" + integration.validate + expect(integration.url_changed?).to be_truthy end it 'returns true when the property has been assigned a different value twice' do - service.url = "http://example.com" - service.url = "http://example.com" - service.validate - expect(service.url_changed?).to be_truthy + integration.url = "http://example.com" + integration.url = "http://example.com" + integration.validate + expect(integration.url_changed?).to be_truthy end it 'returns false when the property has been re-assigned the same value' do - service.url = 'http://url.com' - service.validate - expect(service.url_changed?).to be_falsy + integration.url = 'http://url.com' + integration.validate + expect(integration.url_changed?).to be_falsy end end describe '{arg}_touched?' do it 'returns false when the property has not been assigned a new value' do - service.username = 'new_username' - service.validate - expect(service.url_changed?).to be_falsy + integration.username = 'new_username' + integration.validate + expect(integration.url_changed?).to be_falsy end it 'returns true when the property has been assigned a different value' do - service.url = "http://example.com" - service.validate - expect(service.url_changed?).to be_truthy + integration.url = "http://example.com" + integration.validate + expect(integration.url_changed?).to be_truthy end it 'returns true when the property has been assigned a different value twice' do - service.url = "http://example.com" - service.url = "http://example.com" - service.validate - expect(service.url_changed?).to be_truthy + integration.url = "http://example.com" + integration.url = "http://example.com" + integration.validate + expect(integration.url_changed?).to be_truthy end it 'returns true when the property has been re-assigned the same value' do - service.url = 'http://url.com' - expect(service.url_touched?).to be_truthy + integration.url = 'http://url.com' + expect(integration.url_touched?).to be_truthy end it 'returns false when the property has been re-assigned the same value' do - service.url = 'http://url.com' - service.validate - expect(service.url_changed?).to be_falsy + integration.url = 'http://url.com' + integration.validate + expect(integration.url_changed?).to be_falsy end end describe 'data_fields_present?' do - it 'returns true from the issue tracker service' do - expect(service.data_fields_present?).to be true + it 'returns true from the issue tracker integration' do + expect(integration.data_fields_present?).to be true end end end context 'when data are stored in data_fields' do - let(:service) do + let(:integration) do create(:jira_integration, url: url, username: username) end @@ -91,21 +91,21 @@ RSpec.describe Integrations::HasDataFields do describe '{arg}_was?' do it 'returns nil' do - service.url = 'http://example.com' - service.validate - expect(service.url_was).to be_nil + integration.url = 'http://example.com' + integration.validate + expect(integration.url_was).to be_nil end end end - context 'when service and data_fields are not persisted' do - let(:service) do + context 'when integration and data_fields are not persisted' do + let(:integration) do Integrations::Jira.new end describe 'data_fields_present?' do it 'returns true' do - expect(service.data_fields_present?).to be true + expect(integration.data_fields_present?).to be true end end end @@ -113,9 +113,7 @@ RSpec.describe Integrations::HasDataFields do context 'when data are stored in properties' do let(:integration) { create(:jira_integration, :without_properties_callback, properties: properties) } - it_behaves_like 'data fields' do - let(:service) { integration } - end + it_behaves_like 'data fields' describe '{arg}_was?' do it 'returns nil when the property has not been assigned a new value' do @@ -148,9 +146,7 @@ RSpec.describe Integrations::HasDataFields do end end - it_behaves_like 'data fields' do - let(:service) { integration } - end + it_behaves_like 'data fields' describe '{arg}_was?' do it 'returns nil' do diff --git a/spec/models/concerns/issuable_spec.rb b/spec/models/concerns/issuable_spec.rb index e8e9c263d23..87821de3cf5 100644 --- a/spec/models/concerns/issuable_spec.rb +++ b/spec/models/concerns/issuable_spec.rb @@ -982,14 +982,6 @@ RSpec.describe Issuable do subject { issuable.supports_escalation? } it { is_expected.to eq(supports_escalation) } - - context 'with feature disabled' do - before do - stub_feature_flags(incident_escalations: false) - end - - it { is_expected.to eq(false) } - end end end diff --git a/spec/models/concerns/limitable_spec.rb b/spec/models/concerns/limitable_spec.rb index 850282d54c7..c0a6aea2075 100644 --- a/spec/models/concerns/limitable_spec.rb +++ b/spec/models/concerns/limitable_spec.rb @@ -31,7 +31,7 @@ RSpec.describe Limitable do it 'triggers scoped validations' do instance = MinimalTestClass.new - expect(instance).to receive(:validate_scoped_plan_limit_not_exceeded) + expect(instance).to receive(:scoped_plan_limits) instance.valid?(:create) end @@ -94,7 +94,7 @@ RSpec.describe Limitable do it 'triggers scoped validations' do instance = MinimalTestClass.new - expect(instance).to receive(:validate_global_plan_limit_not_exceeded) + expect(instance).to receive(:global_plan_limits) instance.valid?(:create) end diff --git a/spec/models/concerns/pg_full_text_searchable_spec.rb b/spec/models/concerns/pg_full_text_searchable_spec.rb index b6da481024a..84209999ab2 100644 --- a/spec/models/concerns/pg_full_text_searchable_spec.rb +++ b/spec/models/concerns/pg_full_text_searchable_spec.rb @@ -99,6 +99,17 @@ RSpec.describe PgFullTextSearchable do it 'does not support searching by non-Latin characters' do expect(model_class.pg_full_text_search('日本')).to be_empty end + + context 'when search term has a URL' do + let(:with_url) { model_class.create!(project: project, title: 'issue with url', description: 'sample url,https://gitlab.com/gitlab-org/gitlab') } + + it 'allows searching by full URL, ignoring the scheme' do + with_url.update_search_data! + + expect(model_class.pg_full_text_search('https://gitlab.com/gitlab-org/gitlab')).to contain_exactly(with_url) + expect(model_class.pg_full_text_search('gopher://gitlab.com/gitlab-org/gitlab')).to contain_exactly(with_url) + end + end end describe '#update_search_data!' do diff --git a/spec/models/concerns/project_features_compatibility_spec.rb b/spec/models/concerns/project_features_compatibility_spec.rb index 62c9a041a85..f2dc8464e86 100644 --- a/spec/models/concerns/project_features_compatibility_spec.rb +++ b/spec/models/concerns/project_features_compatibility_spec.rb @@ -5,7 +5,7 @@ require 'spec_helper' RSpec.describe ProjectFeaturesCompatibility do let(:project) { create(:project) } let(:features_enabled) { %w(issues wiki builds merge_requests snippets security_and_compliance) } - let(:features) { features_enabled + %w(repository pages operations container_registry) } + let(:features) { features_enabled + %w(repository pages operations container_registry package_registry) } # We had issues_enabled, snippets_enabled, builds_enabled, merge_requests_enabled and issues_enabled fields on projects table # All those fields got moved to a new table called project_feature and are now integers instead of booleans diff --git a/spec/models/concerns/sensitive_serializable_hash_spec.rb b/spec/models/concerns/sensitive_serializable_hash_spec.rb index c864ecb4eec..3c9199ce18f 100644 --- a/spec/models/concerns/sensitive_serializable_hash_spec.rb +++ b/spec/models/concerns/sensitive_serializable_hash_spec.rb @@ -4,11 +4,15 @@ require 'spec_helper' RSpec.describe SensitiveSerializableHash do describe '.prevent_from_serialization' do - let(:test_class) do + let(:base_class) do Class.new do include ActiveModel::Serialization include SensitiveSerializableHash + end + end + let(:test_class) do + Class.new(base_class) do attr_accessor :name, :super_secret prevent_from_serialization :super_secret @@ -19,6 +23,12 @@ RSpec.describe SensitiveSerializableHash do end end + let(:another_class) do + Class.new(base_class) do + prevent_from_serialization :sub_secret + end + end + let(:model) { test_class.new } it 'does not include the field in serializable_hash' do @@ -30,6 +40,11 @@ RSpec.describe SensitiveSerializableHash do expect(model.serializable_hash(unsafe_serialization_hash: true)).to include('super_secret') end end + + it 'does not change parent class attributes_exempt_from_serializable_hash' do + expect(test_class.attributes_exempt_from_serializable_hash).to contain_exactly(:super_secret) + expect(another_class.attributes_exempt_from_serializable_hash).to contain_exactly(:sub_secret) + end end describe '#serializable_hash' do @@ -56,6 +71,9 @@ RSpec.describe SensitiveSerializableHash do attributes.each do |attribute| expect(model.attributes).to include(attribute) # double-check the attribute does exist + # Do not expect binary columns to appear in JSON + next if klass.columns_hash[attribute]&.type == :binary + expect(model.serializable_hash(unsafe_serialization_hash: true)).to include(attribute) expect(model.to_json(unsafe_serialization_hash: true)).to include(attribute) expect(model.as_json(unsafe_serialization_hash: true)).to include(attribute) @@ -65,8 +83,12 @@ RSpec.describe SensitiveSerializableHash do end end - it_behaves_like 'attr_encrypted attribute', WebHook, 'token' do + context 'for a web hook' do let_it_be(:model) { create(:system_hook) } + + it_behaves_like 'attr_encrypted attribute', WebHook, 'token' + it_behaves_like 'attr_encrypted attribute', WebHook, 'url' + it_behaves_like 'attr_encrypted attribute', WebHook, 'url_variables' end it_behaves_like 'attr_encrypted attribute', Ci::InstanceVariable, 'value' do |