summaryrefslogtreecommitdiff
path: root/spec/lib
diff options
context:
space:
mode:
authorMarcia Ramos <virtua.creative@gmail.com>2018-08-16 10:17:22 +0100
committerMarcia Ramos <virtua.creative@gmail.com>2018-08-16 10:17:22 +0100
commitbfc0c602072bd5b9bf73e117d0808043adc9465e (patch)
treeea55f6e86fdfdcccca9c593d5441c9d2c3efd441 /spec/lib
parent1e23577417b3e4eb06b9aba1ec174dbe78b6b9be (diff)
parent0a666b2cb1020df4b8f7b71041b6bd109b49656a (diff)
downloadgitlab-ce-docs-processes.tar.gz
Merge branch 'master' of gitlab.com:gitlab-org/gitlab-ce into docs-processesdocs-processes
Diffstat (limited to 'spec/lib')
-rw-r--r--spec/lib/banzai/filter/project_reference_filter_spec.rb85
-rw-r--r--spec/lib/banzai/filter/user_reference_filter_spec.rb85
-rw-r--r--spec/lib/banzai/reference_parser/project_parser_spec.rb50
-rw-r--r--spec/lib/gitlab/cleanup/project_uploads_spec.rb2
-rw-r--r--spec/lib/gitlab/database/migration_helpers_spec.rb86
-rw-r--r--spec/lib/gitlab/git/merge_base_spec.rb95
-rw-r--r--spec/lib/gitlab/template/finders/repo_template_finders_spec.rb37
7 files changed, 359 insertions, 81 deletions
diff --git a/spec/lib/banzai/filter/project_reference_filter_spec.rb b/spec/lib/banzai/filter/project_reference_filter_spec.rb
new file mode 100644
index 00000000000..48140305e26
--- /dev/null
+++ b/spec/lib/banzai/filter/project_reference_filter_spec.rb
@@ -0,0 +1,85 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Banzai::Filter::ProjectReferenceFilter do
+ include FilterSpecHelper
+
+ def invalidate_reference(reference)
+ "#{reference.reverse}"
+ end
+
+ def get_reference(project)
+ project.to_reference_with_postfix
+ end
+
+ let(:project) { create(:project, :public) }
+ subject { project }
+ let(:subject_name) { "project" }
+ let(:reference) { get_reference(project) }
+
+ it_behaves_like 'user reference or project reference'
+
+ it 'ignores invalid projects' do
+ exp = act = "Hey #{invalidate_reference(reference)}"
+
+ expect(reference_filter(act).to_html).to eq(CGI.escapeHTML(exp))
+ end
+
+ it 'allows references with text after the > character' do
+ doc = reference_filter("Hey #{reference}foo")
+ expect(doc.css('a').first.attr('href')).to eq urls.project_url(subject)
+ end
+
+ %w(pre code a style).each do |elem|
+ it "ignores valid references contained inside '#{elem}' element" do
+ exp = act = "<#{elem}>Hey #{CGI.escapeHTML(reference)}</#{elem}>"
+ expect(reference_filter(act).to_html).to eq exp
+ end
+ end
+
+ it 'includes default classes' do
+ doc = reference_filter("Hey #{reference}")
+ expect(doc.css('a').first.attr('class')).to eq 'gfm gfm-project has-tooltip'
+ end
+
+ context 'in group context' do
+ let(:group) { create(:group) }
+ let(:project) { create(:project, group: group) }
+
+ let(:nested_group) { create(:group, :nested) }
+ let(:nested_project) { create(:project, group: nested_group) }
+
+ it 'supports mentioning a project' do
+ reference = get_reference(project)
+ doc = reference_filter("Hey #{reference}")
+
+ expect(doc.css('a').first.attr('href')).to eq urls.project_url(project)
+ end
+
+ it 'supports mentioning a project in a nested group' do
+ reference = get_reference(nested_project)
+ doc = reference_filter("Hey #{reference}")
+
+ expect(doc.css('a').first.attr('href')).to eq urls.project_url(nested_project)
+ end
+ end
+
+ describe '#projects_hash' do
+ it 'returns a Hash containing all Projects' do
+ document = Nokogiri::HTML.fragment("<p>#{get_reference(project)}</p>")
+ filter = described_class.new(document, project: project)
+
+ expect(filter.projects_hash).to eq({ project.full_path => project })
+ end
+ end
+
+ describe '#projects' do
+ it 'returns the projects mentioned in a document' do
+ document = Nokogiri::HTML.fragment("<p>#{get_reference(project)}</p>")
+ filter = described_class.new(document, project: project)
+
+ expect(filter.projects).to eq([project.full_path])
+ end
+ end
+end
diff --git a/spec/lib/banzai/filter/user_reference_filter_spec.rb b/spec/lib/banzai/filter/user_reference_filter_spec.rb
index 2f86a046d28..334d29a5368 100644
--- a/spec/lib/banzai/filter/user_reference_filter_spec.rb
+++ b/spec/lib/banzai/filter/user_reference_filter_spec.rb
@@ -3,9 +3,17 @@ require 'spec_helper'
describe Banzai::Filter::UserReferenceFilter do
include FilterSpecHelper
+ def get_reference(user)
+ user.to_reference
+ end
+
let(:project) { create(:project, :public) }
let(:user) { create(:user) }
- let(:reference) { user.to_reference }
+ subject { user }
+ let(:subject_name) { "user" }
+ let(:reference) { get_reference(user) }
+
+ it_behaves_like 'user reference or project reference'
it 'requires project context' do
expect { described_class.call('') }.to raise_error(ArgumentError, /:project/)
@@ -66,45 +74,6 @@ describe Banzai::Filter::UserReferenceFilter do
end
end
- context 'mentioning a user' do
- it_behaves_like 'a reference containing an element node'
-
- it 'links to a User' do
- doc = reference_filter("Hey #{reference}")
- expect(doc.css('a').first.attr('href')).to eq urls.user_url(user)
- end
-
- it 'links to a User with a period' do
- user = create(:user, name: 'alphA.Beta')
-
- doc = reference_filter("Hey #{user.to_reference}")
- expect(doc.css('a').length).to eq 1
- end
-
- it 'links to a User with an underscore' do
- user = create(:user, name: 'ping_pong_king')
-
- doc = reference_filter("Hey #{user.to_reference}")
- expect(doc.css('a').length).to eq 1
- end
-
- it 'links to a User with different case-sensitivity' do
- user = create(:user, username: 'RescueRanger')
-
- doc = reference_filter("Hey #{user.to_reference.upcase}")
- expect(doc.css('a').length).to eq 1
- expect(doc.css('a').text).to eq(user.to_reference)
- end
-
- it 'includes a data-user attribute' do
- doc = reference_filter("Hey #{reference}")
- link = doc.css('a').first
-
- expect(link).to have_attribute('data-user')
- expect(link.attr('data-user')).to eq user.namespace.owner_id.to_s
- end
- end
-
context 'mentioning a group' do
it_behaves_like 'a reference containing an element node'
@@ -154,36 +123,6 @@ describe Banzai::Filter::UserReferenceFilter do
expect(doc.css('a').first.attr('class')).to eq 'gfm gfm-project_member has-tooltip'
end
- it 'supports an :only_path context' do
- doc = reference_filter("Hey #{reference}", only_path: true)
- link = doc.css('a').first.attr('href')
-
- expect(link).not_to match %r(https?://)
- expect(link).to eq urls.user_path(user)
- end
-
- context 'referencing a user in a link href' do
- let(:reference) { %Q{<a href="#{user.to_reference}">User</a>} }
-
- it 'links to a User' do
- doc = reference_filter("Hey #{reference}")
- expect(doc.css('a').first.attr('href')).to eq urls.user_url(user)
- end
-
- it 'links with adjacent text' do
- doc = reference_filter("Mention me (#{reference}.)")
- expect(doc.to_html).to match(%r{\(<a.+>User</a>\.\)})
- end
-
- it 'includes a data-user attribute' do
- doc = reference_filter("Hey #{reference}")
- link = doc.css('a').first
-
- expect(link).to have_attribute('data-user')
- expect(link.attr('data-user')).to eq user.namespace.owner_id.to_s
- end
- end
-
context 'when a project is not specified' do
let(:project) { nil }
@@ -227,7 +166,7 @@ describe Banzai::Filter::UserReferenceFilter do
end
it 'supports mentioning a single user' do
- reference = group_member.to_reference
+ reference = get_reference(group_member)
doc = reference_filter("Hey #{reference}", context)
expect(doc.css('a').first.attr('href')).to eq urls.user_url(group_member)
@@ -243,7 +182,7 @@ describe Banzai::Filter::UserReferenceFilter do
describe '#namespaces' do
it 'returns a Hash containing all Namespaces' do
- document = Nokogiri::HTML.fragment("<p>#{user.to_reference}</p>")
+ document = Nokogiri::HTML.fragment("<p>#{get_reference(user)}</p>")
filter = described_class.new(document, project: project)
ns = user.namespace
@@ -253,7 +192,7 @@ describe Banzai::Filter::UserReferenceFilter do
describe '#usernames' do
it 'returns the usernames mentioned in a document' do
- document = Nokogiri::HTML.fragment("<p>#{user.to_reference}</p>")
+ document = Nokogiri::HTML.fragment("<p>#{get_reference(user)}</p>")
filter = described_class.new(document, project: project)
expect(filter.usernames).to eq([user.username])
diff --git a/spec/lib/banzai/reference_parser/project_parser_spec.rb b/spec/lib/banzai/reference_parser/project_parser_spec.rb
new file mode 100644
index 00000000000..e4936aa9e57
--- /dev/null
+++ b/spec/lib/banzai/reference_parser/project_parser_spec.rb
@@ -0,0 +1,50 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Banzai::ReferenceParser::ProjectParser do
+ include ReferenceParserHelpers
+
+ let(:project) { create(:project, :public) }
+ let(:user) { create(:user) }
+ subject { described_class.new(Banzai::RenderContext.new(project, user)) }
+ let(:link) { empty_html_link }
+
+ describe '#referenced_by' do
+ describe 'when the link has a data-project attribute' do
+ context 'using an existing project ID' do
+ it 'returns an Array of projects' do
+ link['data-project'] = project.id.to_s
+
+ expect(subject.gather_references([link])).to eq([project])
+ end
+ end
+
+ context 'using a non-existing project ID' do
+ it 'returns an empty Array' do
+ link['data-project'] = ''
+
+ expect(subject.gather_references([link])).to eq([])
+ end
+ end
+
+ context 'using a private project ID' do
+ it 'returns an empty Array when unauthorized' do
+ private_project = create(:project, :private)
+
+ link['data-project'] = private_project.id.to_s
+
+ expect(subject.gather_references([link])).to eq([])
+ end
+
+ it 'returns an Array when authorized' do
+ private_project = create(:project, :private, namespace: user.namespace)
+
+ link['data-project'] = private_project.id.to_s
+
+ expect(subject.gather_references([link])).to eq([private_project])
+ end
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/cleanup/project_uploads_spec.rb b/spec/lib/gitlab/cleanup/project_uploads_spec.rb
index 37b38776775..11e605eece6 100644
--- a/spec/lib/gitlab/cleanup/project_uploads_spec.rb
+++ b/spec/lib/gitlab/cleanup/project_uploads_spec.rb
@@ -244,9 +244,11 @@ describe Gitlab::Cleanup::ProjectUploads do
orphaned1 = create(:upload, :personal_snippet_upload, :with_file)
orphaned2 = create(:upload, :namespace_upload, :with_file)
orphaned3 = create(:upload, :attachment_upload, :with_file)
+ orphaned4 = create(:upload, :favicon_upload, :with_file)
paths << orphaned1.absolute_path
paths << orphaned2.absolute_path
paths << orphaned3.absolute_path
+ paths << orphaned4.absolute_path
Upload.delete_all
expect(logger).not_to receive(:info).with(/move|fix/i)
diff --git a/spec/lib/gitlab/database/migration_helpers_spec.rb b/spec/lib/gitlab/database/migration_helpers_spec.rb
index eb7148ff108..4e83b27e4a5 100644
--- a/spec/lib/gitlab/database/migration_helpers_spec.rb
+++ b/spec/lib/gitlab/database/migration_helpers_spec.rb
@@ -48,10 +48,10 @@ describe Gitlab::Database::MigrationHelpers do
allow(model).to receive(:transaction_open?).and_return(false)
end
- context 'using PostgreSQL' do
+ context 'using PostgreSQL', :postgresql do
before do
allow(Gitlab::Database).to receive(:postgresql?).and_return(true)
- allow(model).to receive(:disable_statement_timeout)
+ allow(model).to receive(:disable_statement_timeout).and_call_original
end
it 'creates the index concurrently' do
@@ -114,12 +114,12 @@ describe Gitlab::Database::MigrationHelpers do
before do
allow(model).to receive(:transaction_open?).and_return(false)
allow(model).to receive(:index_exists?).and_return(true)
+ allow(model).to receive(:disable_statement_timeout).and_call_original
end
context 'using PostgreSQL' do
before do
allow(model).to receive(:supports_drop_index_concurrently?).and_return(true)
- allow(model).to receive(:disable_statement_timeout)
end
describe 'by column name' do
@@ -162,7 +162,7 @@ describe Gitlab::Database::MigrationHelpers do
context 'using MySQL' do
it 'removes an index' do
- expect(Gitlab::Database).to receive(:postgresql?).and_return(false)
+ expect(Gitlab::Database).to receive(:postgresql?).and_return(false).twice
expect(model).to receive(:remove_index)
.with(:users, { column: :foo })
@@ -224,21 +224,26 @@ describe Gitlab::Database::MigrationHelpers do
context 'using PostgreSQL' do
before do
+ allow(Gitlab::Database).to receive(:postgresql?).and_return(true)
allow(Gitlab::Database).to receive(:mysql?).and_return(false)
end
it 'creates a concurrent foreign key and validates it' do
- expect(model).to receive(:disable_statement_timeout)
+ expect(model).to receive(:disable_statement_timeout).and_call_original
+ expect(model).to receive(:execute).with(/statement_timeout/)
expect(model).to receive(:execute).ordered.with(/NOT VALID/)
expect(model).to receive(:execute).ordered.with(/VALIDATE CONSTRAINT/)
+ expect(model).to receive(:execute).with(/RESET ALL/)
model.add_concurrent_foreign_key(:projects, :users, column: :user_id)
end
it 'appends a valid ON DELETE statement' do
- expect(model).to receive(:disable_statement_timeout)
+ expect(model).to receive(:disable_statement_timeout).and_call_original
+ expect(model).to receive(:execute).with(/statement_timeout/)
expect(model).to receive(:execute).with(/ON DELETE SET NULL/)
expect(model).to receive(:execute).ordered.with(/VALIDATE CONSTRAINT/)
+ expect(model).to receive(:execute).with(/RESET ALL/)
model.add_concurrent_foreign_key(:projects, :users,
column: :user_id,
@@ -291,13 +296,68 @@ describe Gitlab::Database::MigrationHelpers do
describe '#disable_statement_timeout' do
context 'using PostgreSQL' do
- it 'disables statement timeouts' do
+ it 'disables statement timeouts to current transaction only' do
expect(Gitlab::Database).to receive(:postgresql?).and_return(true)
- expect(model).to receive(:execute).with('SET statement_timeout TO 0')
+ expect(model).to receive(:execute).with('SET LOCAL statement_timeout TO 0')
model.disable_statement_timeout
end
+
+ # this specs runs without an enclosing transaction (:delete truncation method for db_cleaner)
+ context 'with real environment', :postgresql, :delete do
+ before do
+ model.execute("SET statement_timeout TO '20000'")
+ end
+
+ after do
+ model.execute('RESET ALL')
+ end
+
+ it 'defines statement to 0 only for current transaction' do
+ expect(model.execute('SHOW statement_timeout').first['statement_timeout']).to eq('20s')
+
+ model.connection.transaction do
+ model.disable_statement_timeout
+ expect(model.execute('SHOW statement_timeout').first['statement_timeout']).to eq('0')
+ end
+
+ expect(model.execute('SHOW statement_timeout').first['statement_timeout']).to eq('20s')
+ end
+ end
+
+ context 'when passing a blocks' do
+ it 'disables statement timeouts on session level and executes the block' do
+ expect(Gitlab::Database).to receive(:postgresql?).and_return(true)
+ expect(model).to receive(:execute).with('SET statement_timeout TO 0')
+ expect(model).to receive(:execute).with('RESET ALL')
+
+ expect { |block| model.disable_statement_timeout(&block) }.to yield_control
+ end
+
+ # this specs runs without an enclosing transaction (:delete truncation method for db_cleaner)
+ context 'with real environment', :postgresql, :delete do
+ before do
+ model.execute("SET statement_timeout TO '20000'")
+ end
+
+ after do
+ model.execute('RESET ALL')
+ end
+
+ it 'defines statement to 0 for any code run inside the block' do
+ expect(model.execute('SHOW statement_timeout').first['statement_timeout']).to eq('20s')
+
+ model.disable_statement_timeout do
+ model.connection.transaction do
+ expect(model.execute('SHOW statement_timeout').first['statement_timeout']).to eq('0')
+ end
+
+ expect(model.execute('SHOW statement_timeout').first['statement_timeout']).to eq('0')
+ end
+ end
+ end
+ end
end
context 'using MySQL' do
@@ -308,6 +368,16 @@ describe Gitlab::Database::MigrationHelpers do
model.disable_statement_timeout
end
+
+ context 'when passing a blocks' do
+ it 'executes the block of code' do
+ expect(Gitlab::Database).to receive(:postgresql?).and_return(false)
+
+ expect(model).not_to receive(:execute)
+
+ expect { |block| model.disable_statement_timeout(&block) }.to yield_control
+ end
+ end
end
end
diff --git a/spec/lib/gitlab/git/merge_base_spec.rb b/spec/lib/gitlab/git/merge_base_spec.rb
new file mode 100644
index 00000000000..2f4e043a20f
--- /dev/null
+++ b/spec/lib/gitlab/git/merge_base_spec.rb
@@ -0,0 +1,95 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Git::MergeBase do
+ set(:project) { create(:project, :repository) }
+ let(:repository) { project.repository }
+ subject(:merge_base) { described_class.new(repository, refs) }
+
+ shared_context 'existing refs with a merge base', :existing_refs do
+ let(:refs) do
+ %w(304d257dcb821665ab5110318fc58a007bd104ed 0031876facac3f2b2702a0e53a26e89939a42209)
+ end
+ end
+
+ shared_context 'when passing a missing ref', :missing_ref do
+ let(:refs) do
+ %w(304d257dcb821665ab5110318fc58a007bd104ed aaaa)
+ end
+ end
+
+ shared_context 'when passing refs that do not have a common ancestor', :no_common_ancestor do
+ let(:refs) { ['304d257dcb821665ab5110318fc58a007bd104ed', TestEnv::BRANCH_SHA['orphaned-branch']] }
+ end
+
+ describe '#sha' do
+ context 'when the refs exist', :existing_refs do
+ it 'returns the SHA of the merge base' do
+ expect(merge_base.sha).not_to be_nil
+ end
+
+ it 'memoizes the result' do
+ expect(repository).to receive(:merge_base).once.and_call_original
+
+ 2.times { merge_base.sha }
+ end
+ end
+
+ context 'when passing a missing ref', :missing_ref do
+ it 'does not call merge_base on the repository but raises an error' do
+ expect(repository).not_to receive(:merge_base)
+
+ expect { merge_base.sha }.to raise_error(Gitlab::Git::UnknownRef)
+ end
+ end
+
+ it 'returns `nil` when the refs do not have a common ancestor', :no_common_ancestor do
+ expect(merge_base.sha).to be_nil
+ end
+
+ it 'returns a merge base when passing 2 branch names' do
+ merge_base = described_class.new(repository, %w(master feature))
+
+ expect(merge_base.sha).to be_present
+ end
+
+ it 'returns a merge base when passing a tag name' do
+ merge_base = described_class.new(repository, %w(master v1.0.0))
+
+ expect(merge_base.sha).to be_present
+ end
+ end
+
+ describe '#commit' do
+ context 'for existing refs with a merge base', :existing_refs do
+ it 'finds the commit for the merge base' do
+ expect(merge_base.commit).to be_a(Commit)
+ end
+
+ it 'only looks up the commit once' do
+ expect(repository).to receive(:commit_by).once.and_call_original
+
+ 2.times { merge_base.commit }
+ end
+ end
+
+ it 'does not try to find the commit when there is no sha', :no_common_ancestor do
+ expect(repository).not_to receive(:commit_by)
+
+ merge_base.commit
+ end
+ end
+
+ describe '#unknown_refs', :missing_ref do
+ it 'returns the the refs passed that are not part of the repository' do
+ expect(merge_base.unknown_refs).to contain_exactly('aaaa')
+ end
+
+ it 'only looks up the commits once' do
+ expect(merge_base).to receive(:commits_for_refs).once.and_call_original
+
+ 2.times { merge_base.unknown_refs }
+ end
+ end
+end
diff --git a/spec/lib/gitlab/template/finders/repo_template_finders_spec.rb b/spec/lib/gitlab/template/finders/repo_template_finders_spec.rb
new file mode 100644
index 00000000000..2eabccd5dff
--- /dev/null
+++ b/spec/lib/gitlab/template/finders/repo_template_finders_spec.rb
@@ -0,0 +1,37 @@
+require 'spec_helper'
+
+describe Gitlab::Template::Finders::RepoTemplateFinder do
+ set(:project) { create(:project, :repository) }
+
+ let(:categories) { { 'HTML' => 'html' } }
+
+ subject(:finder) { described_class.new(project, 'files/', '.html', categories) }
+
+ describe '#read' do
+ it 'returns the content of the given path' do
+ result = finder.read('files/html/500.html')
+
+ expect(result).to be_present
+ end
+
+ it 'raises an error if the path does not exist' do
+ expect { finder.read('does/not/exist') }.to raise_error(described_class::FileNotFoundError)
+ end
+ end
+
+ describe '#find' do
+ it 'returns the full path of the found template' do
+ result = finder.find('500')
+
+ expect(result).to eq('files/html/500.html')
+ end
+ end
+
+ describe '#list_files_for' do
+ it 'returns the full path of the found files' do
+ result = finder.list_files_for('files/html')
+
+ expect(result).to contain_exactly('files/html/500.html')
+ end
+ end
+end