summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorDouwe Maan <douwe@gitlab.com>2015-11-17 16:19:16 +0100
committerDouwe Maan <douwe@gitlab.com>2015-11-17 16:19:16 +0100
commit16438ad205bbd953ae7fd5c290e05b60618ce7f4 (patch)
tree54ff61e7b7817a29090539da874bd99c6312b0de /spec
parent8434e78b2802d7fe8780a2b3a7358ecfb66b95cf (diff)
parentdf0110ba81a86b3e066c8b703e1c26d6d05a75da (diff)
downloadgitlab-ce-16438ad205bbd953ae7fd5c290e05b60618ce7f4.tar.gz
Merge branch 'master' into dbalexandre/gitlab-ce-fix-personal-snippet-access-workflow
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/admin/users_controller_spec.rb15
-rw-r--r--spec/controllers/projects/compare_controller_spec.rb16
-rw-r--r--spec/controllers/projects/merge_requests_controller_spec.rb28
-rw-r--r--spec/factories/ci/projects.rb12
-rw-r--r--spec/factories/labels.rb1
-rw-r--r--spec/factories/lfs_objects.rb12
-rw-r--r--spec/factories/lfs_objects_projects.rb8
-rw-r--r--spec/factories/merge_requests.rb1
-rw-r--r--spec/factories/releases.rb21
-rw-r--r--spec/features/admin/admin_users_spec.rb50
-rw-r--r--spec/features/builds_spec.rb21
-rw-r--r--spec/features/commits_spec.rb16
-rw-r--r--spec/features/runners_spec.rb12
-rw-r--r--spec/lib/ci/gitlab_ci_yaml_processor_spec.rb133
-rw-r--r--spec/lib/gitlab/inline_diff_spec.rb (renamed from spec/lib/gitlab/diff/inline_diff_spec.rb)0
-rw-r--r--spec/lib/gitlab/lfs/lfs_router_spec.rb650
-rw-r--r--spec/models/application_setting_spec.rb4
-rw-r--r--spec/models/build_spec.rb15
-rw-r--r--spec/models/ci/commit_spec.rb25
-rw-r--r--spec/models/ci/project_spec.rb20
-rw-r--r--spec/models/ci/runner_project_spec.rb2
-rw-r--r--spec/models/ci/runner_spec.rb2
-rw-r--r--spec/models/ci/service_spec.rb2
-rw-r--r--spec/models/ci/trigger_spec.rb12
-rw-r--r--spec/models/ci/variable_spec.rb2
-rw-r--r--spec/models/ci/web_hook_spec.rb2
-rw-r--r--spec/models/commit_status_spec.rb33
-rw-r--r--spec/models/generic_commit_status_spec.rb33
-rw-r--r--spec/models/global_milestone_spec.rb65
-rw-r--r--spec/models/group_spec.rb1
-rw-r--r--spec/models/label_spec.rb1
-rw-r--r--spec/models/merge_request_spec.rb1
-rw-r--r--spec/models/namespace_spec.rb1
-rw-r--r--spec/models/project_spec.rb9
-rw-r--r--spec/models/project_wiki_spec.rb18
-rw-r--r--spec/models/release_spec.rb28
-rw-r--r--spec/models/user_spec.rb2
-rw-r--r--spec/requests/api/commit_status_spec.rb4
-rw-r--r--spec/requests/api/projects_spec.rb7
-rw-r--r--spec/requests/api/repositories_spec.rb75
-rw-r--r--spec/requests/api/services_spec.rb1
-rw-r--r--spec/requests/api/tags_spec.rb135
-rw-r--r--spec/requests/api/users_spec.rb15
-rw-r--r--spec/requests/ci/api/builds_spec.rb196
-rw-r--r--spec/requests/ci/api/commits_spec.rb2
-rw-r--r--spec/requests/ci/api/projects_spec.rb106
-rw-r--r--spec/requests/ci/api/triggers_spec.rb2
-rw-r--r--spec/services/ci/create_trigger_request_service_spec.rb2
-rw-r--r--spec/services/milestones/close_service_spec.rb28
-rw-r--r--spec/services/milestones/create_service_spec.rb24
-rw-r--r--spec/services/milestones/group_service_spec.rb70
-rw-r--r--spec/services/projects/create_service_spec.rb22
-rw-r--r--spec/services/projects/fork_service_spec.rb2
-rw-r--r--spec/tasks/gitlab/backup_rake_spec.rb14
54 files changed, 1672 insertions, 307 deletions
diff --git a/spec/controllers/admin/users_controller_spec.rb b/spec/controllers/admin/users_controller_spec.rb
index fcbe62cace8..8b7af4d3a0a 100644
--- a/spec/controllers/admin/users_controller_spec.rb
+++ b/spec/controllers/admin/users_controller_spec.rb
@@ -7,21 +7,6 @@ describe Admin::UsersController do
sign_in(admin)
end
- describe 'POST login_as' do
- let(:user) { create(:user) }
-
- it 'logs admin as another user' do
- expect(warden.authenticate(scope: :user)).not_to eq(user)
- post :login_as, id: user.username
- expect(warden.authenticate(scope: :user)).to eq(user)
- end
-
- it 'redirects user to homepage' do
- post :login_as, id: user.username
- expect(response).to redirect_to(root_path)
- end
- end
-
describe 'DELETE #user with projects' do
let(:user) { create(:user) }
let(:project) { create(:project, namespace: user.namespace) }
diff --git a/spec/controllers/projects/compare_controller_spec.rb b/spec/controllers/projects/compare_controller_spec.rb
index 2a447248b70..be19f1abc53 100644
--- a/spec/controllers/projects/compare_controller_spec.rb
+++ b/spec/controllers/projects/compare_controller_spec.rb
@@ -23,6 +23,22 @@ describe Projects::CompareController do
expect(assigns(:commits).length).to be >= 1
end
+ it 'compare should show some diffs with ignore whitespace change option' do
+ get(:show,
+ namespace_id: project.namespace.to_param,
+ project_id: project.to_param,
+ from: '08f22f25',
+ to: '66eceea0',
+ w: 1)
+
+ expect(response).to be_success
+ expect(assigns(:diffs).length).to be >= 1
+ expect(assigns(:commits).length).to be >= 1
+ # without whitespace option, there are more than 2 diff_splits
+ diff_splits = assigns(:diffs)[0].diff.split("\n")
+ expect(diff_splits.length).to be <= 2
+ end
+
describe 'non-existent refs' do
it 'invalid source ref' do
get(:show,
diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb
index b8db8591709..3e5e1fa87ae 100644
--- a/spec/controllers/projects/merge_requests_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests_controller_spec.rb
@@ -147,6 +147,34 @@ describe Projects::MergeRequestsController do
end
end
+ describe 'GET diffs with ignore_whitespace_change' do
+ def go(format: 'html')
+ get :diffs,
+ namespace_id: project.namespace.to_param,
+ project_id: project.to_param,
+ id: merge_request.iid,
+ format: format,
+ w: 1
+ end
+
+ context 'as html' do
+ it 'renders the diff template' do
+ go
+
+ expect(response).to render_template('diffs')
+ end
+ end
+
+ context 'as json' do
+ it 'renders the diffs template to a string' do
+ go format: 'json'
+
+ expect(response).to render_template('projects/merge_requests/show/_diffs')
+ expect(JSON.parse(response.body)).to have_key('html')
+ end
+ end
+ end
+
describe 'GET commits' do
def go(format: 'html')
get :commits,
diff --git a/spec/factories/ci/projects.rb b/spec/factories/ci/projects.rb
index 1183a190353..11cb8c9eeaa 100644
--- a/spec/factories/ci/projects.rb
+++ b/spec/factories/ci/projects.rb
@@ -31,16 +31,20 @@ FactoryGirl.define do
factory :ci_project_without_token, class: Ci::Project do
default_ref 'master'
- gl_project factory: :empty_project
-
shared_runners_enabled false
factory :ci_project do
token 'iPWx6WM4lhHNedGfBpPJNP'
end
- factory :ci_public_project do
- public true
+ initialize_with do
+ # TODO:
+ # this is required, because builds_enabled is initialized when Project is created
+ # and this create gitlab_ci_project if builds is set to true
+ # here we take created gitlab_ci_project and update it's attributes
+ ci_project = create(:empty_project).ensure_gitlab_ci_project
+ ci_project.update_attributes(attributes)
+ ci_project
end
end
end
diff --git a/spec/factories/labels.rb b/spec/factories/labels.rb
index 6829387c660..8b12ee11af5 100644
--- a/spec/factories/labels.rb
+++ b/spec/factories/labels.rb
@@ -8,6 +8,7 @@
# project_id :integer
# created_at :datetime
# updated_at :datetime
+# template :boolean default(FALSE)
#
# Read about factories at https://github.com/thoughtbot/factory_girl
diff --git a/spec/factories/lfs_objects.rb b/spec/factories/lfs_objects.rb
new file mode 100644
index 00000000000..7fb2d77ca32
--- /dev/null
+++ b/spec/factories/lfs_objects.rb
@@ -0,0 +1,12 @@
+# Read about factories at https://github.com/thoughtbot/factory_girl
+
+FactoryGirl.define do
+ factory :lfs_object do
+ oid "b68143e6463773b1b6c6fd009a76c32aeec041faff32ba2ed42fd7f708a17f80"
+ size 499013
+ end
+
+ trait :with_file do
+ file { fixture_file_upload(Rails.root + "spec/fixtures/dk.png", "`/png") }
+ end
+end
diff --git a/spec/factories/lfs_objects_projects.rb b/spec/factories/lfs_objects_projects.rb
new file mode 100644
index 00000000000..93de6607df8
--- /dev/null
+++ b/spec/factories/lfs_objects_projects.rb
@@ -0,0 +1,8 @@
+# Read about factories at https://github.com/thoughtbot/factory_girl
+
+FactoryGirl.define do
+ factory :lfs_objects_project do
+ lfs_object
+ project
+ end
+end
diff --git a/spec/factories/merge_requests.rb b/spec/factories/merge_requests.rb
index 6080d0ccdef..729a49c9f72 100644
--- a/spec/factories/merge_requests.rb
+++ b/spec/factories/merge_requests.rb
@@ -20,6 +20,7 @@
# position :integer default(0)
# locked_at :datetime
# updated_by_id :integer
+# merge_error :string(255)
#
FactoryGirl.define do
diff --git a/spec/factories/releases.rb b/spec/factories/releases.rb
new file mode 100644
index 00000000000..43d09b17534
--- /dev/null
+++ b/spec/factories/releases.rb
@@ -0,0 +1,21 @@
+# == Schema Information
+#
+# Table name: releases
+#
+# id :integer not null, primary key
+# tag :string(255)
+# description :text
+# project_id :integer
+# created_at :datetime
+# updated_at :datetime
+#
+
+# Read about factories at https://github.com/thoughtbot/factory_girl
+
+FactoryGirl.define do
+ factory :release do
+ tag "v1.1.0"
+ description "Awesome release"
+ project
+ end
+end
diff --git a/spec/features/admin/admin_users_spec.rb b/spec/features/admin/admin_users_spec.rb
index c2c7364f6c5..4c756a8e732 100644
--- a/spec/features/admin/admin_users_spec.rb
+++ b/spec/features/admin/admin_users_spec.rb
@@ -111,24 +111,50 @@ describe "Admin::Users", feature: true do
expect(page).to have_content(@user.name)
end
- describe 'Login as another user' do
- it 'should show login button for other users and check that it works' do
- another_user = create(:user)
+ describe 'Impersonation' do
+ let(:another_user) { create(:user) }
+ before { visit admin_user_path(another_user) }
- visit admin_user_path(another_user)
-
- click_link 'Log in as this user'
+ context 'before impersonating' do
+ it 'shows impersonate button for other users' do
+ expect(page).to have_content('Impersonate')
+ end
- expect(page).to have_content("Logged in as #{another_user.username}")
+ it 'should not show impersonate button for admin itself' do
+ visit admin_user_path(@user)
- page.within '.sidebar-user .username' do
- expect(page).to have_content(another_user.username)
+ expect(page).not_to have_content('Impersonate')
end
end
- it 'should not show login button for admin itself' do
- visit admin_user_path(@user)
- expect(page).not_to have_content('Log in as this user')
+ context 'when impersonating' do
+ before { click_link 'Impersonate' }
+
+ it 'logs in as the user when impersonate is clicked' do
+ page.within '.sidebar-user .username' do
+ expect(page).to have_content(another_user.username)
+ end
+ end
+
+ it 'sees impersonation log out icon' do
+ icon = first('.fa.fa-user-secret')
+
+ expect(icon).to_not eql nil
+ end
+
+ it 'can log out of impersonated user back to original user' do
+ find(:css, 'li.impersonation a').click
+
+ page.within '.sidebar-user .username' do
+ expect(page).to have_content(@user.username)
+ end
+ end
+
+ it 'is redirected back to the impersonated users page in the admin after stopping' do
+ find(:css, 'li.impersonation a').click
+
+ expect(current_path).to eql "/admin/users/#{another_user.username}"
+ end
end
end
diff --git a/spec/features/builds_spec.rb b/spec/features/builds_spec.rb
index 158e85e598f..5213ce1099f 100644
--- a/spec/features/builds_spec.rb
+++ b/spec/features/builds_spec.rb
@@ -1,6 +1,8 @@
require 'spec_helper'
describe "Builds" do
+ let(:artifacts_file) { fixture_file_upload(Rails.root + 'spec/fixtures/banana_sample.gif', 'image/gif') }
+
before do
login_as(:user)
@commit = FactoryGirl.create :ci_commit
@@ -66,6 +68,15 @@ describe "Builds" do
it { expect(page).to have_content @commit.sha[0..7] }
it { expect(page).to have_content @commit.git_commit_message }
it { expect(page).to have_content @commit.git_author_name }
+
+ context "Download artifacts" do
+ before do
+ @build.update_attributes(artifacts_file: artifacts_file)
+ visit namespace_project_build_path(@gl_project.namespace, @gl_project, @build)
+ end
+
+ it { expect(page).to have_content 'Download artifacts' }
+ end
end
describe "POST /:project/builds/:id/cancel" do
@@ -90,4 +101,14 @@ describe "Builds" do
it { expect(page).to have_content 'pending' }
it { expect(page).to have_content 'Cancel' }
end
+
+ describe "GET /:project/builds/:id/download" do
+ before do
+ @build.update_attributes(artifacts_file: artifacts_file)
+ visit namespace_project_build_path(@gl_project.namespace, @gl_project, @build)
+ click_link 'Download artifacts'
+ end
+
+ it { expect(page.response_headers['Content-Type']).to eq(artifacts_file.content_type) }
+ end
end
diff --git a/spec/features/commits_spec.rb b/spec/features/commits_spec.rb
index 340924fafe7..90739cd6a28 100644
--- a/spec/features/commits_spec.rb
+++ b/spec/features/commits_spec.rb
@@ -19,7 +19,7 @@ describe "Commits" do
stub_ci_commit_to_return_yaml_file
end
- describe "GET /:project/commits/:sha" do
+ describe "GET /:project/commits/:sha/ci" do
before do
visit ci_status_path(@commit)
end
@@ -29,6 +29,20 @@ describe "Commits" do
it { expect(page).to have_content @commit.git_author_name }
end
+ context "Download artifacts" do
+ let(:artifacts_file) { fixture_file_upload(Rails.root + 'spec/fixtures/banana_sample.gif', 'image/gif') }
+
+ before do
+ @build.update_attributes(artifacts_file: artifacts_file)
+ end
+
+ it do
+ visit ci_status_path(@commit)
+ click_on "Download artifacts"
+ expect(page.response_headers['Content-Type']).to eq(artifacts_file.content_type)
+ end
+ end
+
describe "Cancel all builds" do
it "cancels commit" do
visit ci_status_path(@commit)
diff --git a/spec/features/runners_spec.rb b/spec/features/runners_spec.rb
index 06adb7633b2..b0259026630 100644
--- a/spec/features/runners_spec.rb
+++ b/spec/features/runners_spec.rb
@@ -14,15 +14,25 @@ describe "Runners" do
@project2 = FactoryGirl.create :ci_project
@project2.gl_project.team << [user, :master]
+ @project3 = FactoryGirl.create :ci_project
+ @project3.gl_project.team << [user, :developer]
+
@shared_runner = FactoryGirl.create :ci_shared_runner
@specific_runner = FactoryGirl.create :ci_specific_runner
@specific_runner2 = FactoryGirl.create :ci_specific_runner
+ @specific_runner3 = FactoryGirl.create :ci_specific_runner
@project.runners << @specific_runner
@project2.runners << @specific_runner2
+ @project3.runners << @specific_runner3
visit runners_path(@project.gl_project)
end
+ before do
+ expect(page).to_not have_content(@specific_runner3.display_name)
+ expect(page).to_not have_content(@specific_runner3.display_name)
+ end
+
it "places runners in right places" do
expect(page.find(".available-specific-runners")).to have_content(@specific_runner2.display_name)
expect(page.find(".activated-specific-runners")).to have_content(@specific_runner.display_name)
@@ -76,10 +86,10 @@ describe "Runners" do
@project.gl_project.team << [user, :master]
@specific_runner = FactoryGirl.create :ci_specific_runner
@project.runners << @specific_runner
- visit runners_path(@project.gl_project)
end
it "shows runner information" do
+ visit runners_path(@project.gl_project)
click_on @specific_runner.short_sha
expect(page).to have_content(@specific_runner.platform)
end
diff --git a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb
index 9963f76f993..7d90f9877c6 100644
--- a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb
+++ b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb
@@ -333,6 +333,97 @@ module Ci
end
end
+ describe "Caches" do
+ it "returns cache when defined globally" do
+ config = YAML.dump({
+ cache: { paths: ["logs/", "binaries/"], untracked: true },
+ rspec: {
+ script: "rspec"
+ }
+ })
+
+ config_processor = GitlabCiYamlProcessor.new(config)
+
+ expect(config_processor.builds_for_stage_and_ref("test", "master").size).to eq(1)
+ expect(config_processor.builds_for_stage_and_ref("test", "master").first[:options][:cache]).to eq(
+ paths: ["logs/", "binaries/"],
+ untracked: true,
+ )
+ end
+
+ it "returns cache when defined in a job" do
+ config = YAML.dump({
+ rspec: {
+ cache: { paths: ["logs/", "binaries/"], untracked: true },
+ script: "rspec"
+ }
+ })
+
+ config_processor = GitlabCiYamlProcessor.new(config)
+
+ expect(config_processor.builds_for_stage_and_ref("test", "master").size).to eq(1)
+ expect(config_processor.builds_for_stage_and_ref("test", "master").first[:options][:cache]).to eq(
+ paths: ["logs/", "binaries/"],
+ untracked: true,
+ )
+ end
+
+ it "overwrite cache when defined for a job and globally" do
+ config = YAML.dump({
+ cache: { paths: ["logs/", "binaries/"], untracked: true },
+ rspec: {
+ script: "rspec",
+ cache: { paths: ["test/"], untracked: false },
+ }
+ })
+
+ config_processor = GitlabCiYamlProcessor.new(config)
+
+ expect(config_processor.builds_for_stage_and_ref("test", "master").size).to eq(1)
+ expect(config_processor.builds_for_stage_and_ref("test", "master").first[:options][:cache]).to eq(
+ paths: ["test/"],
+ untracked: false,
+ )
+ end
+ end
+
+ describe "Artifacts" do
+ it "returns artifacts when defined" do
+ config = YAML.dump({
+ image: "ruby:2.1",
+ services: ["mysql"],
+ before_script: ["pwd"],
+ rspec: {
+ artifacts: { paths: ["logs/", "binaries/"], untracked: true },
+ script: "rspec"
+ }
+ })
+
+ config_processor = GitlabCiYamlProcessor.new(config)
+
+ expect(config_processor.builds_for_stage_and_ref("test", "master").size).to eq(1)
+ expect(config_processor.builds_for_stage_and_ref("test", "master").first).to eq({
+ except: nil,
+ stage: "test",
+ stage_idx: 1,
+ name: :rspec,
+ only: nil,
+ commands: "pwd\nrspec",
+ tag_list: [],
+ options: {
+ image: "ruby:2.1",
+ services: ["mysql"],
+ artifacts: {
+ paths: ["logs/", "binaries/"],
+ untracked: true
+ }
+ },
+ when: "on_success",
+ allow_failure: false
+ })
+ end
+ end
+
describe "Error handling" do
it "indicates that object is invalid" do
expect{GitlabCiYamlProcessor.new("invalid_yaml\n!ccdvlf%612334@@@@")}.to raise_error(GitlabCiYamlProcessor::ValidationError)
@@ -491,6 +582,48 @@ module Ci
GitlabCiYamlProcessor.new(config, path)
end.to raise_error(GitlabCiYamlProcessor::ValidationError, "rspec job: when parameter should be on_success, on_failure or always")
end
+
+ it "returns errors if job artifacts:untracked is not an array of strings" do
+ config = YAML.dump({ types: ["build", "test"], rspec: { script: "test", artifacts: { untracked: "string" } } })
+ expect do
+ GitlabCiYamlProcessor.new(config)
+ end.to raise_error(GitlabCiYamlProcessor::ValidationError, "rspec job: artifacts:untracked parameter should be an boolean")
+ end
+
+ it "returns errors if job artifacts:paths is not an array of strings" do
+ config = YAML.dump({ types: ["build", "test"], rspec: { script: "test", artifacts: { paths: "string" } } })
+ expect do
+ GitlabCiYamlProcessor.new(config)
+ end.to raise_error(GitlabCiYamlProcessor::ValidationError, "rspec job: artifacts:paths parameter should be an array of strings")
+ end
+
+ it "returns errors if cache:untracked is not an array of strings" do
+ config = YAML.dump({ cache: { untracked: "string" }, rspec: { script: "test" } })
+ expect do
+ GitlabCiYamlProcessor.new(config)
+ end.to raise_error(GitlabCiYamlProcessor::ValidationError, "cache:untracked parameter should be an boolean")
+ end
+
+ it "returns errors if cache:paths is not an array of strings" do
+ config = YAML.dump({ cache: { paths: "string" }, rspec: { script: "test" } })
+ expect do
+ GitlabCiYamlProcessor.new(config)
+ end.to raise_error(GitlabCiYamlProcessor::ValidationError, "cache:paths parameter should be an array of strings")
+ end
+
+ it "returns errors if job cache:untracked is not an array of strings" do
+ config = YAML.dump({ types: ["build", "test"], rspec: { script: "test", cache: { untracked: "string" } } })
+ expect do
+ GitlabCiYamlProcessor.new(config)
+ end.to raise_error(GitlabCiYamlProcessor::ValidationError, "rspec job: cache:untracked parameter should be an boolean")
+ end
+
+ it "returns errors if job cache:paths is not an array of strings" do
+ config = YAML.dump({ types: ["build", "test"], rspec: { script: "test", cache: { paths: "string" } } })
+ expect do
+ GitlabCiYamlProcessor.new(config)
+ end.to raise_error(GitlabCiYamlProcessor::ValidationError, "rspec job: cache:paths parameter should be an array of strings")
+ end
end
end
end
diff --git a/spec/lib/gitlab/diff/inline_diff_spec.rb b/spec/lib/gitlab/inline_diff_spec.rb
index 2e0a05088cc..2e0a05088cc 100644
--- a/spec/lib/gitlab/diff/inline_diff_spec.rb
+++ b/spec/lib/gitlab/inline_diff_spec.rb
diff --git a/spec/lib/gitlab/lfs/lfs_router_spec.rb b/spec/lib/gitlab/lfs/lfs_router_spec.rb
new file mode 100644
index 00000000000..cebcb5bc887
--- /dev/null
+++ b/spec/lib/gitlab/lfs/lfs_router_spec.rb
@@ -0,0 +1,650 @@
+require 'spec_helper'
+
+describe Gitlab::Lfs::Router 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) }
+ let(:lfs_router_noauth) { new_lfs_router(project, nil) }
+ let(:lfs_router_public_auth) { new_lfs_router(public_project, user) }
+ let(:lfs_router_public_noauth) { new_lfs_router(public_project, nil) }
+ let(:lfs_router_forked_noauth) { new_lfs_router(forked_project, nil) }
+ let(:lfs_router_forked_auth) { new_lfs_router(forked_project, user_two) }
+
+ let(:sample_oid) { "b68143e6463773b1b6c6fd009a76c32aeec041faff32ba2ed42fd7f708a17f80" }
+ let(:sample_size) { 499013 }
+
+ describe 'when lfs is disabled' do
+ before do
+ allow(Gitlab.config.lfs).to receive(:enabled).and_return(false)
+ env["PATH_INFO"] = "#{project.repository.path_with_namespace}.git/info/lfs/objects/#{sample_oid}"
+ end
+
+ it 'responds with 501' do
+ respond_with_disabled = [ 501,
+ { "Content-Type"=>"application/vnd.git-lfs+json" },
+ ["{\"message\":\"Git LFS is not enabled on this GitLab server, contact your admin.\",\"documentation_url\":\"#{Gitlab.config.gitlab.url}/help\"}"]
+ ]
+ expect(lfs_router_auth.try_call).to match_array(respond_with_disabled)
+ 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/info/lfs/objects/#{sample_oid}"
+ end
+
+ describe 'when user is authenticated' do
+ context 'and user has project download access' do
+ before do
+ @auth = authorize(user)
+ env["HTTP_AUTHORIZATION"] = @auth
+ project.lfs_objects << lfs_object
+ 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 download hypermedia" do
+ json_response = ActiveSupport::JSON.decode(lfs_router_auth.try_call.last.first)
+
+ expect(json_response['_links']['download']['href']).to eq("#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}.git/gitlab-lfs/objects/#{sample_oid}")
+ expect(json_response['_links']['download']['header']).to eq("Authorization" => @auth, "Accept" => "application/vnd.git-lfs+json; charset=utf-8")
+ end
+ end
+
+ context 'and 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
+ end
+
+ describe 'when user is unauthenticated' do
+ context 'and user does not have download access' do
+ it "responds with status 401" do
+ expect(lfs_router_noauth.try_call.first).to eq(401)
+ end
+ end
+
+ context 'and user has download access' do
+ before do
+ project.team << [user, :master]
+ end
+
+ it "responds with status 401" do
+ expect(lfs_router_noauth.try_call.first).to eq(401)
+ end
+ end
+ end
+
+ describe 'and project is public' do
+ context 'and project has access to the lfs object' do
+ before do
+ public_project.lfs_objects << lfs_object
+ end
+
+ context 'and user is authenticated' do
+ it "responds with status 200 and sends download hypermedia" do
+ expect(lfs_router_public_auth.try_call.first).to eq(200)
+ json_response = ActiveSupport::JSON.decode(lfs_router_public_auth.try_call.last.first)
+
+ expect(json_response['_links']['download']['href']).to eq("#{Gitlab.config.gitlab.url}/#{public_project.path_with_namespace}.git/gitlab-lfs/objects/#{sample_oid}")
+ expect(json_response['_links']['download']['header']).to eq("Accept" => "application/vnd.git-lfs+json; charset=utf-8")
+ end
+ end
+
+ context 'and user is unauthenticated' do
+ it "responds with status 200 and sends download hypermedia" do
+ expect(lfs_router_public_noauth.try_call.first).to eq(200)
+ json_response = ActiveSupport::JSON.decode(lfs_router_public_noauth.try_call.last.first)
+
+ expect(json_response['_links']['download']['href']).to eq("#{Gitlab.config.gitlab.url}/#{public_project.path_with_namespace}.git/gitlab-lfs/objects/#{sample_oid}")
+ expect(json_response['_links']['download']['header']).to eq("Accept" => "application/vnd.git-lfs+json; charset=utf-8")
+ end
+ end
+ end
+
+ context 'and project does not have access to the lfs object' do
+ it "responds with status 404" do
+ expect(lfs_router_public_auth.try_call.first).to eq(404)
+ end
+ end
+ end
+
+ describe 'and request comes from gitlab-workhorse' do
+ before do
+ env["PATH_INFO"] = "#{project.repository.path_with_namespace}.git/gitlab-lfs/objects/#{sample_oid}"
+ end
+ 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
+ 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.lfs_objects << lfs_object
+ 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
+ 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
+
+ describe 'from a forked public project' do
+ before do
+ env['HTTP_ACCEPT'] = "application/vnd.git-lfs+json; charset=utf-8"
+ env["PATH_INFO"] = "#{forked_project.repository.path_with_namespace}.git/info/lfs/objects/#{sample_oid}"
+ end
+
+ context "when fetching a lfs object" do
+ context "and user has project download access" do
+ before do
+ public_project.lfs_objects << lfs_object
+ end
+
+ it "can download the lfs object" do
+ expect(lfs_router_forked_auth.try_call.first).to eq(200)
+ json_response = ActiveSupport::JSON.decode(lfs_router_forked_auth.try_call.last.first)
+
+ expect(json_response['_links']['download']['href']).to eq("#{Gitlab.config.gitlab.url}/#{forked_project.path_with_namespace}.git/gitlab-lfs/objects/#{sample_oid}")
+ expect(json_response['_links']['download']['header']).to eq("Accept" => "application/vnd.git-lfs+json; charset=utf-8")
+ end
+ end
+
+ context "and user is not authenticated but project is public" do
+ before do
+ public_project.lfs_objects << lfs_object
+ end
+
+ it "can download the lfs object" do
+ expect(lfs_router_forked_auth.try_call.first).to eq(200)
+ end
+ end
+
+ context "and user has project download access" do
+ before do
+ env["PATH_INFO"] = "#{forked_project.repository.path_with_namespace}.git/info/lfs/objects/91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897"
+ @auth = ActionController::HttpAuthentication::Basic.encode_credentials(user.username, user.password)
+ env["HTTP_AUTHORIZATION"] = @auth
+ lfs_object_two = create(:lfs_object, :with_file, oid: "91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897", size: 1575078)
+ public_project.lfs_objects << lfs_object_two
+ end
+
+ it "can get a lfs object that is not in the forked project" do
+ expect(lfs_router_forked_auth.try_call.first).to eq(200)
+
+ json_response = ActiveSupport::JSON.decode(lfs_router_forked_auth.try_call.last.first)
+ expect(json_response['_links']['download']['href']).to eq("#{Gitlab.config.gitlab.url}/#{forked_project.path_with_namespace}.git/gitlab-lfs/objects/91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897")
+ expect(json_response['_links']['download']['header']).to eq("Accept" => "application/vnd.git-lfs+json; charset=utf-8", "Authorization" => @auth)
+ end
+ end
+
+ context "and user has project download access" do
+ before do
+ env["PATH_INFO"] = "#{forked_project.repository.path_with_namespace}.git/info/lfs/objects/267c8b1d876743971e3a9978405818ff5ca731c4c870b06507619cd9b1847b6b"
+ lfs_object_three = create(:lfs_object, :with_file, oid: "267c8b1d876743971e3a9978405818ff5ca731c4c870b06507619cd9b1847b6b", size: 127192524)
+ project.lfs_objects << lfs_object_three
+ end
+
+ it "cannot get a lfs object that is not in the project" do
+ expect(lfs_router_forked_auth.try_call.first).to eq(404)
+ end
+ end
+ end
+ end
+ end
+
+ describe 'when initiating pushing of the lfs object' do
+ before do
+ enable_lfs
+ env['REQUEST_METHOD'] = 'POST'
+ env["PATH_INFO"] = "#{project.repository.path_with_namespace}.git/info/lfs/objects/batch"
+ end
+
+ describe 'when user is authenticated' do
+ before do
+ body = { 'objects' => [{
+ 'oid' => sample_oid,
+ 'size' => sample_size
+ }]
+ }.to_json
+ env['rack.input'] = StringIO.new(body)
+ end
+
+ describe 'when user has project push access' do
+ before do
+ @auth = authorize(user)
+ env["HTTP_AUTHORIZATION"] = @auth
+ project.team << [user, :master]
+ 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)).to_not include(project.id)
+ expect(lfs_object.projects.pluck(:id)).to include(public_project.id)
+ expect(response['objects'].first).to have_key('_links')
+ end
+ end
+
+ context 'when pushing a lfs object that does not exist' do
+ before do
+ body = {
+ '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['_links']['upload']['href']).to eq("#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}.git/gitlab-lfs/objects/91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897/1575078")
+ expect(response_body['objects'].first['_links']['upload']['header']).to eq("Authorization" => @auth)
+ end
+ end
+
+ context 'when pushing one new and one existing lfs object' do
+ before do
+ body = {
+ 'objects' => [
+ { 'oid' => '91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897',
+ 'size' => 1575078
+ },
+ { 'oid' => sample_oid,
+ 'size' => sample_size
+ }
+ ]
+ }.to_json
+ env['rack.input'] = StringIO.new(body)
+ public_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['_links']['upload']['href']).to eq("#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}.git/gitlab-lfs/objects/91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897/1575078")
+ expect(response_body['objects'].first['_links']['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(lfs_object.projects.pluck(:id)).to_not include(project.id)
+ expect(lfs_object.projects.pluck(:id)).to include(public_project.id)
+ expect(response_body['objects'].last).to have_key('_links')
+ 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
+ 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
+ end
+
+ describe 'when pushing a lfs object' do
+ before do
+ enable_lfs
+ env['REQUEST_METHOD'] = 'PUT'
+ end
+
+ describe 'to one project' do
+ describe 'when user has push access to the project' do
+ before do
+ project.team << [user, :master]
+ end
+
+ describe 'when user is authenticated' do
+ 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 'when user is unauthenticated' do
+ let(:lfs_router_noauth) { new_lfs_router(project, nil) }
+
+ 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 401' do
+ expect(lfs_router_noauth.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(project)
+ end
+
+ it 'responds with status 401' do
+ expect(lfs_router_noauth.try_call.first).to eq(401)
+ end
+ end
+
+ context 'and request is sent with a malformed headers' do
+ before do
+ env["PATH_INFO"] = "#{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(lfs_router_noauth.try_call).to eq(nil)
+ end
+ end
+ end
+ end
+
+ describe 'and user does not have push access' do
+ describe 'when user is authenticated' do
+ context 'and request is sent by gitlab-workhorse to authorize the request' do
+ before do
+ header_for_upload_authorize(project)
+ end
+
+ it 'responds with 403' do
+ expect(lfs_router_auth.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(project)
+ end
+
+ it 'responds with 403' do
+ expect(lfs_router_auth.try_call.first).to eq(403)
+ end
+ end
+ end
+
+ describe 'when user is unauthenticated' do
+ let(:lfs_router_noauth) { new_lfs_router(project, nil) }
+
+ context 'and request is sent by gitlab-workhorse to authorize the request' do
+ before do
+ header_for_upload_authorize(project)
+ end
+
+ it 'responds with 401' do
+ expect(lfs_router_noauth.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(project)
+ end
+
+ it 'responds with 401' do
+ expect(lfs_router_noauth.try_call.first).to eq(401)
+ end
+ end
+ end
+ end
+ end
+
+ describe "to a forked project" do
+ let(:forked_project) { fork_project(public_project, user) }
+
+ describe 'when user has push access to the project' do
+ before do
+ forked_project.team << [user_two, :master]
+ end
+
+ describe 'when user is authenticated' do
+ 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 'when user is unauthenticated' do
+ 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 401' do
+ expect(lfs_router_forked_noauth.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(forked_project)
+ end
+
+ it 'responds with status 401' do
+ expect(lfs_router_forked_noauth.try_call.first).to eq(401)
+ end
+ end
+ end
+ end
+
+ describe 'and user does not have push access' do
+ describe 'when user is authenticated' do
+ 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 403' do
+ expect(lfs_router_forked_auth.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(forked_project)
+ end
+
+ it 'responds with 403' do
+ expect(lfs_router_forked_auth.try_call.first).to eq(403)
+ end
+ end
+ end
+
+ describe 'when user is unauthenticated' do
+ 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 401' do
+ expect(lfs_router_forked_noauth.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(forked_project)
+ end
+
+ it 'responds with 401' do
+ expect(lfs_router_forked_noauth.try_call.first).to eq(401)
+ end
+ end
+ end
+ 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) }
+
+ 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)
+ Gitlab::Lfs::Router.new(project, user, 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
diff --git a/spec/models/application_setting_spec.rb b/spec/models/application_setting_spec.rb
index f01fe8bd398..dfbac7b4004 100644
--- a/spec/models/application_setting_spec.rb
+++ b/spec/models/application_setting_spec.rb
@@ -23,6 +23,10 @@
# after_sign_out_path :string(255)
# session_expire_delay :integer default(10080), not null
# import_sources :text
+# help_page_text :text
+# admin_notification_email :string(255)
+# shared_runners_enabled :boolean default(TRUE), not null
+# max_artifacts_size :integer default(100), not null
#
require 'spec_helper'
diff --git a/spec/models/build_spec.rb b/spec/models/build_spec.rb
index 7f5abb83ac2..839b4c6b16e 100644
--- a/spec/models/build_spec.rb
+++ b/spec/models/build_spec.rb
@@ -400,4 +400,19 @@ describe Ci::Build do
end
end
end
+
+ describe :download_url do
+ subject { build.download_url }
+
+ it "should be nil if artifact doesn't exist" do
+ build.update_attributes(artifacts_file: nil)
+ is_expected.to be_nil
+ end
+
+ it 'should be nil if artifact exist' do
+ gif = fixture_file_upload(Rails.root + 'spec/fixtures/banana_sample.gif', 'image/gif')
+ build.update_attributes(artifacts_file: gif)
+ is_expected.to_not be_nil
+ end
+ end
end
diff --git a/spec/models/ci/commit_spec.rb b/spec/models/ci/commit_spec.rb
index 44dbd083f06..a13f6458cac 100644
--- a/spec/models/ci/commit_spec.rb
+++ b/spec/models/ci/commit_spec.rb
@@ -1,18 +1,19 @@
# == Schema Information
#
-# Table name: commits
+# Table name: ci_commits
#
-# id :integer not null, primary key
-# project_id :integer
-# ref :string(255)
-# sha :string(255)
-# before_sha :string(255)
-# push_data :text
-# created_at :datetime
-# updated_at :datetime
-# tag :boolean default(FALSE)
-# yaml_errors :text
-# committed_at :datetime
+# id :integer not null, primary key
+# project_id :integer
+# ref :string(255)
+# sha :string(255)
+# before_sha :string(255)
+# push_data :text
+# created_at :datetime
+# updated_at :datetime
+# tag :boolean default(FALSE)
+# yaml_errors :text
+# committed_at :datetime
+# gl_project_id :integer
#
require 'spec_helper'
diff --git a/spec/models/ci/project_spec.rb b/spec/models/ci/project_spec.rb
index 490c6a67982..ac7e38bbcb0 100644
--- a/spec/models/ci/project_spec.rb
+++ b/spec/models/ci/project_spec.rb
@@ -1,9 +1,9 @@
# == Schema Information
#
-# Table name: projects
+# Table name: ci_projects
#
# id :integer not null, primary key
-# name :string(255) not null
+# name :string(255)
# timeout :integer default(3600), not null
# created_at :datetime
# updated_at :datetime
@@ -28,8 +28,8 @@
require 'spec_helper'
describe Ci::Project do
- let(:gl_project) { FactoryGirl.create :empty_project }
- let(:project) { FactoryGirl.create :ci_project, gl_project: gl_project }
+ let(:project) { FactoryGirl.create :ci_project }
+ let(:gl_project) { project.gl_project }
subject { project }
it { is_expected.to have_many(:runner_projects) }
@@ -194,18 +194,6 @@ describe Ci::Project do
end
end
- describe 'Project.parse' do
- let(:project) { FactoryGirl.create :project }
-
- subject { Ci::Project.parse(project) }
-
- it { is_expected.to be_valid }
- it { is_expected.to be_kind_of(Ci::Project) }
- it { expect(subject.name).to eq(project.name_with_namespace) }
- it { expect(subject.gitlab_id).to eq(project.id) }
- it { expect(subject.gitlab_url).to eq(project.web_url) }
- end
-
describe :repo_url_with_auth do
let(:project) { FactoryGirl.create :ci_project }
subject { project.repo_url_with_auth }
diff --git a/spec/models/ci/runner_project_spec.rb b/spec/models/ci/runner_project_spec.rb
index 0218d484130..37682c6ea0c 100644
--- a/spec/models/ci/runner_project_spec.rb
+++ b/spec/models/ci/runner_project_spec.rb
@@ -1,6 +1,6 @@
# == Schema Information
#
-# Table name: runner_projects
+# Table name: ci_runner_projects
#
# id :integer not null, primary key
# runner_id :integer not null
diff --git a/spec/models/ci/runner_spec.rb b/spec/models/ci/runner_spec.rb
index f8a51c29dc2..9a1233b9095 100644
--- a/spec/models/ci/runner_spec.rb
+++ b/spec/models/ci/runner_spec.rb
@@ -1,6 +1,6 @@
# == Schema Information
#
-# Table name: runners
+# Table name: ci_runners
#
# id :integer not null, primary key
# token :string(255)
diff --git a/spec/models/ci/service_spec.rb b/spec/models/ci/service_spec.rb
index 2df70e88888..36cda988eb4 100644
--- a/spec/models/ci/service_spec.rb
+++ b/spec/models/ci/service_spec.rb
@@ -1,6 +1,6 @@
# == Schema Information
#
-# Table name: services
+# Table name: ci_services
#
# id :integer not null, primary key
# type :string(255)
diff --git a/spec/models/ci/trigger_spec.rb b/spec/models/ci/trigger_spec.rb
index 19c14ef2da2..b8aa3c1e777 100644
--- a/spec/models/ci/trigger_spec.rb
+++ b/spec/models/ci/trigger_spec.rb
@@ -1,3 +1,15 @@
+# == Schema Information
+#
+# Table name: ci_triggers
+#
+# id :integer not null, primary key
+# token :string(255)
+# project_id :integer not null
+# deleted_at :datetime
+# created_at :datetime
+# updated_at :datetime
+#
+
require 'spec_helper'
describe Ci::Trigger do
diff --git a/spec/models/ci/variable_spec.rb b/spec/models/ci/variable_spec.rb
index d034a6c7b9f..a515f5881ff 100644
--- a/spec/models/ci/variable_spec.rb
+++ b/spec/models/ci/variable_spec.rb
@@ -1,6 +1,6 @@
# == Schema Information
#
-# Table name: variables
+# Table name: ci_variables
#
# id :integer not null, primary key
# project_id :integer not null
diff --git a/spec/models/ci/web_hook_spec.rb b/spec/models/ci/web_hook_spec.rb
index bf9481ab81d..2865482a212 100644
--- a/spec/models/ci/web_hook_spec.rb
+++ b/spec/models/ci/web_hook_spec.rb
@@ -1,6 +1,6 @@
# == Schema Information
#
-# Table name: web_hooks
+# Table name: ci_web_hooks
#
# id :integer not null, primary key
# url :string(255) not null
diff --git a/spec/models/commit_status_spec.rb b/spec/models/commit_status_spec.rb
index c96a606fdaa..dca0715eed8 100644
--- a/spec/models/commit_status_spec.rb
+++ b/spec/models/commit_status_spec.rb
@@ -1,3 +1,36 @@
+# == Schema Information
+#
+# Table name: ci_builds
+#
+# id :integer not null, primary key
+# project_id :integer
+# status :string(255)
+# finished_at :datetime
+# trace :text
+# created_at :datetime
+# updated_at :datetime
+# started_at :datetime
+# runner_id :integer
+# coverage :float
+# commit_id :integer
+# commands :text
+# job_id :integer
+# name :string(255)
+# deploy :boolean default(FALSE)
+# options :text
+# allow_failure :boolean default(FALSE), not null
+# stage :string(255)
+# trigger_request_id :integer
+# stage_idx :integer
+# tag :boolean
+# ref :string(255)
+# user_id :integer
+# type :string(255)
+# target_url :string(255)
+# description :string(255)
+# artifacts_file :text
+#
+
require 'spec_helper'
describe CommitStatus do
diff --git a/spec/models/generic_commit_status_spec.rb b/spec/models/generic_commit_status_spec.rb
index f442fa5fbe5..c86314c454c 100644
--- a/spec/models/generic_commit_status_spec.rb
+++ b/spec/models/generic_commit_status_spec.rb
@@ -1,3 +1,36 @@
+# == Schema Information
+#
+# Table name: ci_builds
+#
+# id :integer not null, primary key
+# project_id :integer
+# status :string(255)
+# finished_at :datetime
+# trace :text
+# created_at :datetime
+# updated_at :datetime
+# started_at :datetime
+# runner_id :integer
+# coverage :float
+# commit_id :integer
+# commands :text
+# job_id :integer
+# name :string(255)
+# deploy :boolean default(FALSE)
+# options :text
+# allow_failure :boolean default(FALSE), not null
+# stage :string(255)
+# trigger_request_id :integer
+# stage_idx :integer
+# tag :boolean
+# ref :string(255)
+# user_id :integer
+# type :string(255)
+# target_url :string(255)
+# description :string(255)
+# artifacts_file :text
+#
+
require 'spec_helper'
describe GenericCommitStatus do
diff --git a/spec/models/global_milestone_spec.rb b/spec/models/global_milestone_spec.rb
new file mode 100644
index 00000000000..6eeff30b20e
--- /dev/null
+++ b/spec/models/global_milestone_spec.rb
@@ -0,0 +1,65 @@
+require 'spec_helper'
+
+describe GlobalMilestone do
+ let(:user) { create(:user) }
+ let(:user2) { create(:user) }
+ let(:group) { create(:group) }
+ let(:project1) { create(:project, group: group) }
+ let(:project2) { create(:project, path: 'gitlab-ci', group: group) }
+ let(:project3) { create(:project, path: 'cookbook-gitlab', group: group) }
+ let(:milestone1_project1) { create(:milestone, title: "Milestone v1.2", project: project1) }
+ let(:milestone1_project2) { create(:milestone, title: "Milestone v1.2", project: project2) }
+ let(:milestone1_project3) { create(:milestone, title: "Milestone v1.2", project: project3) }
+ let(:milestone2_project1) { create(:milestone, title: "VD-123", project: project1) }
+ let(:milestone2_project2) { create(:milestone, title: "VD-123", project: project2) }
+ let(:milestone2_project3) { create(:milestone, title: "VD-123", project: project3) }
+
+ describe :build_collection do
+ before do
+ milestones =
+ [
+ milestone1_project1,
+ milestone1_project2,
+ milestone1_project3,
+ milestone2_project1,
+ milestone2_project2,
+ milestone2_project3
+ ]
+
+ @global_milestones = GlobalMilestone.build_collection(milestones)
+ end
+
+ it 'should have all project milestones' do
+ expect(@global_milestones.count).to eq(2)
+ end
+
+ it 'should have all project milestones titles' do
+ expect(@global_milestones.map(&:title)).to match_array(['Milestone v1.2', 'VD-123'])
+ end
+
+ it 'should have all project milestones' do
+ expect(@global_milestones.map { |group_milestone| group_milestone.milestones.count }.sum).to eq(6)
+ end
+ end
+
+ describe :initialize do
+ before do
+ milestones =
+ [
+ milestone1_project1,
+ milestone1_project2,
+ milestone1_project3,
+ ]
+
+ @global_milestone = GlobalMilestone.new(milestone1_project1.title, milestones)
+ end
+
+ it 'should have exactly one group milestone' do
+ expect(@global_milestone.title).to eq('Milestone v1.2')
+ end
+
+ it 'should have all project milestones with the same title' do
+ expect(@global_milestone.milestones.count).to eq(3)
+ end
+ end
+end
diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb
index 0f23e81ace9..bbfc5535eec 100644
--- a/spec/models/group_spec.rb
+++ b/spec/models/group_spec.rb
@@ -11,6 +11,7 @@
# type :string(255)
# description :string(255) default(""), not null
# avatar :string(255)
+# public :boolean default(FALSE)
#
require 'spec_helper'
diff --git a/spec/models/label_spec.rb b/spec/models/label_spec.rb
index 6518213d71c..511ee8cbd96 100644
--- a/spec/models/label_spec.rb
+++ b/spec/models/label_spec.rb
@@ -8,6 +8,7 @@
# project_id :integer
# created_at :datetime
# updated_at :datetime
+# template :boolean default(FALSE)
#
require 'spec_helper'
diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb
index eed2cbc5412..90af75ff0e3 100644
--- a/spec/models/merge_request_spec.rb
+++ b/spec/models/merge_request_spec.rb
@@ -20,6 +20,7 @@
# position :integer default(0)
# locked_at :datetime
# updated_by_id :integer
+# merge_error :string(255)
#
require 'spec_helper'
diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb
index 1d72a9503ae..a98b9cb7321 100644
--- a/spec/models/namespace_spec.rb
+++ b/spec/models/namespace_spec.rb
@@ -11,6 +11,7 @@
# type :string(255)
# description :string(255) default(""), not null
# avatar :string(255)
+# public :boolean default(FALSE)
#
require 'spec_helper'
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index f93935ebe3b..8d7e6e76766 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -415,12 +415,15 @@ describe Project do
it { expect(project.ci_commit(commit.sha)).to eq(commit) }
end
- describe :enable_ci do
+ describe :builds_enabled do
let(:project) { create :project }
- before { project.enable_ci }
+ before { project.builds_enabled = true }
- it { expect(project.gitlab_ci?).to be_truthy }
+ subject { project.builds_enabled }
+
+ it { is_expected.to eq(project.gitlab_ci_service.active) }
+ it { expect(project.builds_enabled?).to be_truthy }
it { expect(project.gitlab_ci_project).to be_a(Ci::Project) }
end
diff --git a/spec/models/project_wiki_spec.rb b/spec/models/project_wiki_spec.rb
index 9f6cdeeaa96..3b889144447 100644
--- a/spec/models/project_wiki_spec.rb
+++ b/spec/models/project_wiki_spec.rb
@@ -184,6 +184,12 @@ describe ProjectWiki do
subject.create_page("test page", "some content", :markdown, "commit message")
expect(subject.pages.first.page.version.message).to eq("commit message")
end
+
+ it 'updates project activity' do
+ expect(subject).to receive(:update_project_activity)
+
+ subject.create_page('Test Page', 'This is content')
+ end
end
describe "#update_page" do
@@ -205,6 +211,12 @@ describe ProjectWiki do
it "sets the correct commit message" do
expect(@page.version.message).to eq("updated page")
end
+
+ it 'updates project activity' do
+ expect(subject).to receive(:update_project_activity)
+
+ subject.update_page(@gollum_page, 'Yet more content', :markdown, 'Updated page again')
+ end
end
describe "#delete_page" do
@@ -217,6 +229,12 @@ describe ProjectWiki do
subject.delete_page(@page)
expect(subject.pages.count).to eq(0)
end
+
+ it 'updates project activity' do
+ expect(subject).to receive(:update_project_activity)
+
+ subject.delete_page(@page)
+ end
end
private
diff --git a/spec/models/release_spec.rb b/spec/models/release_spec.rb
new file mode 100644
index 00000000000..72ecb442a36
--- /dev/null
+++ b/spec/models/release_spec.rb
@@ -0,0 +1,28 @@
+# == Schema Information
+#
+# Table name: releases
+#
+# id :integer not null, primary key
+# tag :string(255)
+# description :text
+# project_id :integer
+# created_at :datetime
+# updated_at :datetime
+#
+
+require 'rails_helper'
+
+RSpec.describe Release, type: :model do
+ let(:release) { create(:release) }
+
+ it { expect(release).to be_valid }
+
+ describe 'associations' do
+ it { is_expected.to belong_to(:project) }
+ end
+
+ describe 'validation' do
+ it { is_expected.to validate_presence_of(:project) }
+ it { is_expected.to validate_presence_of(:description) }
+ end
+end
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 49e0bfdd2ec..7d716c23120 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -54,6 +54,8 @@
# public_email :string(255) default(""), not null
# dashboard :integer default(0)
# project_view :integer default(0)
+# consumed_timestep :integer
+# layout :integer default(0)
#
require 'spec_helper'
diff --git a/spec/requests/api/commit_status_spec.rb b/spec/requests/api/commit_status_spec.rb
index b9e6dfc15a7..a28607bd240 100644
--- a/spec/requests/api/commit_status_spec.rb
+++ b/spec/requests/api/commit_status_spec.rb
@@ -18,7 +18,7 @@ describe API::API, api: true do
before do
@status1 = create(:commit_status, commit: ci_commit, status: 'running')
@status2 = create(:commit_status, commit: ci_commit, name: 'coverage', status: 'pending')
- @status3 = create(:commit_status, commit: ci_commit, name: 'coverage', ref: 'develop', status: 'running')
+ @status3 = create(:commit_status, commit: ci_commit, name: 'coverage', ref: 'develop', status: 'running', allow_failure: true)
@status4 = create(:commit_status, commit: ci_commit, name: 'coverage', status: 'success')
@status5 = create(:commit_status, commit: ci_commit, ref: 'develop', status: 'success')
@status6 = create(:commit_status, commit: ci_commit, status: 'success')
@@ -30,6 +30,8 @@ describe API::API, api: true do
expect(json_response).to be_an Array
expect(statuses_id).to contain_exactly(@status3.id, @status4.id, @status5.id, @status6.id)
+ json_response.sort_by!{ |status| status['id'] }
+ expect(json_response.map{ |status| status['allow_failure'] }).to eq([true, false, false, false])
end
it "should return all commit statuses" do
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index e9de9e0826d..9fc294118ae 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -88,8 +88,11 @@ describe API::API, api: true do
end
it 'returns projects in the correct order when ci_enabled_first parameter is passed' do
- [project, project2, project3].each{ |project| project.build_missing_services }
- project2.gitlab_ci_service.update(active: true)
+ [project, project2, project3].each do |project|
+ project.builds_enabled = false
+ project.build_missing_services
+ end
+ project2.builds_enabled = true
get api('/projects', user), { ci_enabled_first: 'true' }
expect(response.status).to eq(200)
expect(json_response).to be_an Array
diff --git a/spec/requests/api/repositories_spec.rb b/spec/requests/api/repositories_spec.rb
index faf6b77a462..4911cdd9da6 100644
--- a/spec/requests/api/repositories_spec.rb
+++ b/spec/requests/api/repositories_spec.rb
@@ -11,81 +11,6 @@ describe API::API, api: true do
let!(:master) { create(:project_member, user: user, project: project, access_level: ProjectMember::MASTER) }
let!(:guest) { create(:project_member, user: user2, project: project, access_level: ProjectMember::GUEST) }
- describe "GET /projects/:id/repository/tags" do
- it "should return an array of project tags" do
- get api("/projects/#{project.id}/repository/tags", user)
- expect(response.status).to eq(200)
- expect(json_response).to be_an Array
- expect(json_response.first['name']).to eq(project.repo.tags.sort_by(&:name).reverse.first.name)
- end
- end
-
- describe 'POST /projects/:id/repository/tags' do
- context 'lightweight tags' do
- it 'should create a new tag' do
- post api("/projects/#{project.id}/repository/tags", user),
- tag_name: 'v7.0.1',
- ref: 'master'
-
- expect(response.status).to eq(201)
- expect(json_response['name']).to eq('v7.0.1')
- end
- end
-
- context 'annotated tag' do
- it 'should create a new annotated tag' do
- # Identity must be set in .gitconfig to create annotated tag.
- repo_path = project.repository.path_to_repo
- system(*%W(#{Gitlab.config.git.bin_path} --git-dir=#{repo_path} config user.name #{user.name}))
- system(*%W(#{Gitlab.config.git.bin_path} --git-dir=#{repo_path} config user.email #{user.email}))
-
- post api("/projects/#{project.id}/repository/tags", user),
- tag_name: 'v7.1.0',
- ref: 'master',
- message: 'Release 7.1.0'
-
- expect(response.status).to eq(201)
- expect(json_response['name']).to eq('v7.1.0')
- expect(json_response['message']).to eq('Release 7.1.0')
- end
- end
-
- it 'should deny for user without push access' do
- post api("/projects/#{project.id}/repository/tags", user2),
- tag_name: 'v1.9.0',
- ref: '621491c677087aa243f165eab467bfdfbee00be1'
- expect(response.status).to eq(403)
- end
-
- it 'should return 400 if tag name is invalid' do
- post api("/projects/#{project.id}/repository/tags", user),
- tag_name: 'v 1.0.0',
- ref: 'master'
- expect(response.status).to eq(400)
- expect(json_response['message']).to eq('Tag name invalid')
- end
-
- it 'should return 400 if tag already exists' do
- post api("/projects/#{project.id}/repository/tags", user),
- tag_name: 'v8.0.0',
- ref: 'master'
- expect(response.status).to eq(201)
- post api("/projects/#{project.id}/repository/tags", user),
- tag_name: 'v8.0.0',
- ref: 'master'
- expect(response.status).to eq(400)
- expect(json_response['message']).to eq('Tag already exists')
- end
-
- it 'should return 400 if ref name is invalid' do
- post api("/projects/#{project.id}/repository/tags", user),
- tag_name: 'mytag',
- ref: 'foo'
- expect(response.status).to eq(400)
- expect(json_response['message']).to eq('Invalid reference name')
- end
- end
-
describe "GET /projects/:id/repository/tree" do
context "authorized user" do
before { project.team << [user2, :reporter] }
diff --git a/spec/requests/api/services_spec.rb b/spec/requests/api/services_spec.rb
index c0226605a23..b180d2fec77 100644
--- a/spec/requests/api/services_spec.rb
+++ b/spec/requests/api/services_spec.rb
@@ -46,6 +46,7 @@ describe API::API, api: true do
delete api("/projects/#{project.id}/services/#{dashed_service}", user)
expect(response.status).to eq(200)
+ project.send(service_method).reload
expect(project.send(service_method).activated?).to be_falsey
end
end
diff --git a/spec/requests/api/tags_spec.rb b/spec/requests/api/tags_spec.rb
new file mode 100644
index 00000000000..cc9a5f47582
--- /dev/null
+++ b/spec/requests/api/tags_spec.rb
@@ -0,0 +1,135 @@
+require 'spec_helper'
+require 'mime/types'
+
+describe API::API, api: true do
+ include ApiHelpers
+ include RepoHelpers
+
+ let(:user) { create(:user) }
+ let(:user2) { create(:user) }
+ let!(:project) { create(:project, creator_id: user.id) }
+ let!(:master) { create(:project_member, user: user, project: project, access_level: ProjectMember::MASTER) }
+ let!(:guest) { create(:project_member, user: user2, project: project, access_level: ProjectMember::GUEST) }
+
+ describe "GET /projects/:id/repository/tags" do
+ let(:tag_name) { project.repository.tag_names.sort.reverse.first }
+ let(:description) { 'Awesome release!' }
+
+ context 'without releases' do
+ it "should return an array of project tags" do
+ get api("/projects/#{project.id}/repository/tags", user)
+ expect(response.status).to eq(200)
+ expect(json_response).to be_an Array
+ expect(json_response.first['name']).to eq(tag_name)
+ end
+ end
+
+ context 'with releases' do
+ before do
+ release = project.releases.find_or_initialize_by(tag: tag_name)
+ release.update_attributes(description: description)
+ get api("/projects/#{project.id}/repository/tags", user)
+ end
+
+ it "should return an array of project tags with release info" do
+ expect(response.status).to eq(200)
+ expect(json_response).to be_an Array
+ expect(json_response.first['name']).to eq(tag_name)
+ expect(json_response.first['release']['description']).to eq(description)
+ end
+ end
+ end
+
+ describe 'POST /projects/:id/repository/tags' do
+ context 'lightweight tags' do
+ it 'should create a new tag' do
+ post api("/projects/#{project.id}/repository/tags", user),
+ tag_name: 'v7.0.1',
+ ref: 'master'
+
+ expect(response.status).to eq(201)
+ expect(json_response['name']).to eq('v7.0.1')
+ end
+ end
+
+ context 'lightweight tags with release notes' do
+ it 'should create a new tag' do
+ post api("/projects/#{project.id}/repository/tags", user),
+ tag_name: 'v7.0.1',
+ ref: 'master',
+ release_description: 'Wow'
+
+ expect(response.status).to eq(201)
+ expect(json_response['name']).to eq('v7.0.1')
+ expect(json_response['release']['description']).to eq('Wow')
+ end
+ end
+
+ context 'annotated tag' do
+ it 'should create a new annotated tag' do
+ # Identity must be set in .gitconfig to create annotated tag.
+ repo_path = project.repository.path_to_repo
+ system(*%W(#{Gitlab.config.git.bin_path} --git-dir=#{repo_path} config user.name #{user.name}))
+ system(*%W(#{Gitlab.config.git.bin_path} --git-dir=#{repo_path} config user.email #{user.email}))
+
+ post api("/projects/#{project.id}/repository/tags", user),
+ tag_name: 'v7.1.0',
+ ref: 'master',
+ message: 'Release 7.1.0'
+
+ expect(response.status).to eq(201)
+ expect(json_response['name']).to eq('v7.1.0')
+ expect(json_response['message']).to eq('Release 7.1.0')
+ end
+ end
+
+ it 'should deny for user without push access' do
+ post api("/projects/#{project.id}/repository/tags", user2),
+ tag_name: 'v1.9.0',
+ ref: '621491c677087aa243f165eab467bfdfbee00be1'
+ expect(response.status).to eq(403)
+ end
+
+ it 'should return 400 if tag name is invalid' do
+ post api("/projects/#{project.id}/repository/tags", user),
+ tag_name: 'v 1.0.0',
+ ref: 'master'
+ expect(response.status).to eq(400)
+ expect(json_response['message']).to eq('Tag name invalid')
+ end
+
+ it 'should return 400 if tag already exists' do
+ post api("/projects/#{project.id}/repository/tags", user),
+ tag_name: 'v8.0.0',
+ ref: 'master'
+ expect(response.status).to eq(201)
+ post api("/projects/#{project.id}/repository/tags", user),
+ tag_name: 'v8.0.0',
+ ref: 'master'
+ expect(response.status).to eq(400)
+ expect(json_response['message']).to eq('Tag already exists')
+ end
+
+ it 'should return 400 if ref name is invalid' do
+ post api("/projects/#{project.id}/repository/tags", user),
+ tag_name: 'mytag',
+ ref: 'foo'
+ expect(response.status).to eq(400)
+ expect(json_response['message']).to eq('Invalid reference name')
+ end
+ end
+
+ describe 'PUT /projects/:id/repository/:tag/release' do
+ let(:tag_name) { project.repository.tag_names.first }
+ let(:description) { 'Awesome release!' }
+
+ it 'should create description for existing git tag' do
+ put api("/projects/#{project.id}/repository/#{tag_name}/release", user),
+ description: description
+
+ expect(response.status).to eq(200)
+ expect(json_response['tag']).to eq(tag_name)
+ expect(json_response['description']).to eq(description)
+ end
+ end
+end
diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb
index d26a300ed82..a9ef2fe5885 100644
--- a/spec/requests/api/users_spec.rb
+++ b/spec/requests/api/users_spec.rb
@@ -343,8 +343,9 @@ describe API::API, api: true do
end.to change{ user.keys.count }.by(1)
end
- it "should raise error for invalid ID" do
- expect{post api("/users/ASDF/keys", admin) }.to raise_error(ActionController::RoutingError)
+ it "should return 405 for invalid ID" do
+ post api("/users/ASDF/keys", admin)
+ expect(response.status).to eq(405)
end
end
@@ -374,9 +375,9 @@ describe API::API, api: true do
expect(json_response.first['title']).to eq(key.title)
end
- it "should return 404 for invalid ID" do
+ it "should return 405 for invalid ID" do
get api("/users/ASDF/keys", admin)
- expect(response.status).to eq(404)
+ expect(response.status).to eq(405)
end
end
end
@@ -434,7 +435,8 @@ describe API::API, api: true do
end
it "should raise error for invalid ID" do
- expect{post api("/users/ASDF/emails", admin) }.to raise_error(ActionController::RoutingError)
+ post api("/users/ASDF/emails", admin)
+ expect(response.status).to eq(405)
end
end
@@ -465,7 +467,8 @@ describe API::API, api: true do
end
it "should raise error for invalid ID" do
- expect{put api("/users/ASDF/emails", admin) }.to raise_error(ActionController::RoutingError)
+ put api("/users/ASDF/emails", admin)
+ expect(response.status).to eq(405)
end
end
end
diff --git a/spec/requests/ci/api/builds_spec.rb b/spec/requests/ci/api/builds_spec.rb
index 88218a93e1f..c2be045099d 100644
--- a/spec/requests/ci/api/builds_spec.rb
+++ b/spec/requests/ci/api/builds_spec.rb
@@ -5,7 +5,7 @@ describe Ci::API::API do
let(:runner) { FactoryGirl.create(:ci_runner, tag_list: ["mysql", "ruby"]) }
let(:project) { FactoryGirl.create(:ci_project) }
- let(:gl_project) { FactoryGirl.create(:empty_project, gitlab_ci_project: project) }
+ let(:gl_project) { project.gl_project }
before do
stub_ci_commit_to_return_yaml_file
@@ -14,7 +14,7 @@ describe Ci::API::API do
describe "Builds API for runners" do
let(:shared_runner) { FactoryGirl.create(:ci_runner, token: "SharedRunner") }
let(:shared_project) { FactoryGirl.create(:ci_project, name: "SharedProject") }
- let(:shared_gl_project) { FactoryGirl.create(:empty_project, gitlab_ci_project: shared_project) }
+ let(:shared_gl_project) { shared_project.gl_project }
before do
FactoryGirl.create :ci_runner_project, project_id: project.id, runner_id: runner.id
@@ -41,7 +41,7 @@ describe Ci::API::API do
it "should return 404 error if no builds for specific runner" do
commit = FactoryGirl.create(:ci_commit, gl_project: shared_gl_project)
- FactoryGirl.create(:ci_build, commit: commit, status: 'pending' )
+ FactoryGirl.create(:ci_build, commit: commit, status: 'pending')
post ci_api("/builds/register"), token: runner.token
@@ -50,7 +50,7 @@ describe Ci::API::API do
it "should return 404 error if no builds for shared runner" do
commit = FactoryGirl.create(:ci_commit, gl_project: gl_project)
- FactoryGirl.create(:ci_build, commit: commit, status: 'pending' )
+ FactoryGirl.create(:ci_build, commit: commit, status: 'pending')
post ci_api("/builds/register"), token: shared_runner.token
@@ -79,7 +79,7 @@ describe Ci::API::API do
{ "key" => "CI_BUILD_NAME", "value" => "spinach", "public" => true },
{ "key" => "CI_BUILD_STAGE", "value" => "test", "public" => true },
{ "key" => "DB_NAME", "value" => "postgres", "public" => true },
- { "key" => "SECRET_KEY", "value" => "secret_value", "public" => false },
+ { "key" => "SECRET_KEY", "value" => "secret_value", "public" => false }
])
end
@@ -122,5 +122,191 @@ describe Ci::API::API do
expect(build.reload.trace).to eq 'hello_world'
end
end
+
+ context "Artifacts" do
+ let(:file_upload) { fixture_file_upload(Rails.root + 'spec/fixtures/banana_sample.gif', 'image/gif') }
+ let(:file_upload2) { fixture_file_upload(Rails.root + 'spec/fixtures/dk.png', 'image/gif') }
+ let(:commit) { FactoryGirl.create(:ci_commit, gl_project: gl_project) }
+ let(:build) { FactoryGirl.create(:ci_build, commit: commit, runner_id: runner.id) }
+ let(:authorize_url) { ci_api("/builds/#{build.id}/artifacts/authorize") }
+ let(:post_url) { ci_api("/builds/#{build.id}/artifacts") }
+ let(:delete_url) { ci_api("/builds/#{build.id}/artifacts") }
+ let(:get_url) { ci_api("/builds/#{build.id}/artifacts") }
+ let(:headers) { { "GitLab-Workhorse" => "1.0" } }
+ let(:headers_with_token) { headers.merge(Ci::API::Helpers::BUILD_TOKEN_HEADER => build.project.token) }
+
+ describe "POST /builds/:id/artifacts/authorize" do
+ context "should authorize posting artifact to running build" do
+ before do
+ build.run!
+ end
+
+ it "using token as parameter" do
+ post authorize_url, { token: build.project.token }, headers
+ expect(response.status).to eq(200)
+ expect(json_response["TempPath"]).to_not be_nil
+ end
+
+ it "using token as header" do
+ post authorize_url, {}, headers_with_token
+ expect(response.status).to eq(200)
+ expect(json_response["TempPath"]).to_not be_nil
+ end
+ end
+
+ context "should fail to post too large artifact" do
+ before do
+ build.run!
+ end
+
+ it "using token as parameter" do
+ stub_application_setting(max_artifacts_size: 0)
+ post authorize_url, { token: build.project.token, filesize: 100 }, headers
+ expect(response.status).to eq(413)
+ end
+
+ it "using token as header" do
+ stub_application_setting(max_artifacts_size: 0)
+ post authorize_url, { filesize: 100 }, headers_with_token
+ expect(response.status).to eq(413)
+ end
+ end
+
+ context "should get denied" do
+ it do
+ post authorize_url, { token: 'invalid', filesize: 100 }
+ expect(response.status).to eq(403)
+ end
+ end
+ end
+
+ describe "POST /builds/:id/artifacts" do
+ context "Disable sanitizer" do
+ before do
+ # by configuring this path we allow to pass temp file from any path
+ allow(ArtifactUploader).to receive(:artifacts_upload_path).and_return('/')
+ end
+
+ context "should post artifact to running build" do
+ before do
+ build.run!
+ end
+
+ it "uses regual file post" do
+ upload_artifacts(file_upload, headers_with_token, false)
+ expect(response.status).to eq(201)
+ expect(json_response["artifacts_file"]["filename"]).to eq(file_upload.original_filename)
+ end
+
+ it "uses accelerated file post" do
+ upload_artifacts(file_upload, headers_with_token, true)
+ expect(response.status).to eq(201)
+ expect(json_response["artifacts_file"]["filename"]).to eq(file_upload.original_filename)
+ end
+
+ it "updates artifact" do
+ upload_artifacts(file_upload, headers_with_token)
+ upload_artifacts(file_upload2, headers_with_token)
+ expect(response.status).to eq(201)
+ expect(json_response["artifacts_file"]["filename"]).to eq(file_upload2.original_filename)
+ end
+ end
+
+ context "should fail to post too large artifact" do
+ before do
+ build.run!
+ end
+
+ it do
+ stub_application_setting(max_artifacts_size: 0)
+ upload_artifacts(file_upload, headers_with_token)
+ expect(response.status).to eq(413)
+ end
+ end
+
+ context "should fail to post artifacts without file" do
+ before do
+ build.run!
+ end
+
+ it do
+ post post_url, {}, headers_with_token
+ expect(response.status).to eq(400)
+ end
+ end
+
+ context "should fail to post artifacts without GitLab-Workhorse" do
+ before do
+ build.run!
+ end
+
+ it do
+ post post_url, { token: build.project.token }, {}
+ expect(response.status).to eq(403)
+ end
+ end
+ end
+
+ context "should fail to post artifacts for outside of tmp path" do
+ before do
+ # by configuring this path we allow to pass file from @tmpdir only
+ # but all temporary files are stored in system tmp directory
+ @tmpdir = Dir.mktmpdir
+ allow(ArtifactUploader).to receive(:artifacts_upload_path).and_return(@tmpdir)
+ build.run!
+ end
+
+ after do
+ FileUtils.remove_entry @tmpdir
+ end
+
+ it do
+ upload_artifacts(file_upload, headers_with_token)
+ expect(response.status).to eq(400)
+ end
+ end
+
+ def upload_artifacts(file, headers = {}, accelerated = true)
+ if accelerated
+ post post_url, {
+ 'file.path' => file.path,
+ 'file.name' => file.original_filename
+ }, headers
+ else
+ post post_url, { file: file }, headers
+ end
+ end
+ end
+
+ describe "DELETE /builds/:id/artifacts" do
+ before do
+ build.run!
+ post delete_url, token: build.project.token, file: file_upload
+ end
+
+ it "should delete artifact build" do
+ build.success
+ delete delete_url, token: build.project.token
+ expect(response.status).to eq(200)
+ end
+ end
+
+ describe "GET /builds/:id/artifacts" do
+ before do
+ build.run!
+ end
+
+ it "should download artifact" do
+ build.update_attributes(artifacts_file: file_upload)
+ get get_url, token: build.project.token
+ expect(response.status).to eq(200)
+ end
+
+ it "should fail to download if no artifact uploaded" do
+ get get_url, token: build.project.token
+ expect(response.status).to eq(404)
+ end
+ end
+ end
end
end
diff --git a/spec/requests/ci/api/commits_spec.rb b/spec/requests/ci/api/commits_spec.rb
index 6049135fd10..aa51ba95bca 100644
--- a/spec/requests/ci/api/commits_spec.rb
+++ b/spec/requests/ci/api/commits_spec.rb
@@ -4,7 +4,7 @@ describe Ci::API::API, 'Commits' do
include ApiHelpers
let(:project) { FactoryGirl.create(:ci_project) }
- let(:gl_project) { FactoryGirl.create(:empty_project, gitlab_ci_project: project) }
+ let(:gl_project) { project.gl_project }
let(:commit) { FactoryGirl.create(:ci_commit, gl_project: gl_project) }
let(:options) do
diff --git a/spec/requests/ci/api/projects_spec.rb b/spec/requests/ci/api/projects_spec.rb
index 53f7f91cc1f..893fd168d3e 100644
--- a/spec/requests/ci/api/projects_spec.rb
+++ b/spec/requests/ci/api/projects_spec.rb
@@ -41,8 +41,8 @@ describe Ci::API::API do
describe "GET /projects/owned" do
let!(:gl_project1) {FactoryGirl.create(:empty_project, namespace: user.namespace)}
let!(:gl_project2) {FactoryGirl.create(:empty_project, namespace: user.namespace)}
- let!(:project1) { FactoryGirl.create(:ci_project, gl_project: gl_project1) }
- let!(:project2) { FactoryGirl.create(:ci_project, gl_project: gl_project2) }
+ let!(:project1) { gl_project1.ensure_gitlab_ci_project }
+ let!(:project2) { gl_project2.ensure_gitlab_ci_project }
before do
project1.gl_project.team << [user, :developer]
@@ -180,87 +180,53 @@ describe Ci::API::API do
end
end
- describe "POST /projects" do
- let(:gl_project) { FactoryGirl.create :empty_project }
- let(:project_info) do
- {
- gitlab_id: gl_project.id
- }
- end
-
- let(:invalid_project_info) { {} }
+ describe "POST /projects/:id/runners/:id" do
+ let(:project) { FactoryGirl.create(:ci_project) }
+ let(:runner) { FactoryGirl.create(:ci_runner) }
- context "with valid project info" do
- before do
- options.merge!(project_info)
- end
+ it "should add the project to the runner" do
+ project.gl_project.team << [user, :master]
+ post ci_api("/projects/#{project.id}/runners/#{runner.id}"), options
+ expect(response.status).to eq(201)
- it "should create a project with valid data" do
- post ci_api("/projects"), options
- expect(response.status).to eq(201)
- expect(json_response['name']).to eq(gl_project.name_with_namespace)
- end
+ project.reload
+ expect(project.runners.first.id).to eq(runner.id)
end
- context "with invalid project info" do
- before do
- options.merge!(invalid_project_info)
- end
+ it "should fail if it tries to link a non-existing project or runner" do
+ post ci_api("/projects/#{project.id}/runners/non-existing"), options
+ expect(response.status).to eq(404)
- it "should error with invalid data" do
- post ci_api("/projects"), options
- expect(response.status).to eq(400)
- end
+ post ci_api("/projects/non-existing/runners/#{runner.id}"), options
+ expect(response.status).to eq(404)
end
- describe "POST /projects/:id/runners/:id" do
- let(:project) { FactoryGirl.create(:ci_project) }
- let(:runner) { FactoryGirl.create(:ci_runner) }
-
- it "should add the project to the runner" do
- project.gl_project.team << [user, :master]
- post ci_api("/projects/#{project.id}/runners/#{runner.id}"), options
- expect(response.status).to eq(201)
-
- project.reload
- expect(project.runners.first.id).to eq(runner.id)
- end
-
- it "should fail if it tries to link a non-existing project or runner" do
- post ci_api("/projects/#{project.id}/runners/non-existing"), options
- expect(response.status).to eq(404)
-
- post ci_api("/projects/non-existing/runners/#{runner.id}"), options
- expect(response.status).to eq(404)
- end
-
- it "non-manager is not authorized" do
- allow_any_instance_of(User).to receive(:can_manage_project?).and_return(false)
- post ci_api("/projects/#{project.id}/runners/#{runner.id}"), options
- expect(response.status).to eq(401)
- end
+ it "non-manager is not authorized" do
+ allow_any_instance_of(User).to receive(:can_manage_project?).and_return(false)
+ post ci_api("/projects/#{project.id}/runners/#{runner.id}"), options
+ expect(response.status).to eq(401)
end
+ end
- describe "DELETE /projects/:id/runners/:id" do
- let(:project) { FactoryGirl.create(:ci_project) }
- let(:runner) { FactoryGirl.create(:ci_runner) }
+ describe "DELETE /projects/:id/runners/:id" do
+ let(:project) { FactoryGirl.create(:ci_project) }
+ let(:runner) { FactoryGirl.create(:ci_runner) }
- it "should remove the project from the runner" do
- project.gl_project.team << [user, :master]
- post ci_api("/projects/#{project.id}/runners/#{runner.id}"), options
+ it "should remove the project from the runner" do
+ project.gl_project.team << [user, :master]
+ post ci_api("/projects/#{project.id}/runners/#{runner.id}"), options
- expect(project.runners).to be_present
- delete ci_api("/projects/#{project.id}/runners/#{runner.id}"), options
- expect(response.status).to eq(200)
+ expect(project.runners).to be_present
+ delete ci_api("/projects/#{project.id}/runners/#{runner.id}"), options
+ expect(response.status).to eq(200)
- project.reload
- expect(project.runners).to be_empty
- end
+ project.reload
+ expect(project.runners).to be_empty
+ end
- it "non-manager is not authorized" do
- delete ci_api("/projects/#{project.id}/runners/#{runner.id}"), options
- expect(response.status).to eq(401)
- end
+ it "non-manager is not authorized" do
+ delete ci_api("/projects/#{project.id}/runners/#{runner.id}"), options
+ expect(response.status).to eq(401)
end
end
end
diff --git a/spec/requests/ci/api/triggers_spec.rb b/spec/requests/ci/api/triggers_spec.rb
index 93617fc4b3f..a2b436d5811 100644
--- a/spec/requests/ci/api/triggers_spec.rb
+++ b/spec/requests/ci/api/triggers_spec.rb
@@ -6,7 +6,7 @@ describe Ci::API::API do
describe 'POST /projects/:project_id/refs/:ref/trigger' do
let!(:trigger_token) { 'secure token' }
let!(:gl_project) { FactoryGirl.create(:project) }
- let!(:project) { FactoryGirl.create(:ci_project, gl_project: gl_project) }
+ let!(:project) { gl_project.ensure_gitlab_ci_project }
let!(:project2) { FactoryGirl.create(:ci_project) }
let!(:trigger) { FactoryGirl.create(:ci_trigger, project: project, token: trigger_token) }
let(:options) do
diff --git a/spec/services/ci/create_trigger_request_service_spec.rb b/spec/services/ci/create_trigger_request_service_spec.rb
index fcafae38644..2ef4bb50a57 100644
--- a/spec/services/ci/create_trigger_request_service_spec.rb
+++ b/spec/services/ci/create_trigger_request_service_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe Ci::CreateTriggerRequestService do
let(:service) { Ci::CreateTriggerRequestService.new }
let(:gl_project) { create(:project) }
- let(:project) { create(:ci_project, gl_project: gl_project) }
+ let(:project) { gl_project.ensure_gitlab_ci_project }
let(:trigger) { create(:ci_trigger, project: project) }
before do
diff --git a/spec/services/milestones/close_service_spec.rb b/spec/services/milestones/close_service_spec.rb
new file mode 100644
index 00000000000..034c0f22e12
--- /dev/null
+++ b/spec/services/milestones/close_service_spec.rb
@@ -0,0 +1,28 @@
+require 'spec_helper'
+
+describe Milestones::CloseService do
+ let(:user) { create(:user) }
+ let(:project) { create(:project) }
+ let(:milestone) { create(:milestone, title: "Milestone v1.2", project: project) }
+
+ before do
+ project.team << [user, :master]
+ end
+
+ describe :execute do
+ before do
+ Milestones::CloseService.new(project, user, {}).execute(milestone)
+ end
+
+ it { expect(milestone).to be_valid }
+ it { expect(milestone).to be_closed }
+
+ describe :event do
+ let(:event) { Event.first }
+
+ it { expect(event.milestone).to be_truthy }
+ it { expect(event.target).to eq(milestone) }
+ it { expect(event.action_name).to eq('closed') }
+ end
+ end
+end
diff --git a/spec/services/milestones/create_service_spec.rb b/spec/services/milestones/create_service_spec.rb
new file mode 100644
index 00000000000..757c9a226d8
--- /dev/null
+++ b/spec/services/milestones/create_service_spec.rb
@@ -0,0 +1,24 @@
+require 'spec_helper'
+
+describe Milestones::CreateService do
+ let(:project) { create(:empty_project) }
+ let(:user) { create(:user) }
+
+ describe :execute do
+ context "valid params" do
+ before do
+ project.team << [user, :master]
+
+ opts = {
+ title: 'v2.1.9',
+ description: 'Patch release to fix security issue'
+ }
+
+ @milestone = Milestones::CreateService.new(project, user, opts).execute
+ end
+
+ it { expect(@milestone).to be_valid }
+ it { expect(@milestone.title).to eq('v2.1.9') }
+ end
+ end
+end
diff --git a/spec/services/milestones/group_service_spec.rb b/spec/services/milestones/group_service_spec.rb
deleted file mode 100644
index 74eb0f99e0f..00000000000
--- a/spec/services/milestones/group_service_spec.rb
+++ /dev/null
@@ -1,70 +0,0 @@
-require 'spec_helper'
-
-describe Milestones::GroupService do
- let(:user) { create(:user) }
- let(:user2) { create(:user) }
- let(:group) { create(:group) }
- let(:project1) { create(:project, group: group) }
- let(:project2) { create(:project, path: 'gitlab-ci', group: group) }
- let(:project3) { create(:project, path: 'cookbook-gitlab', group: group) }
- let(:milestone1_project1) { create(:milestone, title: "Milestone v1.2", project: project1) }
- let(:milestone1_project2) { create(:milestone, title: "Milestone v1.2", project: project2) }
- let(:milestone1_project3) { create(:milestone, title: "Milestone v1.2", project: project3) }
- let(:milestone2_project1) { create(:milestone, title: "VD-123", project: project1) }
- let(:milestone2_project2) { create(:milestone, title: "VD-123", project: project2) }
- let(:milestone2_project3) { create(:milestone, title: "VD-123", project: project3) }
-
- describe 'execute' do
- context 'with valid projects' do
- before do
- milestones =
- [
- milestone1_project1,
- milestone1_project2,
- milestone1_project3,
- milestone2_project1,
- milestone2_project2,
- milestone2_project3
- ]
- @group_milestones = Milestones::GroupService.new(milestones).execute
- end
-
- it 'should have all project milestones' do
- expect(@group_milestones.count).to eq(2)
- end
-
- it 'should have all project milestones titles' do
- expect(@group_milestones.map { |group_milestone| group_milestone.title }).to match_array(['Milestone v1.2', 'VD-123'])
- end
-
- it 'should have all project milestones' do
- expect(@group_milestones.map { |group_milestone| group_milestone.milestones.count }.sum).to eq(6)
- end
- end
- end
-
- describe 'milestone' do
- context 'with valid title' do
- before do
- milestones =
- [
- milestone1_project1,
- milestone1_project2,
- milestone1_project3,
- milestone2_project1,
- milestone2_project2,
- milestone2_project3
- ]
- @group_milestones = Milestones::GroupService.new(milestones).milestone('Milestone v1.2')
- end
-
- it 'should have exactly one group milestone' do
- expect(@group_milestones.title).to eq('Milestone v1.2')
- end
-
- it 'should have all project milestones with the same title' do
- expect(@group_milestones.milestones.count).to eq(3)
- end
- end
- end
-end
diff --git a/spec/services/projects/create_service_spec.rb b/spec/services/projects/create_service_spec.rb
index 25277f07482..e81c4edb7d8 100644
--- a/spec/services/projects/create_service_spec.rb
+++ b/spec/services/projects/create_service_spec.rb
@@ -70,6 +70,28 @@ describe Projects::CreateService do
end
end
+ context 'builds_enabled global setting' do
+ let(:project) { create_project(@user, @opts) }
+
+ subject { project.builds_enabled? }
+
+ context 'global builds_enabled false does not enable CI by default' do
+ before do
+ @opts.merge!(builds_enabled: false)
+ end
+
+ it { is_expected.to be_falsey }
+ end
+
+ context 'global builds_enabled true does enable CI by default' do
+ before do
+ @opts.merge!(builds_enabled: true)
+ end
+
+ it { is_expected.to be_truthy }
+ end
+ end
+
context 'restricted visibility level' do
before do
stub_application_setting(restricted_visibility_levels: [Gitlab::VisibilityLevel::PUBLIC])
diff --git a/spec/services/projects/fork_service_spec.rb b/spec/services/projects/fork_service_spec.rb
index 65a8c81204d..e397b2b9b4a 100644
--- a/spec/services/projects/fork_service_spec.rb
+++ b/spec/services/projects/fork_service_spec.rb
@@ -46,7 +46,7 @@ describe Projects::ForkService do
it "fork and enable CI for fork" do
@from_project.enable_ci
@to_project = fork_project(@from_project, @to_user)
- expect(@to_project.gitlab_ci?).to be_truthy
+ expect(@to_project.builds_enabled?).to be_truthy
end
end
end
diff --git a/spec/tasks/gitlab/backup_rake_spec.rb b/spec/tasks/gitlab/backup_rake_spec.rb
index 386ac9c8372..06559c3925d 100644
--- a/spec/tasks/gitlab/backup_rake_spec.rb
+++ b/spec/tasks/gitlab/backup_rake_spec.rb
@@ -16,7 +16,7 @@ describe 'gitlab:app namespace rake task' do
end
def reenable_backup_sub_tasks
- %w{db repo uploads builds}.each do |subtask|
+ %w{db repo uploads builds artifacts}.each do |subtask|
Rake::Task["gitlab:backup:#{subtask}:create"].reenable
end
end
@@ -56,6 +56,7 @@ describe 'gitlab:app namespace rake task' do
expect(Rake::Task["gitlab:backup:repo:restore"]).to receive(:invoke)
expect(Rake::Task["gitlab:backup:builds:restore"]).to receive(:invoke)
expect(Rake::Task["gitlab:backup:uploads:restore"]).to receive(:invoke)
+ expect(Rake::Task["gitlab:backup:artifacts:restore"]).to receive(:invoke)
expect(Rake::Task["gitlab:shell:setup"]).to receive(:invoke)
expect { run_rake_task('gitlab:backup:restore') }.not_to raise_error
end
@@ -113,19 +114,20 @@ describe 'gitlab:app namespace rake task' do
it 'should set correct permissions on the tar contents' do
tar_contents, exit_status = Gitlab::Popen.popen(
- %W{tar -tvf #{@backup_tar} db uploads.tar.gz repositories builds.tar.gz}
+ %W{tar -tvf #{@backup_tar} db uploads.tar.gz repositories builds.tar.gz artifacts.tar.gz}
)
expect(exit_status).to eq(0)
expect(tar_contents).to match('db/')
expect(tar_contents).to match('uploads.tar.gz')
expect(tar_contents).to match('repositories/')
expect(tar_contents).to match('builds.tar.gz')
- expect(tar_contents).not_to match(/^.{4,9}[rwx].* (database.sql.gz|uploads.tar.gz|repositories|builds.tar.gz)\/$/)
+ expect(tar_contents).to match('artifacts.tar.gz')
+ expect(tar_contents).not_to match(/^.{4,9}[rwx].* (database.sql.gz|uploads.tar.gz|repositories|builds.tar.gz|artifacts.tar.gz)\/$/)
end
it 'should delete temp directories' do
temp_dirs = Dir.glob(
- File.join(Gitlab.config.backup.path, '{db,repositories,uploads,builds}')
+ File.join(Gitlab.config.backup.path, '{db,repositories,uploads,builds,artifacts}')
)
expect(temp_dirs).to be_empty
@@ -161,12 +163,13 @@ describe 'gitlab:app namespace rake task' do
it "does not contain skipped item" do
tar_contents, _exit_status = Gitlab::Popen.popen(
- %W{tar -tvf #{@backup_tar} db uploads.tar.gz repositories builds.tar.gz}
+ %W{tar -tvf #{@backup_tar} db uploads.tar.gz repositories builds.tar.gz artifacts.tar.gz}
)
expect(tar_contents).to match('db/')
expect(tar_contents).to match('uploads.tar.gz')
expect(tar_contents).to match('builds.tar.gz')
+ expect(tar_contents).to match('artifacts.tar.gz')
expect(tar_contents).not_to match('repositories/')
end
@@ -178,6 +181,7 @@ describe 'gitlab:app namespace rake task' do
expect(Rake::Task["gitlab:backup:db:restore"]).to receive :invoke
expect(Rake::Task["gitlab:backup:repo:restore"]).not_to receive :invoke
expect(Rake::Task["gitlab:backup:builds:restore"]).to receive :invoke
+ expect(Rake::Task["gitlab:backup:artifacts:restore"]).to receive :invoke
expect(Rake::Task["gitlab:shell:setup"]).to receive :invoke
expect { run_rake_task('gitlab:backup:restore') }.not_to raise_error
end