diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-01-30 12:12:53 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-01-30 12:12:53 +0300 |
commit | e8c894d0365414bab8a322c614690cae7d29949a (patch) | |
tree | eb02b9a80940b6712a4db0b8d889c5030e2e6c22 /spec/support/shared_examples | |
parent | 76bace8cdfcc8dfb033f534094d376b9d3b2c849 (diff) |
Add latest changes from gitlab-org/security/gitlab@15-7-stable-ee
Diffstat (limited to 'spec/support/shared_examples')
-rw-r--r-- | spec/support/shared_examples/models/concerns/issuable_shared_examples.rb | 103 | ||||
-rw-r--r-- | spec/support/shared_examples/models/concerns/sanitizable_shared_examples.rb | 19 |
2 files changed, 105 insertions, 17 deletions
diff --git a/spec/support/shared_examples/models/concerns/issuable_shared_examples.rb b/spec/support/shared_examples/models/concerns/issuable_shared_examples.rb index 3a407088997..f49ec906382 100644 --- a/spec/support/shared_examples/models/concerns/issuable_shared_examples.rb +++ b/spec/support/shared_examples/models/concerns/issuable_shared_examples.rb @@ -10,40 +10,111 @@ RSpec.shared_examples 'matches_cross_reference_regex? fails fast' do end RSpec.shared_examples 'validates description length with custom validation' do - let(:issuable) { build(:issue, description: 'x' * (::Issuable::DESCRIPTION_LENGTH_MAX + 1)) } - let(:context) { :update } + let(:invalid_description) { 'x' * (::Issuable::DESCRIPTION_LENGTH_MAX + 1) } + let(:valid_description) { 'short description' } + let(:issuable) { build(:issue, description: description) } + + let(:error_message) do + format( + _('is too long (%{size}). The maximum size is %{max_size}.'), + size: ActiveSupport::NumberHelper.number_to_human_size(invalid_description.bytesize), + max_size: ActiveSupport::NumberHelper.number_to_human_size(::Issuable::DESCRIPTION_LENGTH_MAX) + ) + end - subject { issuable.validate(context) } + subject(:validate) { issuable.validate(context) } context 'when Issuable is a new record' do - it 'validates the maximum description length' do - subject - expect(issuable.errors[:description]).to eq(["is too long (maximum is #{::Issuable::DESCRIPTION_LENGTH_MAX} characters)"]) - end + let(:context) { :create } + + context 'when description exceeds the maximum size' do + let(:description) { invalid_description } - context 'on create' do - let(:context) { :create } + it 'adds a description too long error' do + validate - it 'does not validate the maximum description length' do - allow(issuable).to receive(:description_max_length_for_new_records_is_valid).and_call_original + expect(issuable.errors[:description]).to contain_exactly(error_message) + end + end - subject + context 'when description is within the allowed limits' do + let(:description) { valid_description } - expect(issuable).not_to have_received(:description_max_length_for_new_records_is_valid) + it 'does not add a validation error' do + validate + + expect(issuable.errors).not_to have_key(:description) end end end context 'when Issuable is an existing record' do + let(:context) { :update } + before do allow(issuable).to receive(:expire_etag_cache) # to skip the expire_etag_cache callback + issuable.description = existing_description issuable.save!(validate: false) + issuable.description = description + end + + context 'when record already had a valid description' do + let(:existing_description) { 'small difference so it triggers description_changed?' } + + context 'when new description exceeds the maximum size' do + let(:description) { invalid_description } + + it 'adds a description too long error' do + validate + + expect(issuable.errors[:description]).to contain_exactly(error_message) + end + end + + context 'when new description is within the allowed limits' do + let(:description) { valid_description } + + it 'does not add a validation error' do + validate + + expect(issuable.errors).not_to have_key(:description) + end + end end - it 'does not validate the maximum description length' do - subject - expect(issuable.errors).not_to have_key(:description) + context 'when record existed with an invalid description' do + let(:existing_description) { "#{invalid_description} small difference so it triggers description_changed?" } + + context 'when description is not changed' do + let(:description) { existing_description } + + it 'does not add a validation error' do + validate + + expect(issuable.errors).not_to have_key(:description) + end + end + + context 'when new description exceeds the maximum size' do + let(:description) { invalid_description } + + it 'allows updating descriptions that already existed above the limit' do + validate + + expect(issuable.errors).not_to have_key(:description) + end + end + + context 'when new description is within the allowed limits' do + let(:description) { valid_description } + + it 'does not add a validation error' do + validate + + expect(issuable.errors).not_to have_key(:description) + end + end end end end diff --git a/spec/support/shared_examples/models/concerns/sanitizable_shared_examples.rb b/spec/support/shared_examples/models/concerns/sanitizable_shared_examples.rb index aedbfe4deb3..9bfa4ace05c 100644 --- a/spec/support/shared_examples/models/concerns/sanitizable_shared_examples.rb +++ b/spec/support/shared_examples/models/concerns/sanitizable_shared_examples.rb @@ -32,8 +32,25 @@ RSpec.shared_examples 'sanitizable' do |factory, fields| subject { build(factory, attributes) } it 'is not valid', :aggregate_failures do + error = 'cannot contain escaped HTML entities' + + expect(subject).not_to be_valid + expect(subject.errors.details[field].flat_map(&:values)).to contain_exactly(error) + end + end + + context 'when it contains a path component' do + let_it_be(:input) do + 'main../../../../../../api/v4/projects/1/import_project_members/2' + end + + subject { build(factory, attributes) } + + it 'is not valid', :aggregate_failures do + error = 'cannot contain a path traversal component' + expect(subject).not_to be_valid - expect(subject.errors.details[field].flat_map(&:values)).to include('cannot contain escaped HTML entities') + expect(subject.errors.details[field].flat_map(&:values)).to contain_exactly(error) end end end |