diff options
Diffstat (limited to 'spec')
-rw-r--r-- | spec/frontend/snippets/components/show_spec.js | 19 | ||||
-rw-r--r-- | spec/graphql/resolvers/snippets/blobs_resolver_spec.rb | 13 | ||||
-rw-r--r-- | spec/lib/gitlab/email/hook/validate_addresses_interceptor_spec.rb | 52 | ||||
-rw-r--r-- | spec/models/snippet_spec.rb | 34 |
4 files changed, 115 insertions, 3 deletions
diff --git a/spec/frontend/snippets/components/show_spec.js b/spec/frontend/snippets/components/show_spec.js index af61f4ea54f..c73bf8f80a2 100644 --- a/spec/frontend/snippets/components/show_spec.js +++ b/spec/frontend/snippets/components/show_spec.js @@ -1,4 +1,4 @@ -import { GlLoadingIcon } from '@gitlab/ui'; +import { GlLoadingIcon, GlAlert } from '@gitlab/ui'; import { shallowMount } from '@vue/test-utils'; import { Blob, BinaryBlob } from 'jest/blob/components/mock_data'; import EmbedDropdown from '~/snippets/components/embed_dropdown.vue'; @@ -106,6 +106,23 @@ describe('Snippet view app', () => { }); }); + describe('hasUnretrievableBlobs alert rendering', () => { + it.each` + hasUnretrievableBlobs | condition | isRendered + ${false} | ${'not render'} | ${false} + ${true} | ${'render'} | ${true} + `('does $condition gl-alert by default', ({ hasUnretrievableBlobs, isRendered }) => { + createComponent({ + data: { + snippet: { + hasUnretrievableBlobs, + }, + }, + }); + expect(wrapper.findComponent(GlAlert).exists()).toBe(isRendered); + }); + }); + describe('Clone button rendering', () => { it.each` httpUrlToRepo | sshUrlToRepo | shouldRender | isRendered diff --git a/spec/graphql/resolvers/snippets/blobs_resolver_spec.rb b/spec/graphql/resolvers/snippets/blobs_resolver_spec.rb index ebe286769cf..b5db7ac5748 100644 --- a/spec/graphql/resolvers/snippets/blobs_resolver_spec.rb +++ b/spec/graphql/resolvers/snippets/blobs_resolver_spec.rb @@ -13,11 +13,14 @@ RSpec.describe Resolvers::Snippets::BlobsResolver do let_it_be(:current_user) { create(:user) } let_it_be(:snippet) { create(:personal_snippet, :private, :repository, author: current_user) } + let(:query_context) { {} } + context 'when user is not authorized' do let(:other_user) { create(:user) } it 'redacts the field' do expect(resolve_blobs(snippet, user: other_user)).to be_nil + expect(query_context[:unretrievable_blobs?]).to eq(false) end end @@ -28,6 +31,7 @@ RSpec.describe Resolvers::Snippets::BlobsResolver do expect(result).to match_array(snippet.list_files.map do |file| have_attributes(path: file) end) + expect(query_context[:unretrievable_blobs?]).to eq(false) end end @@ -37,12 +41,14 @@ RSpec.describe Resolvers::Snippets::BlobsResolver do path = 'CHANGELOG' expect(resolve_blobs(snippet, paths: [path])).to contain_exactly(have_attributes(path: path)) + expect(query_context[:unretrievable_blobs?]).to eq(false) end end context 'the argument does not match anything' do it 'returns an empty result' do expect(resolve_blobs(snippet, paths: ['does not exist'])).to be_empty + expect(query_context[:unretrievable_blobs?]).to eq(true) end end @@ -53,12 +59,15 @@ RSpec.describe Resolvers::Snippets::BlobsResolver do expect(resolve_blobs(snippet, paths: paths)).to match_array(paths.map do |file| have_attributes(path: file) end) + expect(query_context[:unretrievable_blobs?]).to eq(false) end end end end - def resolve_blobs(snippet, user: current_user, paths: [], args: { paths: paths }) - resolve(described_class, args: args, ctx: { current_user: user }, obj: snippet) + def resolve_blobs(snippet, user: current_user, paths: [], args: { paths: paths }, has_unretrievable_blobs: false) + query_context[:current_user] = user + query_context[:unretrievable_blobs?] = has_unretrievable_blobs + resolve(described_class, args: args, ctx: query_context, obj: snippet) end end diff --git a/spec/lib/gitlab/email/hook/validate_addresses_interceptor_spec.rb b/spec/lib/gitlab/email/hook/validate_addresses_interceptor_spec.rb new file mode 100644 index 00000000000..a3f0158db40 --- /dev/null +++ b/spec/lib/gitlab/email/hook/validate_addresses_interceptor_spec.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::Email::Hook::ValidateAddressesInterceptor do + describe 'UNSAFE_CHARACTERS' do + subject { described_class::UNSAFE_CHARACTERS } + + it { is_expected.to match('\\') } + it { is_expected.to match("\x00") } + it { is_expected.to match("\x01") } + it { is_expected.not_to match('') } + it { is_expected.not_to match('user@example.com') } + it { is_expected.not_to match('foo-123+bar_456@example.com') } + end + + describe '.delivering_email' do + let(:mail) do + ActionMailer::Base.mail(to: 'test@mail.com', from: 'info@mail.com', subject: 'title', body: 'hello') + end + + let(:unsafe_email) { "evil+\x01$HOME@example.com" } + + it 'sends emails to normal addresses' do + expect(Gitlab::AuthLogger).not_to receive(:info) + expect { mail.deliver_now }.to change(ActionMailer::Base.deliveries, :count) + end + + [:from, :to, :cc, :bcc].each do |header| + it "does not send emails if the #{header.inspect} header contains unsafe characters" do + mail[header] = unsafe_email + + expect(Gitlab::AuthLogger).to receive(:info).with( + message: 'Skipping email with unsafe characters in address', + address: unsafe_email, + subject: mail.subject + ) + + expect { mail.deliver_now }.not_to change(ActionMailer::Base.deliveries, :count) + end + end + + [:reply_to].each do |header| + it "sends emails if the #{header.inspect} header contains unsafe characters" do + mail[header] = unsafe_email + + expect(Gitlab::AuthLogger).not_to receive(:info) + expect { mail.deliver_now }.to change(ActionMailer::Base.deliveries, :count) + end + end + end +end diff --git a/spec/models/snippet_spec.rb b/spec/models/snippet_spec.rb index 5d4a78bb15f..92e4bc7d1a9 100644 --- a/spec/models/snippet_spec.rb +++ b/spec/models/snippet_spec.rb @@ -3,6 +3,8 @@ require 'spec_helper' RSpec.describe Snippet do + include FakeBlobHelpers + describe 'modules' do subject { described_class } @@ -526,6 +528,21 @@ RSpec.describe Snippet do end end + describe '#all_files' do + let(:snippet) { create(:snippet, :repository) } + let(:files) { double(:files) } + + subject(:all_files) { snippet.all_files } + + before do + allow(snippet.repository).to receive(:ls_files).with(snippet.default_branch).and_return(files) + end + + it 'lists files from the repository with the default branch' do + expect(all_files).to eq(files) + end + end + describe '#blobs' do context 'when repository does not exist' do let(:snippet) { create(:snippet) } @@ -552,6 +569,23 @@ RSpec.describe Snippet do end end end + + context 'when some blobs are not retrievable from repository' do + let(:snippet) { create(:snippet, :repository) } + let(:container) { double(:container) } + let(:retrievable_filename) { 'retrievable_file'} + let(:unretrievable_filename) { 'unretrievable_file'} + + before do + allow(snippet).to receive(:list_files).and_return([retrievable_filename, unretrievable_filename]) + blob = fake_blob(path: retrievable_filename, container: container) + allow(snippet.repository).to receive(:blobs_at).and_return([blob, nil]) + end + + it 'does not include unretrievable blobs' do + expect(snippet.blobs.map(&:name)).to contain_exactly(retrievable_filename) + end + end end describe '#to_json' do |