summaryrefslogtreecommitdiff
path: root/spec/lib
diff options
context:
space:
mode:
Diffstat (limited to 'spec/lib')
-rw-r--r--spec/lib/banzai/filter/syntax_highlight_filter_spec.rb34
-rw-r--r--spec/lib/gitlab/bitbucket_import/client_spec.rb2
-rw-r--r--spec/lib/gitlab/database/migration_helpers_spec.rb4
-rw-r--r--spec/lib/gitlab/diff/highlight_spec.rb4
-rw-r--r--spec/lib/gitlab/import_export/import_export_spec.rb21
-rw-r--r--spec/lib/gitlab/import_export/project.json1
-rw-r--r--spec/lib/gitlab/import_export/project_tree_restorer_spec.rb8
-rw-r--r--spec/lib/gitlab/lfs/lfs_router_spec.rb730
8 files changed, 64 insertions, 740 deletions
diff --git a/spec/lib/banzai/filter/syntax_highlight_filter_spec.rb b/spec/lib/banzai/filter/syntax_highlight_filter_spec.rb
index 407617f3307..b1370bca833 100644
--- a/spec/lib/banzai/filter/syntax_highlight_filter_spec.rb
+++ b/spec/lib/banzai/filter/syntax_highlight_filter_spec.rb
@@ -3,15 +3,35 @@ require 'spec_helper'
describe Banzai::Filter::SyntaxHighlightFilter, lib: true do
include FilterSpecHelper
- it 'highlights valid code blocks' do
- result = filter('<pre><code>def fun end</code>')
- expect(result.to_html).to eq("<pre class=\"code highlight js-syntax-highlight plaintext\"><code>def fun end</code></pre>\n")
+ context "when no language is specified" do
+ it "highlights as plaintext" do
+ result = filter('<pre><code>def fun end</code></pre>')
+ expect(result.to_html).to eq('<pre class="code highlight js-syntax-highlight plaintext"><code>def fun end</code></pre>')
+ end
end
- it 'passes through invalid code blocks' do
- allow_any_instance_of(described_class).to receive(:block_code).and_raise(StandardError)
+ context "when a valid language is specified" do
+ it "highlights as that language" do
+ result = filter('<pre><code class="ruby">def fun end</code></pre>')
+ expect(result.to_html).to eq('<pre class="code highlight js-syntax-highlight ruby"><code><span class="k">def</span> <span class="nf">fun</span> <span class="k">end</span></code></pre>')
+ end
+ end
+
+ context "when an invalid language is specified" do
+ it "highlights as plaintext" do
+ result = filter('<pre><code class="gnuplot">This is a test</code></pre>')
+ expect(result.to_html).to eq('<pre class="code highlight js-syntax-highlight plaintext"><code>This is a test</code></pre>')
+ end
+ end
+
+ context "when Rouge formatting fails" do
+ before do
+ allow_any_instance_of(Rouge::Formatter).to receive(:format).and_raise(StandardError)
+ end
- result = filter('<pre><code>This is a test</code></pre>')
- expect(result.to_html).to eq('<pre>This is a test</pre>')
+ it "highlights as plaintext" do
+ result = filter('<pre><code class="ruby">This is a test</code></pre>')
+ expect(result.to_html).to eq('<pre class="code highlight"><code>This is a test</code></pre>')
+ end
end
end
diff --git a/spec/lib/gitlab/bitbucket_import/client_spec.rb b/spec/lib/gitlab/bitbucket_import/client_spec.rb
index 760d66a1488..7543c29bcc4 100644
--- a/spec/lib/gitlab/bitbucket_import/client_spec.rb
+++ b/spec/lib/gitlab/bitbucket_import/client_spec.rb
@@ -54,12 +54,12 @@ describe Gitlab::BitbucketImport::Client, lib: true do
context 'project import' do
it 'calls .from_project with no errors' do
project = create(:empty_project)
+ project.import_url = "ssh://git@bitbucket.org/test/test.git"
project.create_or_update_import_data(credentials:
{ user: "git",
password: nil,
bb_session: { bitbucket_access_token: "test",
bitbucket_access_token_secret: "test" } })
- project.import_url = "ssh://git@bitbucket.org/test/test.git"
expect { described_class.from_project(project) }.not_to raise_error
end
diff --git a/spec/lib/gitlab/database/migration_helpers_spec.rb b/spec/lib/gitlab/database/migration_helpers_spec.rb
index 9096ad101b0..4ec3f19e03f 100644
--- a/spec/lib/gitlab/database/migration_helpers_spec.rb
+++ b/spec/lib/gitlab/database/migration_helpers_spec.rb
@@ -13,6 +13,10 @@ describe Gitlab::Database::MigrationHelpers, lib: true do
context 'outside a transaction' do
before do
expect(model).to receive(:transaction_open?).and_return(false)
+
+ unless Gitlab::Database.postgresql?
+ allow_any_instance_of(Gitlab::Database::MigrationHelpers).to receive(:disable_statement_timeout)
+ end
end
context 'using PostgreSQL' do
diff --git a/spec/lib/gitlab/diff/highlight_spec.rb b/spec/lib/gitlab/diff/highlight_spec.rb
index fb5d50a5c68..88e4115c453 100644
--- a/spec/lib/gitlab/diff/highlight_spec.rb
+++ b/spec/lib/gitlab/diff/highlight_spec.rb
@@ -28,13 +28,13 @@ describe Gitlab::Diff::Highlight, lib: true do
end
it 'highlights and marks removed lines' do
- code = %Q{-<span id="LC9" class="line"> <span class="k">raise</span> <span class="s2">&quot;System commands must be given as an array of strings&quot;</span></span>\n}
+ code = %Q{-<span id="LC9" class="line"> <span class="k">raise</span> <span class="s2">"System commands must be given as an array of strings"</span></span>\n}
expect(subject[4].text).to eq(code)
end
it 'highlights and marks added lines' do
- code = %Q{+<span id="LC9" class="line"> <span class="k">raise</span> <span class="no"><span class='idiff left'>RuntimeError</span></span><span class="p"><span class='idiff'>,</span></span><span class='idiff right'> </span><span class="s2">&quot;System commands must be given as an array of strings&quot;</span></span>\n}
+ code = %Q{+<span id="LC9" class="line"> <span class="k">raise</span> <span class="no"><span class='idiff left'>RuntimeError</span></span><span class="p"><span class='idiff'>,</span></span><span class='idiff right'> </span><span class="s2">"System commands must be given as an array of strings"</span></span>\n}
expect(subject[5].text).to eq(code)
end
diff --git a/spec/lib/gitlab/import_export/import_export_spec.rb b/spec/lib/gitlab/import_export/import_export_spec.rb
new file mode 100644
index 00000000000..d6409a29550
--- /dev/null
+++ b/spec/lib/gitlab/import_export/import_export_spec.rb
@@ -0,0 +1,21 @@
+require 'spec_helper'
+
+describe Gitlab::ImportExport, services: true do
+ describe 'export filename' do
+ let(:project) { create(:project, :public, path: 'project-path') }
+
+ it 'contains the project path' do
+ expect(described_class.export_filename(project: project)).to include(project.path)
+ end
+
+ it 'contains the namespace path' do
+ expect(described_class.export_filename(project: project)).to include(project.namespace.path)
+ end
+
+ it 'does not go over a certain length' do
+ project.path = 'a' * 100
+
+ expect(described_class.export_filename(project: project).length).to be < 70
+ end
+ end
+end
diff --git a/spec/lib/gitlab/import_export/project.json b/spec/lib/gitlab/import_export/project.json
index 7286b0c39c0..4113d829c3c 100644
--- a/spec/lib/gitlab/import_export/project.json
+++ b/spec/lib/gitlab/import_export/project.json
@@ -26,6 +26,7 @@
"deleted_at": null,
"due_date": null,
"moved_to_id": null,
+ "test_ee_field": "test",
"notes": [
{
"id": 351,
diff --git a/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
index 05ffec8ea0a..877be300262 100644
--- a/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
+++ b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
@@ -30,6 +30,14 @@ describe Gitlab::ImportExport::ProjectTreeRestorer, services: true do
expect(Event.where.not(data: nil).first.data[:ref]).not_to be_empty
end
+ it 'preserves updated_at on issues' do
+ restored_project_json
+
+ issue = Issue.where(description: 'Aliquam enim illo et possimus.').first
+
+ expect(issue.reload.updated_at.to_s).to eq('2016-06-14 15:02:47 UTC')
+ end
+
context 'event at forth level of the tree' do
let(:event) { Event.where(title: 'test levels').first }
diff --git a/spec/lib/gitlab/lfs/lfs_router_spec.rb b/spec/lib/gitlab/lfs/lfs_router_spec.rb
deleted file mode 100644
index 659facd6c19..00000000000
--- a/spec/lib/gitlab/lfs/lfs_router_spec.rb
+++ /dev/null
@@ -1,730 +0,0 @@
-require 'spec_helper'
-
-describe Gitlab::Lfs::Router, lib: true do
- let(:project) { create(:project) }
- let(:public_project) { create(:project, :public) }
- let(:forked_project) { fork_project(public_project, user) }
-
- let(:user) { create(:user) }
- let(:user_two) { create(:user) }
- let!(:lfs_object) { create(:lfs_object, :with_file) }
-
- let(:request) { Rack::Request.new(env) }
- let(:env) do
- {
- 'rack.input' => '',
- 'REQUEST_METHOD' => 'GET',
- }
- end
-
- let(:lfs_router_auth) { new_lfs_router(project, user: user) }
- let(:lfs_router_ci_auth) { new_lfs_router(project, ci: true) }
- let(:lfs_router_noauth) { new_lfs_router(project) }
- let(:lfs_router_public_auth) { new_lfs_router(public_project, user: user) }
- let(:lfs_router_public_ci_auth) { new_lfs_router(public_project, ci: true) }
- let(:lfs_router_public_noauth) { new_lfs_router(public_project) }
- let(:lfs_router_forked_noauth) { new_lfs_router(forked_project) }
- let(:lfs_router_forked_auth) { new_lfs_router(forked_project, user: user_two) }
- let(:lfs_router_forked_ci_auth) { new_lfs_router(forked_project, ci: true) }
-
- let(:sample_oid) { "b68143e6463773b1b6c6fd009a76c32aeec041faff32ba2ed42fd7f708a17f80" }
- let(:sample_size) { 499013 }
- let(:respond_with_deprecated) {[ 501, { "Content-Type" => "application/json; charset=utf-8" }, ["{\"message\":\"Server supports batch API only, please update your Git LFS client to version 1.0.1 and up.\",\"documentation_url\":\"#{Gitlab.config.gitlab.url}/help\"}"]]}
- let(:respond_with_disabled) {[ 501, { "Content-Type" => "application/json; charset=utf-8" }, ["{\"message\":\"Git LFS is not enabled on this GitLab server, contact your admin.\",\"documentation_url\":\"#{Gitlab.config.gitlab.url}/help\"}"]]}
-
- describe 'when lfs is disabled' do
- before do
- allow(Gitlab.config.lfs).to receive(:enabled).and_return(false)
- env['REQUEST_METHOD'] = 'POST'
- body = {
- 'objects' => [
- { 'oid' => '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897',
- 'size' => 1575078
- },
- { 'oid' => sample_oid,
- 'size' => sample_size
- }
- ],
- 'operation' => 'upload'
- }.to_json
- env['rack.input'] = StringIO.new(body)
- env["PATH_INFO"] = "#{project.repository.path_with_namespace}.git/info/lfs/objects/batch"
- end
-
- it 'responds with 501' do
- expect(lfs_router_auth.try_call).to match_array(respond_with_disabled)
- end
- end
-
- describe 'when fetching lfs object using deprecated API' do
- before do
- enable_lfs
- env["PATH_INFO"] = "#{project.repository.path_with_namespace}.git/info/lfs/objects/#{sample_oid}"
- end
-
- it 'responds with 501' do
- expect(lfs_router_auth.try_call).to match_array(respond_with_deprecated)
- end
- end
-
- describe 'when fetching lfs object' do
- before do
- enable_lfs
- env['HTTP_ACCEPT'] = "application/vnd.git-lfs+json; charset=utf-8"
- env["PATH_INFO"] = "#{project.repository.path_with_namespace}.git/gitlab-lfs/objects/#{sample_oid}"
- end
-
- describe 'and request comes from gitlab-workhorse' do
- context 'without user being authorized' do
- it "responds with status 401" do
- expect(lfs_router_noauth.try_call.first).to eq(401)
- end
- end
-
- context 'with required headers' do
- before do
- project.lfs_objects << lfs_object
- env['HTTP_X_SENDFILE_TYPE'] = "X-Sendfile"
- end
-
- context 'when user does not have project access' do
- it "responds with status 403" do
- expect(lfs_router_auth.try_call.first).to eq(403)
- end
- end
-
- context 'when user has project access' do
- before do
- project.team << [user, :master]
- end
-
- it "responds with status 200" do
- expect(lfs_router_auth.try_call.first).to eq(200)
- end
-
- it "responds with the file location" do
- expect(lfs_router_auth.try_call[1]['Content-Type']).to eq("application/octet-stream")
- expect(lfs_router_auth.try_call[1]['X-Sendfile']).to eq(lfs_object.file.path)
- end
- end
-
- context 'when CI is authorized' do
- it "responds with status 200" do
- expect(lfs_router_ci_auth.try_call.first).to eq(200)
- end
-
- it "responds with the file location" do
- expect(lfs_router_ci_auth.try_call[1]['Content-Type']).to eq("application/octet-stream")
- expect(lfs_router_ci_auth.try_call[1]['X-Sendfile']).to eq(lfs_object.file.path)
- end
- end
- end
-
- context 'without required headers' do
- it "responds with status 403" do
- expect(lfs_router_auth.try_call.first).to eq(403)
- end
- end
- end
- end
-
- describe 'when handling lfs request using deprecated API' do
- before do
- enable_lfs
- env['REQUEST_METHOD'] = 'POST'
- env["PATH_INFO"] = "#{project.repository.path_with_namespace}.git/info/lfs/objects"
- end
-
- it 'responds with 501' do
- expect(lfs_router_auth.try_call).to match_array(respond_with_deprecated)
- end
- end
-
- describe 'when handling lfs batch request' do
- before do
- enable_lfs
- env['REQUEST_METHOD'] = 'POST'
- env['PATH_INFO'] = "#{project.repository.path_with_namespace}.git/info/lfs/objects/batch"
- end
-
- describe 'download' do
- before do
- body = { 'operation' => 'download',
- 'objects' => [
- { 'oid' => sample_oid,
- 'size' => sample_size
- }]
- }.to_json
- env['rack.input'] = StringIO.new(body)
- end
-
- shared_examples 'an authorized requests' do
- context 'when downloading an lfs object that is assigned to our project' do
- before do
- project.lfs_objects << lfs_object
- end
-
- it 'responds with status 200 and href to download' do
- response = router.try_call
- expect(response.first).to eq(200)
- response_body = ActiveSupport::JSON.decode(response.last.first)
-
- expect(response_body).to eq('objects' => [
- { 'oid' => sample_oid,
- 'size' => sample_size,
- 'actions' => {
- 'download' => {
- 'href' => "#{project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}",
- 'header' => { 'Authorization' => auth }
- }
- }
- }])
- end
- end
-
- context 'when downloading an lfs object that is assigned to other project' do
- before do
- public_project.lfs_objects << lfs_object
- end
-
- it 'responds with status 200 and error message' do
- response = router.try_call
- expect(response.first).to eq(200)
- response_body = ActiveSupport::JSON.decode(response.last.first)
-
- expect(response_body).to eq('objects' => [
- { 'oid' => sample_oid,
- 'size' => sample_size,
- 'error' => {
- 'code' => 404,
- 'message' => "Object does not exist on the server or you don't have permissions to access it",
- }
- }])
- end
- end
-
- context 'when downloading a lfs object that does not exist' do
- before do
- body = { 'operation' => 'download',
- 'objects' => [
- { 'oid' => '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897',
- 'size' => 1575078
- }]
- }.to_json
- env['rack.input'] = StringIO.new(body)
- end
-
- it "responds with status 200 and error message" do
- response = router.try_call
- expect(response.first).to eq(200)
- response_body = ActiveSupport::JSON.decode(response.last.first)
-
- expect(response_body).to eq('objects' => [
- { 'oid' => '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897',
- 'size' => 1575078,
- 'error' => {
- 'code' => 404,
- 'message' => "Object does not exist on the server or you don't have permissions to access it",
- }
- }])
- end
- end
-
- context 'when downloading one new and one existing lfs object' do
- before do
- body = { 'operation' => 'download',
- 'objects' => [
- { 'oid' => '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897',
- 'size' => 1575078
- },
- { 'oid' => sample_oid,
- 'size' => sample_size
- }
- ]
- }.to_json
- env['rack.input'] = StringIO.new(body)
- project.lfs_objects << lfs_object
- end
-
- it "responds with status 200 with upload hypermedia link for the new object" do
- response = router.try_call
- expect(response.first).to eq(200)
- response_body = ActiveSupport::JSON.decode(response.last.first)
-
- expect(response_body).to eq('objects' => [
- { 'oid' => '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897',
- 'size' => 1575078,
- 'error' => {
- 'code' => 404,
- 'message' => "Object does not exist on the server or you don't have permissions to access it",
- }
- },
- { 'oid' => sample_oid,
- 'size' => sample_size,
- 'actions' => {
- 'download' => {
- 'href' => "#{project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}",
- 'header' => { 'Authorization' => auth }
- }
- }
- }])
- end
- end
- end
-
- context 'when user is authenticated' do
- let(:auth) { authorize(user) }
-
- before do
- env["HTTP_AUTHORIZATION"] = auth
- project.team << [user, role]
- end
-
- it_behaves_like 'an authorized requests' do
- let(:role) { :reporter }
- let(:router) { lfs_router_auth }
- end
-
- context 'when user does is not member of the project' do
- let(:role) { :guest }
-
- it 'responds with 403' do
- expect(lfs_router_auth.try_call.first).to eq(403)
- end
- end
-
- context 'when user does not have download access' do
- let(:role) { :guest }
-
- it 'responds with 403' do
- expect(lfs_router_auth.try_call.first).to eq(403)
- end
- end
- end
-
- context 'when CI is authorized' do
- let(:auth) { 'gitlab-ci-token:password' }
-
- before do
- env["HTTP_AUTHORIZATION"] = auth
- end
-
- it_behaves_like 'an authorized requests' do
- let(:router) { lfs_router_ci_auth }
- end
- end
-
- context 'when user is not authenticated' do
- describe 'is accessing public project' do
- before do
- public_project.lfs_objects << lfs_object
- end
-
- it 'responds with status 200 and href to download' do
- response = lfs_router_public_noauth.try_call
- expect(response.first).to eq(200)
- response_body = ActiveSupport::JSON.decode(response.last.first)
-
- expect(response_body).to eq('objects' => [
- { 'oid' => sample_oid,
- 'size' => sample_size,
- 'actions' => {
- 'download' => {
- 'href' => "#{public_project.http_url_to_repo}/gitlab-lfs/objects/#{sample_oid}",
- 'header' => {}
- }
- }
- }])
- end
- end
-
- describe 'is accessing non-public project' do
- before do
- project.lfs_objects << lfs_object
- end
-
- it 'responds with authorization required' do
- expect(lfs_router_noauth.try_call.first).to eq(401)
- end
- end
- end
- end
-
- describe 'upload' do
- before do
- body = { 'operation' => 'upload',
- 'objects' => [
- { 'oid' => sample_oid,
- 'size' => sample_size
- }]
- }.to_json
- env['rack.input'] = StringIO.new(body)
- end
-
- describe 'when request is authenticated' do
- describe 'when user has project push access' do
- before do
- @auth = authorize(user)
- env["HTTP_AUTHORIZATION"] = @auth
- project.team << [user, :developer]
- end
-
- context 'when pushing an lfs object that already exists' do
- before do
- public_project.lfs_objects << lfs_object
- end
-
- it "responds with status 200 and links the object to the project" do
- response_body = lfs_router_auth.try_call.last
- response = ActiveSupport::JSON.decode(response_body.first)
-
- expect(response['objects']).to be_kind_of(Array)
- expect(response['objects'].first['oid']).to eq(sample_oid)
- expect(response['objects'].first['size']).to eq(sample_size)
- expect(lfs_object.projects.pluck(:id)).not_to include(project.id)
- expect(lfs_object.projects.pluck(:id)).to include(public_project.id)
- expect(response['objects'].first['actions']['upload']['href']).to eq("#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}.git/gitlab-lfs/objects/#{sample_oid}/#{sample_size}")
- expect(response['objects'].first['actions']['upload']['header']).to eq('Authorization' => @auth)
- end
- end
-
- context 'when pushing a lfs object that does not exist' do
- before do
- body = { 'operation' => 'upload',
- 'objects' => [
- { 'oid' => '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897',
- 'size' => 1575078
- }]
- }.to_json
- env['rack.input'] = StringIO.new(body)
- end
-
- it "responds with status 200 and upload hypermedia link" do
- response = lfs_router_auth.try_call
- expect(response.first).to eq(200)
-
- response_body = ActiveSupport::JSON.decode(response.last.first)
- expect(response_body['objects']).to be_kind_of(Array)
- expect(response_body['objects'].first['oid']).to eq("91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897")
- expect(response_body['objects'].first['size']).to eq(1575078)
- expect(lfs_object.projects.pluck(:id)).not_to include(project.id)
- expect(response_body['objects'].first['actions']['upload']['href']).to eq("#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}.git/gitlab-lfs/objects/91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897/1575078")
- expect(response_body['objects'].first['actions']['upload']['header']).to eq('Authorization' => @auth)
- end
- end
-
- context 'when pushing one new and one existing lfs object' do
- before do
- body = { 'operation' => 'upload',
- 'objects' => [
- { 'oid' => '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897',
- 'size' => 1575078
- },
- { 'oid' => sample_oid,
- 'size' => sample_size
- }
- ]
- }.to_json
- env['rack.input'] = StringIO.new(body)
- project.lfs_objects << lfs_object
- end
-
- it "responds with status 200 with upload hypermedia link for the new object" do
- response = lfs_router_auth.try_call
- expect(response.first).to eq(200)
-
- response_body = ActiveSupport::JSON.decode(response.last.first)
- expect(response_body['objects']).to be_kind_of(Array)
-
- expect(response_body['objects'].first['oid']).to eq("91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897")
- expect(response_body['objects'].first['size']).to eq(1575078)
- expect(response_body['objects'].first['actions']['upload']['href']).to eq("#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}.git/gitlab-lfs/objects/91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897/1575078")
- expect(response_body['objects'].first['actions']['upload']['header']).to eq("Authorization" => @auth)
-
- expect(response_body['objects'].last['oid']).to eq(sample_oid)
- expect(response_body['objects'].last['size']).to eq(sample_size)
- expect(response_body['objects'].last).not_to have_key('actions')
- end
- end
- end
-
- context 'when user does not have push access' do
- it 'responds with 403' do
- expect(lfs_router_auth.try_call.first).to eq(403)
- end
- end
-
- context 'when CI is authorized' do
- it 'responds with 401' do
- expect(lfs_router_ci_auth.try_call.first).to eq(401)
- end
- end
- end
-
- context 'when user is not authenticated' do
- context 'when user has push access' do
- before do
- project.team << [user, :master]
- end
-
- it "responds with status 401" do
- expect(lfs_router_public_noauth.try_call.first).to eq(401)
- end
- end
-
- context 'when user does not have push access' do
- it "responds with status 401" do
- expect(lfs_router_public_noauth.try_call.first).to eq(401)
- end
- end
- end
-
- context 'when CI is authorized' do
- let(:auth) { 'gitlab-ci-token:password' }
-
- before do
- env["HTTP_AUTHORIZATION"] = auth
- end
-
- it "responds with status 403" do
- expect(lfs_router_public_ci_auth.try_call.first).to eq(401)
- end
- end
- end
-
- describe 'unsupported' do
- before do
- body = { 'operation' => 'other',
- 'objects' => [
- { 'oid' => sample_oid,
- 'size' => sample_size
- }]
- }.to_json
- env['rack.input'] = StringIO.new(body)
- end
-
- it 'responds with status 404' do
- expect(lfs_router_public_noauth.try_call.first).to eq(404)
- end
- end
- end
-
- describe 'when pushing a lfs object' do
- before do
- enable_lfs
- env['REQUEST_METHOD'] = 'PUT'
- end
-
- shared_examples 'unauthorized' do
- context 'and request is sent by gitlab-workhorse to authorize the request' do
- before do
- header_for_upload_authorize(router.project)
- end
-
- it 'responds with status 401' do
- expect(router.try_call.first).to eq(401)
- end
- end
-
- context 'and request is sent by gitlab-workhorse to finalize the upload' do
- before do
- headers_for_upload_finalize(router.project)
- end
-
- it 'responds with status 401' do
- expect(router.try_call.first).to eq(401)
- end
- end
-
- context 'and request is sent with a malformed headers' do
- before do
- env["PATH_INFO"] = "#{router.project.repository.path_with_namespace}.git/gitlab-lfs/objects/#{sample_oid}/#{sample_size}"
- env["HTTP_X_GITLAB_LFS_TMP"] = "cat /etc/passwd"
- end
-
- it 'does not recognize it as a valid lfs command' do
- expect(router.try_call).to eq(nil)
- end
- end
- end
-
- shared_examples 'forbidden' do
- context 'and request is sent by gitlab-workhorse to authorize the request' do
- before do
- header_for_upload_authorize(router.project)
- end
-
- it 'responds with 403' do
- expect(router.try_call.first).to eq(403)
- end
- end
-
- context 'and request is sent by gitlab-workhorse to finalize the upload' do
- before do
- headers_for_upload_finalize(router.project)
- end
-
- it 'responds with 403' do
- expect(router.try_call.first).to eq(403)
- end
- end
- end
-
- describe 'to one project' do
- describe 'when user is authenticated' do
- describe 'when user has push access to the project' do
- before do
- project.team << [user, :developer]
- end
-
- context 'and request is sent by gitlab-workhorse to authorize the request' do
- before do
- header_for_upload_authorize(project)
- end
-
- it 'responds with status 200, location of lfs store and object details' do
- json_response = ActiveSupport::JSON.decode(lfs_router_auth.try_call.last.first)
-
- expect(lfs_router_auth.try_call.first).to eq(200)
- expect(json_response['StoreLFSPath']).to eq("#{Gitlab.config.shared.path}/lfs-objects/tmp/upload")
- expect(json_response['LfsOid']).to eq(sample_oid)
- expect(json_response['LfsSize']).to eq(sample_size)
- end
- end
-
- context 'and request is sent by gitlab-workhorse to finalize the upload' do
- before do
- headers_for_upload_finalize(project)
- end
-
- it 'responds with status 200 and lfs object is linked to the project' do
- expect(lfs_router_auth.try_call.first).to eq(200)
- expect(lfs_object.projects.pluck(:id)).to include(project.id)
- end
- end
- end
-
- describe 'and user does not have push access' do
- let(:router) { lfs_router_auth }
-
- it_behaves_like 'forbidden'
- end
- end
-
- context 'when CI is authenticated' do
- let(:router) { lfs_router_ci_auth }
-
- it_behaves_like 'unauthorized'
- end
-
- context 'for unauthenticated' do
- let(:router) { new_lfs_router(project) }
-
- it_behaves_like 'unauthorized'
- end
- end
-
- describe 'to a forked project' do
- let(:forked_project) { fork_project(public_project, user) }
-
- describe 'when user is authenticated' do
- describe 'when user has push access to the project' do
- before do
- forked_project.team << [user_two, :developer]
- end
-
- context 'and request is sent by gitlab-workhorse to authorize the request' do
- before do
- header_for_upload_authorize(forked_project)
- end
-
- it 'responds with status 200, location of lfs store and object details' do
- json_response = ActiveSupport::JSON.decode(lfs_router_forked_auth.try_call.last.first)
-
- expect(lfs_router_forked_auth.try_call.first).to eq(200)
- expect(json_response['StoreLFSPath']).to eq("#{Gitlab.config.shared.path}/lfs-objects/tmp/upload")
- expect(json_response['LfsOid']).to eq(sample_oid)
- expect(json_response['LfsSize']).to eq(sample_size)
- end
- end
-
- context 'and request is sent by gitlab-workhorse to finalize the upload' do
- before do
- headers_for_upload_finalize(forked_project)
- end
-
- it 'responds with status 200 and lfs object is linked to the source project' do
- expect(lfs_router_forked_auth.try_call.first).to eq(200)
- expect(lfs_object.projects.pluck(:id)).to include(public_project.id)
- end
- end
- end
-
- describe 'and user does not have push access' do
- let(:router) { lfs_router_forked_auth }
-
- it_behaves_like 'forbidden'
- end
- end
-
- context 'when CI is authenticated' do
- let(:router) { lfs_router_forked_ci_auth }
-
- it_behaves_like 'unauthorized'
- end
-
- context 'for unauthenticated' do
- let(:router) { lfs_router_forked_noauth }
-
- it_behaves_like 'unauthorized'
- end
-
- describe 'and second project not related to fork or a source project' do
- let(:second_project) { create(:project) }
- let(:lfs_router_second_project) { new_lfs_router(second_project, user: user) }
-
- before do
- public_project.lfs_objects << lfs_object
- headers_for_upload_finalize(second_project)
- end
-
- context 'when pushing the same lfs object to the second project' do
- before do
- second_project.team << [user, :master]
- end
-
- it 'responds with 200 and links the lfs object to the project' do
- expect(lfs_router_second_project.try_call.first).to eq(200)
- expect(lfs_object.projects.pluck(:id)).to include(second_project.id, public_project.id)
- end
- end
- end
- end
- end
-
- def enable_lfs
- allow(Gitlab.config.lfs).to receive(:enabled).and_return(true)
- end
-
- def authorize(user)
- ActionController::HttpAuthentication::Basic.encode_credentials(user.username, user.password)
- end
-
- def new_lfs_router(project, user: nil, ci: false)
- Gitlab::Lfs::Router.new(project, user, ci, request)
- end
-
- def header_for_upload_authorize(project)
- env["PATH_INFO"] = "#{project.repository.path_with_namespace}.git/gitlab-lfs/objects/#{sample_oid}/#{sample_size}/authorize"
- end
-
- def headers_for_upload_finalize(project)
- env["PATH_INFO"] = "#{project.repository.path_with_namespace}.git/gitlab-lfs/objects/#{sample_oid}/#{sample_size}"
- env["HTTP_X_GITLAB_LFS_TMP"] = "#{sample_oid}6e561c9d4"
- end
-
- def fork_project(project, user, object = nil)
- allow(RepositoryForkWorker).to receive(:perform_async).and_return(true)
- Projects::ForkService.new(project, user, {}).execute
- end
-end