summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/profiles/keys_controller_spec.rb10
-rw-r--r--spec/controllers/projects/branches_controller_spec.rb23
-rw-r--r--spec/controllers/projects/graphs_controller_spec.rb10
-rw-r--r--spec/controllers/projects/notes_controller_spec.rb27
-rw-r--r--spec/features/profile_spec.rb14
-rw-r--r--spec/features/projects/services/mattermost_slash_command_spec.rb42
-rw-r--r--spec/initializers/8_metrics_spec.rb (renamed from spec/initializers/metrics_spec.rb)2
-rw-r--r--spec/lib/gitlab/etag_caching/middleware_spec.rb163
-rw-r--r--spec/lib/gitlab/import_export/all_models.yml1
-rw-r--r--spec/lib/gitlab/import_export/safe_model_attributes.yml2
-rw-r--r--spec/lib/mattermost/team_spec.rb6
-rw-r--r--spec/models/ci/trigger_spec.rb14
-rw-r--r--spec/models/note_spec.rb12
-rw-r--r--spec/models/project_services/mattermost_slash_commands_service_spec.rb2
-rw-r--r--spec/models/user_spec.rb1
-rw-r--r--spec/requests/api/triggers_spec.rb147
-rw-r--r--spec/requests/api/v3/triggers_spec.rb171
-rw-r--r--spec/routing/project_routing_spec.rb18
-rw-r--r--spec/services/ci/create_trigger_request_service_spec.rb18
-rw-r--r--spec/services/projects/update_pages_service_spec.rb22
-rw-r--r--spec/tasks/gitlab/backup_rake_spec.rb21
21 files changed, 631 insertions, 95 deletions
diff --git a/spec/controllers/profiles/keys_controller_spec.rb b/spec/controllers/profiles/keys_controller_spec.rb
index f7219690722..61e4fae46fb 100644
--- a/spec/controllers/profiles/keys_controller_spec.rb
+++ b/spec/controllers/profiles/keys_controller_spec.rb
@@ -3,16 +3,6 @@ require 'spec_helper'
describe Profiles::KeysController do
let(:user) { create(:user) }
- describe '#new' do
- before { sign_in(user) }
-
- it 'redirects to #index' do
- get :new
-
- expect(response).to redirect_to(profile_keys_path)
- end
- end
-
describe "#get_keys" do
describe "non existant user" do
it "does not generally work" do
diff --git a/spec/controllers/projects/branches_controller_spec.rb b/spec/controllers/projects/branches_controller_spec.rb
index e70737376af..298a7ff179c 100644
--- a/spec/controllers/projects/branches_controller_spec.rb
+++ b/spec/controllers/projects/branches_controller_spec.rb
@@ -244,4 +244,27 @@ describe Projects::BranchesController do
end
end
end
+
+ describe "GET index" do
+ render_views
+
+ before do
+ sign_in(user)
+ end
+
+ context 'when rendering a JSON format' do
+ it 'filters branches by name' do
+ get :index,
+ namespace_id: project.namespace,
+ project_id: project,
+ format: :json,
+ search: 'master'
+
+ parsed_response = JSON.parse(response.body)
+
+ expect(parsed_response.length).to eq 1
+ expect(parsed_response.first).to eq 'master'
+ end
+ end
+ end
end
diff --git a/spec/controllers/projects/graphs_controller_spec.rb b/spec/controllers/projects/graphs_controller_spec.rb
index 049bae1899d..e0de62e4454 100644
--- a/spec/controllers/projects/graphs_controller_spec.rb
+++ b/spec/controllers/projects/graphs_controller_spec.rb
@@ -30,18 +30,18 @@ describe Projects::GraphsController do
double(languages: {
'Ruby' => 1000,
'CoffeeScript' => 350,
- 'PowerShell' => 15
+ 'NSIS' => 15
})
end
let(:expected_values) do
- ps_color = "##{Digest::SHA256.hexdigest('PowerShell')[0...6]}"
+ nsis_color = "##{Digest::SHA256.hexdigest('NSIS')[0...6]}"
[
# colors from Linguist:
- { label: "Ruby", color: "#701516", highlight: "#701516" },
- { label: "CoffeeScript", color: "#244776", highlight: "#244776" },
+ { label: "Ruby", color: "#701516", highlight: "#701516" },
+ { label: "CoffeeScript", color: "#244776", highlight: "#244776" },
# colors from SHA256 fallback:
- { label: "PowerShell", color: ps_color, highlight: ps_color }
+ { label: "NSIS", color: nsis_color, highlight: nsis_color }
]
end
diff --git a/spec/controllers/projects/notes_controller_spec.rb b/spec/controllers/projects/notes_controller_spec.rb
index dc597202050..d80780b1d90 100644
--- a/spec/controllers/projects/notes_controller_spec.rb
+++ b/spec/controllers/projects/notes_controller_spec.rb
@@ -200,4 +200,31 @@ describe Projects::NotesController do
end
end
end
+
+ describe 'GET index' do
+ let(:last_fetched_at) { '1487756246' }
+ let(:request_params) do
+ {
+ namespace_id: project.namespace,
+ project_id: project,
+ target_type: 'issue',
+ target_id: issue.id
+ }
+ end
+
+ before do
+ sign_in(user)
+ project.team << [user, :developer]
+ end
+
+ it 'passes last_fetched_at from headers to NotesFinder' do
+ request.headers['X-Last-Fetched-At'] = last_fetched_at
+
+ expect(NotesFinder).to receive(:new)
+ .with(anything, anything, hash_including(last_fetched_at: last_fetched_at))
+ .and_call_original
+
+ get :index, request_params
+ end
+ end
end
diff --git a/spec/features/profile_spec.rb b/spec/features/profile_spec.rb
index 406d7cf791c..e63feb14b7e 100644
--- a/spec/features/profile_spec.rb
+++ b/spec/features/profile_spec.rb
@@ -61,4 +61,18 @@ describe 'Profile account page', feature: true do
expect(find('#incoming-email-token').value).not_to eq(previous_token)
end
end
+
+ describe 'when I change my username' do
+ before do
+ visit profile_account_path
+ end
+
+ it 'changes my username' do
+ fill_in 'user_username', with: 'new-username'
+
+ click_button('Update username')
+
+ expect(page).to have_content('new-username')
+ end
+ end
end
diff --git a/spec/features/projects/services/mattermost_slash_command_spec.rb b/spec/features/projects/services/mattermost_slash_command_spec.rb
index f5adb53a2dc..24d22a092d4 100644
--- a/spec/features/projects/services/mattermost_slash_command_spec.rb
+++ b/spec/features/projects/services/mattermost_slash_command_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-feature 'Setup Mattermost slash commands', feature: true do
+feature 'Setup Mattermost slash commands', :feature, :js do
let(:user) { create(:user) }
let(:project) { create(:empty_project) }
let(:service) { project.create_mattermost_slash_commands_service }
@@ -62,11 +62,11 @@ feature 'Setup Mattermost slash commands', feature: true do
click_link 'Add to Mattermost'
- team_name = teams.first[1]['display_name']
- select_element = find('select#mattermost_team_id')
+ team_name = teams.first['display_name']
+ select_element = find('#mattermost_team_id')
selected_option = select_element.find('option[selected]')
- expect(select_element['disabled']).to eq('disabled')
+ expect(select_element['disabled']).to be(true)
expect(selected_option).to have_content(team_name.to_s)
end
@@ -75,7 +75,7 @@ feature 'Setup Mattermost slash commands', feature: true do
click_link 'Add to Mattermost'
- expect(find('input#mattermost_team_id', visible: false).value).to eq(teams.first[0].to_s)
+ expect(find('input#mattermost_team_id', visible: false).value).to eq(teams.first['id'])
end
it 'shows an explanation user is a member of multiple teams' do
@@ -92,12 +92,9 @@ feature 'Setup Mattermost slash commands', feature: true do
click_link 'Add to Mattermost'
- select_element = find('select#mattermost_team_id')
- selected_option = select_element.find('option[selected]')
+ select_element = find('#mattermost_team_id')
- expect(select_element['disabled']).to be(nil)
- expect(selected_option).to have_content('Select team...')
- # The 'Select team...' placeholder is item `0`.
+ expect(select_element['disabled']).to be(false)
expect(select_element.all('option').count).to eq(3)
end
@@ -110,20 +107,37 @@ feature 'Setup Mattermost slash commands', feature: true do
expect(page).to have_content('test mattermost error message')
end
+ it 'enables the submit button if the required fields are provided', :js do
+ stub_teams(count: 1)
+
+ click_link 'Add to Mattermost'
+
+ expect(find('input[type="submit"]')['disabled']).not_to be(true)
+ end
+
+ it 'disables the submit button if the required fields are not provided', :js do
+ stub_teams(count: 1)
+
+ click_link 'Add to Mattermost'
+
+ fill_in('mattermost_trigger', with: '')
+
+ expect(find('input[type="submit"]')['disabled']).to be(true)
+ end
+
def stub_teams(count: 0)
teams = create_teams(count)
- allow_any_instance_of(MattermostSlashCommandsService).to receive(:list_teams) { teams }
+ allow_any_instance_of(MattermostSlashCommandsService).to receive(:list_teams) { [teams, nil] }
teams
end
def create_teams(count = 0)
- teams = {}
+ teams = []
count.times do |i|
- i += 1
- teams[i] = { id: i, display_name: i }
+ teams.push({ "id" => "x#{i}", "display_name" => "x#{i}-name" })
end
teams
diff --git a/spec/initializers/metrics_spec.rb b/spec/initializers/8_metrics_spec.rb
index bb595162370..570754621f3 100644
--- a/spec/initializers/metrics_spec.rb
+++ b/spec/initializers/8_metrics_spec.rb
@@ -1,5 +1,5 @@
require 'spec_helper'
-require_relative '../../config/initializers/metrics'
+require_relative '../../config/initializers/8_metrics'
describe 'instrument_classes', lib: true do
let(:config) { double(:config) }
diff --git a/spec/lib/gitlab/etag_caching/middleware_spec.rb b/spec/lib/gitlab/etag_caching/middleware_spec.rb
new file mode 100644
index 00000000000..8b5bfc4dbb0
--- /dev/null
+++ b/spec/lib/gitlab/etag_caching/middleware_spec.rb
@@ -0,0 +1,163 @@
+require 'spec_helper'
+
+describe Gitlab::EtagCaching::Middleware do
+ let(:app) { double(:app) }
+ let(:middleware) { described_class.new(app) }
+ let(:app_status_code) { 200 }
+ let(:if_none_match) { nil }
+ let(:enabled_path) { '/gitlab-org/gitlab-ce/noteable/issue/1/notes' }
+
+ context 'when ETag caching is not enabled for current route' do
+ let(:path) { '/gitlab-org/gitlab-ce/tree/master/noteable/issue/1/notes' }
+
+ before do
+ mock_app_response
+ end
+
+ it 'does not add ETag header' do
+ _, headers, _ = middleware.call(build_env(path, if_none_match))
+
+ expect(headers['ETag']).to be_nil
+ end
+
+ it 'passes status code from app' do
+ status, _, _ = middleware.call(build_env(path, if_none_match))
+
+ expect(status).to eq app_status_code
+ end
+ end
+
+ context 'when there is no ETag in store for given resource' do
+ let(:path) { enabled_path }
+
+ before do
+ mock_app_response
+ mock_value_in_store(nil)
+ end
+
+ it 'generates ETag' do
+ expect_any_instance_of(Gitlab::EtagCaching::Store)
+ .to receive(:touch).and_return('123')
+
+ middleware.call(build_env(path, if_none_match))
+ end
+
+ context 'when If-None-Match header was specified' do
+ let(:if_none_match) { 'W/"abc"' }
+
+ it 'tracks "etag_caching_key_not_found" event' do
+ expect(Gitlab::Metrics).to receive(:add_event)
+ .with(:etag_caching_middleware_used)
+ expect(Gitlab::Metrics).to receive(:add_event)
+ .with(:etag_caching_key_not_found)
+
+ middleware.call(build_env(path, if_none_match))
+ end
+ end
+ end
+
+ context 'when there is ETag in store for given resource' do
+ let(:path) { enabled_path }
+
+ before do
+ mock_app_response
+ mock_value_in_store('123')
+ end
+
+ it 'returns this value as header' do
+ _, headers, _ = middleware.call(build_env(path, if_none_match))
+
+ expect(headers['ETag']).to eq 'W/"123"'
+ end
+ end
+
+ context 'when If-None-Match header matches ETag in store' do
+ let(:path) { enabled_path }
+ let(:if_none_match) { 'W/"123"' }
+
+ before do
+ mock_value_in_store('123')
+ end
+
+ it 'does not call app' do
+ expect(app).not_to receive(:call)
+
+ middleware.call(build_env(path, if_none_match))
+ end
+
+ it 'returns status code 304' do
+ status, _, _ = middleware.call(build_env(path, if_none_match))
+
+ expect(status).to eq 304
+ end
+
+ it 'tracks "etag_caching_cache_hit" event' do
+ expect(Gitlab::Metrics).to receive(:add_event)
+ .with(:etag_caching_middleware_used)
+ expect(Gitlab::Metrics).to receive(:add_event)
+ .with(:etag_caching_cache_hit)
+
+ middleware.call(build_env(path, if_none_match))
+ end
+ end
+
+ context 'when If-None-Match header does not match ETag in store' do
+ let(:path) { enabled_path }
+ let(:if_none_match) { 'W/"abc"' }
+
+ before do
+ mock_value_in_store('123')
+ end
+
+ it 'calls app' do
+ expect(app).to receive(:call).and_return([app_status_code, {}, ['body']])
+
+ middleware.call(build_env(path, if_none_match))
+ end
+
+ it 'tracks "etag_caching_resource_changed" event' do
+ mock_app_response
+
+ expect(Gitlab::Metrics).to receive(:add_event)
+ .with(:etag_caching_middleware_used)
+ expect(Gitlab::Metrics).to receive(:add_event)
+ .with(:etag_caching_resource_changed)
+
+ middleware.call(build_env(path, if_none_match))
+ end
+ end
+
+ context 'when If-None-Match header is not specified' do
+ let(:path) { enabled_path }
+
+ before do
+ mock_value_in_store('123')
+ mock_app_response
+ end
+
+ it 'tracks "etag_caching_header_missing" event' do
+ expect(Gitlab::Metrics).to receive(:add_event)
+ .with(:etag_caching_middleware_used)
+ expect(Gitlab::Metrics).to receive(:add_event)
+ .with(:etag_caching_header_missing)
+
+ middleware.call(build_env(path, if_none_match))
+ end
+ end
+
+ def mock_app_response
+ allow(app).to receive(:call).and_return([app_status_code, {}, ['body']])
+ end
+
+ def mock_value_in_store(value)
+ allow_any_instance_of(Gitlab::EtagCaching::Store)
+ .to receive(:get).and_return(value)
+ end
+
+ def build_env(path, if_none_match)
+ {
+ 'PATH_INFO' => path,
+ 'HTTP_IF_NONE_MATCH' => if_none_match
+ }
+ end
+end
diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml
index eef283c2460..f20b6be51e1 100644
--- a/spec/lib/gitlab/import_export/all_models.yml
+++ b/spec/lib/gitlab/import_export/all_models.yml
@@ -97,6 +97,7 @@ variables:
triggers:
- project
- trigger_requests
+- owner
deploy_keys:
- user
- deploy_keys_projects
diff --git a/spec/lib/gitlab/import_export/safe_model_attributes.yml b/spec/lib/gitlab/import_export/safe_model_attributes.yml
index 6534902b52d..3bd1f335a89 100644
--- a/spec/lib/gitlab/import_export/safe_model_attributes.yml
+++ b/spec/lib/gitlab/import_export/safe_model_attributes.yml
@@ -240,6 +240,8 @@ Ci::Trigger:
- created_at
- updated_at
- gl_project_id
+- owner_id
+- description
DeployKey:
- id
- user_id
diff --git a/spec/lib/mattermost/team_spec.rb b/spec/lib/mattermost/team_spec.rb
index 6a9c7cebfff..ac493fdb20f 100644
--- a/spec/lib/mattermost/team_spec.rb
+++ b/spec/lib/mattermost/team_spec.rb
@@ -13,7 +13,7 @@ describe Mattermost::Team do
context 'for valid request' do
let(:response) do
- [{
+ { "xiyro8huptfhdndadpz8r3wnbo" => {
"id" => "xiyro8huptfhdndadpz8r3wnbo",
"create_at" => 1482174222155,
"update_at" => 1482174222155,
@@ -26,7 +26,7 @@ describe Mattermost::Team do
"allowed_domains" => "",
"invite_id" => "o4utakb9jtb7imctdfzbf9r5ro",
"allow_open_invite" => false
- }]
+ } }
end
before do
@@ -39,7 +39,7 @@ describe Mattermost::Team do
end
it 'returns a token' do
- is_expected.to eq(response)
+ is_expected.to eq(response.values)
end
end
diff --git a/spec/models/ci/trigger_spec.rb b/spec/models/ci/trigger_spec.rb
index 3ca9231f58e..074cf1a0bd7 100644
--- a/spec/models/ci/trigger_spec.rb
+++ b/spec/models/ci/trigger_spec.rb
@@ -1,16 +1,24 @@
require 'spec_helper'
describe Ci::Trigger, models: true do
- let(:project) { FactoryGirl.create :empty_project }
+ let(:project) { create :empty_project }
+
+ describe 'associations' do
+ it { is_expected.to belong_to(:project) }
+ it { is_expected.to belong_to(:owner) }
+ it { is_expected.to have_many(:trigger_requests) }
+ end
describe 'before_validation' do
it 'sets an random token if none provided' do
- trigger = FactoryGirl.create :ci_trigger_without_token, project: project
+ trigger = create(:ci_trigger_without_token, project: project)
+
expect(trigger.token).not_to be_nil
end
it 'does not set an random token if one provided' do
- trigger = FactoryGirl.create :ci_trigger, project: project
+ trigger = create(:ci_trigger, project: project)
+
expect(trigger.token).to eq('token')
end
end
diff --git a/spec/models/note_spec.rb b/spec/models/note_spec.rb
index 1cde9e04951..33536487c41 100644
--- a/spec/models/note_spec.rb
+++ b/spec/models/note_spec.rb
@@ -387,4 +387,16 @@ describe Note, models: true do
end
end
end
+
+ describe 'expiring ETag cache' do
+ let(:note) { build(:note_on_issue) }
+
+ it "expires cache for note's issue when note is saved" do
+ expect_any_instance_of(Gitlab::EtagCaching::Store)
+ .to receive(:touch)
+ .with("/#{note.project.namespace.to_param}/#{note.project.to_param}/noteable/issue/#{note.noteable.id}/notes")
+
+ note.save!
+ end
+ end
end
diff --git a/spec/models/project_services/mattermost_slash_commands_service_spec.rb b/spec/models/project_services/mattermost_slash_commands_service_spec.rb
index 598ff232c82..f9531be5d25 100644
--- a/spec/models/project_services/mattermost_slash_commands_service_spec.rb
+++ b/spec/models/project_services/mattermost_slash_commands_service_spec.rb
@@ -92,7 +92,7 @@ describe MattermostSlashCommandsService, :models do
to_return(
status: 200,
headers: { 'Content-Type' => 'application/json' },
- body: ['list'].to_json
+ body: { 'list' => true }.to_json
)
end
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index e86b4a761d9..b99cde64675 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -32,6 +32,7 @@ describe User, models: true do
it { is_expected.to have_many(:spam_logs).dependent(:destroy) }
it { is_expected.to have_many(:todos).dependent(:destroy) }
it { is_expected.to have_many(:award_emoji).dependent(:destroy) }
+ it { is_expected.to have_many(:triggers).dependent(:destroy) }
it { is_expected.to have_many(:builds).dependent(:nullify) }
it { is_expected.to have_many(:pipelines).dependent(:nullify) }
it { is_expected.to have_many(:chat_names).dependent(:destroy) }
diff --git a/spec/requests/api/triggers_spec.rb b/spec/requests/api/triggers_spec.rb
index 153e2791cbe..424c02932ab 100644
--- a/spec/requests/api/triggers_spec.rb
+++ b/spec/requests/api/triggers_spec.rb
@@ -14,7 +14,7 @@ describe API::Triggers do
let!(:trigger2) { create(:ci_trigger, project: project, token: trigger_token_2) }
let!(:trigger_request) { create(:ci_trigger_request, trigger: trigger, created_at: '2015-01-01 12:13:14') }
- describe 'POST /projects/:project_id/trigger' do
+ describe 'POST /projects/:project_id/trigger/pipeline' do
let!(:project2) { create(:project) }
let(:options) do
{
@@ -28,17 +28,20 @@ describe API::Triggers do
context 'Handles errors' do
it 'returns bad request if token is missing' do
- post api("/projects/#{project.id}/trigger/builds"), ref: 'master'
+ post api("/projects/#{project.id}/trigger/pipeline"), ref: 'master'
+
expect(response).to have_http_status(400)
end
it 'returns not found if project is not found' do
- post api('/projects/0/trigger/builds'), options.merge(ref: 'master')
+ post api('/projects/0/trigger/pipeline'), options.merge(ref: 'master')
+
expect(response).to have_http_status(404)
end
it 'returns unauthorized if token is for different project' do
- post api("/projects/#{project2.id}/trigger/builds"), options.merge(ref: 'master')
+ post api("/projects/#{project2.id}/trigger/pipeline"), options.merge(ref: 'master')
+
expect(response).to have_http_status(401)
end
end
@@ -46,9 +49,11 @@ describe API::Triggers do
context 'Have a commit' do
let(:pipeline) { project.pipelines.last }
- it 'creates builds' do
- post api("/projects/#{project.id}/trigger/builds"), options.merge(ref: 'master')
+ it 'creates pipeline' do
+ post api("/projects/#{project.id}/trigger/pipeline"), options.merge(ref: 'master')
+
expect(response).to have_http_status(201)
+ expect(json_response).to include('id' => pipeline.id)
pipeline.builds.reload
expect(pipeline.builds.pending.size).to eq(2)
expect(pipeline.builds.size).to eq(5)
@@ -56,15 +61,17 @@ describe API::Triggers do
it 'creates builds on webhook from other gitlab repository and branch' do
expect do
- post api("/projects/#{project.id}/ref/master/trigger/builds?token=#{trigger_token}"), { ref: 'refs/heads/other-branch' }
+ post api("/projects/#{project.id}/ref/master/trigger/pipeline?token=#{trigger_token}"), { ref: 'refs/heads/other-branch' }
end.to change(project.builds, :count).by(5)
+
expect(response).to have_http_status(201)
end
- it 'returns bad request with no builds created if there\'s no commit for that ref' do
- post api("/projects/#{project.id}/trigger/builds"), options.merge(ref: 'other-branch')
+ it 'returns bad request with no pipeline created if there\'s no commit for that ref' do
+ post api("/projects/#{project.id}/trigger/pipeline"), options.merge(ref: 'other-branch')
+
expect(response).to have_http_status(400)
- expect(json_response['message']).to eq('No builds created')
+ expect(json_response['message']).to eq('No pipeline created')
end
context 'Validates variables' do
@@ -73,22 +80,24 @@ describe API::Triggers do
end
it 'validates variables to be a hash' do
- post api("/projects/#{project.id}/trigger/builds"), options.merge(variables: 'value', ref: 'master')
+ post api("/projects/#{project.id}/trigger/pipeline"), options.merge(variables: 'value', ref: 'master')
+
expect(response).to have_http_status(400)
expect(json_response['error']).to eq('variables is invalid')
end
it 'validates variables needs to be a map of key-valued strings' do
- post api("/projects/#{project.id}/trigger/builds"), options.merge(variables: { key: %w(1 2) }, ref: 'master')
+ post api("/projects/#{project.id}/trigger/pipeline"), options.merge(variables: { key: %w(1 2) }, ref: 'master')
+
expect(response).to have_http_status(400)
expect(json_response['message']).to eq('variables needs to be a map of key-valued strings')
end
it 'creates trigger request with variables' do
- post api("/projects/#{project.id}/trigger/builds"), options.merge(variables: variables, ref: 'master')
+ post api("/projects/#{project.id}/trigger/pipeline"), options.merge(variables: variables, ref: 'master')
+
expect(response).to have_http_status(201)
- pipeline.builds.reload
- expect(pipeline.builds.first.trigger_request.variables).to eq(variables)
+ expect(pipeline.builds.reload.first.trigger_request.variables).to eq(variables)
end
end
end
@@ -123,17 +132,17 @@ describe API::Triggers do
end
end
- describe 'GET /projects/:id/triggers/:token' do
+ describe 'GET /projects/:id/triggers/:trigger_id' do
context 'authenticated user with valid permissions' do
it 'returns trigger details' do
- get api("/projects/#{project.id}/triggers/#{trigger.token}", user)
+ get api("/projects/#{project.id}/triggers/#{trigger.id}", user)
expect(response).to have_http_status(200)
expect(json_response).to be_a(Hash)
end
it 'responds with 404 Not Found if requesting non-existing trigger' do
- get api("/projects/#{project.id}/triggers/abcdef012345", user)
+ get api("/projects/#{project.id}/triggers/-5", user)
expect(response).to have_http_status(404)
end
@@ -141,7 +150,7 @@ describe API::Triggers do
context 'authenticated user with invalid permissions' do
it 'does not return triggers list' do
- get api("/projects/#{project.id}/triggers/#{trigger.token}", user2)
+ get api("/projects/#{project.id}/triggers/#{trigger.id}", user2)
expect(response).to have_http_status(403)
end
@@ -149,7 +158,7 @@ describe API::Triggers do
context 'unauthenticated user' do
it 'does not return triggers list' do
- get api("/projects/#{project.id}/triggers/#{trigger.token}")
+ get api("/projects/#{project.id}/triggers/#{trigger.id}")
expect(response).to have_http_status(401)
end
@@ -158,19 +167,31 @@ describe API::Triggers do
describe 'POST /projects/:id/triggers' do
context 'authenticated user with valid permissions' do
- it 'creates trigger' do
- expect do
+ context 'with required parameters' do
+ it 'creates trigger' do
+ expect do
+ post api("/projects/#{project.id}/triggers", user),
+ description: 'trigger'
+ end.to change{project.triggers.count}.by(1)
+
+ expect(response).to have_http_status(201)
+ expect(json_response).to include('description' => 'trigger')
+ end
+ end
+
+ context 'without required parameters' do
+ it 'does not create trigger' do
post api("/projects/#{project.id}/triggers", user)
- end.to change{project.triggers.count}.by(1)
- expect(response).to have_http_status(201)
- expect(json_response).to be_a(Hash)
+ expect(response).to have_http_status(:bad_request)
+ end
end
end
context 'authenticated user with invalid permissions' do
it 'does not create trigger' do
- post api("/projects/#{project.id}/triggers", user2)
+ post api("/projects/#{project.id}/triggers", user2),
+ description: 'trigger'
expect(response).to have_http_status(403)
end
@@ -178,25 +199,87 @@ describe API::Triggers do
context 'unauthenticated user' do
it 'does not create trigger' do
- post api("/projects/#{project.id}/triggers")
+ post api("/projects/#{project.id}/triggers"),
+ description: 'trigger'
+
+ expect(response).to have_http_status(401)
+ end
+ end
+ end
+
+ describe 'PUT /projects/:id/triggers/:trigger_id' do
+ context 'authenticated user with valid permissions' do
+ let(:new_description) { 'new description' }
+
+ it 'updates description' do
+ put api("/projects/#{project.id}/triggers/#{trigger.id}", user),
+ description: new_description
+
+ expect(response).to have_http_status(200)
+ expect(json_response).to include('description' => new_description)
+ expect(trigger.reload.description).to eq(new_description)
+ end
+ end
+
+ context 'authenticated user with invalid permissions' do
+ it 'does not update trigger' do
+ put api("/projects/#{project.id}/triggers/#{trigger.id}", user2)
+
+ expect(response).to have_http_status(403)
+ end
+ end
+
+ context 'unauthenticated user' do
+ it 'does not update trigger' do
+ put api("/projects/#{project.id}/triggers/#{trigger.id}")
+
+ expect(response).to have_http_status(401)
+ end
+ end
+ end
+
+ describe 'POST /projects/:id/triggers/:trigger_id/take_ownership' do
+ context 'authenticated user with valid permissions' do
+ it 'updates owner' do
+ expect(trigger.owner).to be_nil
+
+ post api("/projects/#{project.id}/triggers/#{trigger.id}/take_ownership", user)
+
+ expect(response).to have_http_status(200)
+ expect(json_response).to include('owner')
+ expect(trigger.reload.owner).to eq(user)
+ end
+ end
+
+ context 'authenticated user with invalid permissions' do
+ it 'does not update owner' do
+ post api("/projects/#{project.id}/triggers/#{trigger.id}/take_ownership", user2)
+
+ expect(response).to have_http_status(403)
+ end
+ end
+
+ context 'unauthenticated user' do
+ it 'does not update owner' do
+ post api("/projects/#{project.id}/triggers/#{trigger.id}/take_ownership")
expect(response).to have_http_status(401)
end
end
end
- describe 'DELETE /projects/:id/triggers/:token' do
+ describe 'DELETE /projects/:id/triggers/:trigger_id' do
context 'authenticated user with valid permissions' do
it 'deletes trigger' do
expect do
- delete api("/projects/#{project.id}/triggers/#{trigger.token}", user)
+ delete api("/projects/#{project.id}/triggers/#{trigger.id}", user)
expect(response).to have_http_status(204)
end.to change{project.triggers.count}.by(-1)
end
it 'responds with 404 Not Found if requesting non-existing trigger' do
- delete api("/projects/#{project.id}/triggers/abcdef012345", user)
+ delete api("/projects/#{project.id}/triggers/-5", user)
expect(response).to have_http_status(404)
end
@@ -204,7 +287,7 @@ describe API::Triggers do
context 'authenticated user with invalid permissions' do
it 'does not delete trigger' do
- delete api("/projects/#{project.id}/triggers/#{trigger.token}", user2)
+ delete api("/projects/#{project.id}/triggers/#{trigger.id}", user2)
expect(response).to have_http_status(403)
end
@@ -212,7 +295,7 @@ describe API::Triggers do
context 'unauthenticated user' do
it 'does not delete trigger' do
- delete api("/projects/#{project.id}/triggers/#{trigger.token}")
+ delete api("/projects/#{project.id}/triggers/#{trigger.id}")
expect(response).to have_http_status(401)
end
diff --git a/spec/requests/api/v3/triggers_spec.rb b/spec/requests/api/v3/triggers_spec.rb
index 721ce4a361b..4819269d69f 100644
--- a/spec/requests/api/v3/triggers_spec.rb
+++ b/spec/requests/api/v3/triggers_spec.rb
@@ -11,6 +11,177 @@ describe API::V3::Triggers do
let!(:developer) { create(:project_member, :developer, user: user2, project: project) }
let!(:trigger) { create(:ci_trigger, project: project, token: trigger_token) }
+ describe 'POST /projects/:project_id/trigger' do
+ let!(:project2) { create(:project) }
+ let(:options) do
+ {
+ token: trigger_token
+ }
+ end
+
+ before do
+ stub_ci_pipeline_to_return_yaml_file
+ end
+
+ context 'Handles errors' do
+ it 'returns bad request if token is missing' do
+ post v3_api("/projects/#{project.id}/trigger/builds"), ref: 'master'
+ expect(response).to have_http_status(400)
+ end
+
+ it 'returns not found if project is not found' do
+ post v3_api('/projects/0/trigger/builds'), options.merge(ref: 'master')
+ expect(response).to have_http_status(404)
+ end
+
+ it 'returns unauthorized if token is for different project' do
+ post v3_api("/projects/#{project2.id}/trigger/builds"), options.merge(ref: 'master')
+ expect(response).to have_http_status(401)
+ end
+ end
+
+ context 'Have a commit' do
+ let(:pipeline) { project.pipelines.last }
+
+ it 'creates builds' do
+ post v3_api("/projects/#{project.id}/trigger/builds"), options.merge(ref: 'master')
+ expect(response).to have_http_status(201)
+ pipeline.builds.reload
+ expect(pipeline.builds.pending.size).to eq(2)
+ expect(pipeline.builds.size).to eq(5)
+ end
+
+ it 'creates builds on webhook from other gitlab repository and branch' do
+ expect do
+ post v3_api("/projects/#{project.id}/ref/master/trigger/builds?token=#{trigger_token}"), { ref: 'refs/heads/other-branch' }
+ end.to change(project.builds, :count).by(5)
+ expect(response).to have_http_status(201)
+ end
+
+ it 'returns bad request with no builds created if there\'s no commit for that ref' do
+ post v3_api("/projects/#{project.id}/trigger/builds"), options.merge(ref: 'other-branch')
+ expect(response).to have_http_status(400)
+ expect(json_response['message']).to eq('No builds created')
+ end
+
+ context 'Validates variables' do
+ let(:variables) do
+ { 'TRIGGER_KEY' => 'TRIGGER_VALUE' }
+ end
+
+ it 'validates variables to be a hash' do
+ post v3_api("/projects/#{project.id}/trigger/builds"), options.merge(variables: 'value', ref: 'master')
+ expect(response).to have_http_status(400)
+ expect(json_response['error']).to eq('variables is invalid')
+ end
+
+ it 'validates variables needs to be a map of key-valued strings' do
+ post v3_api("/projects/#{project.id}/trigger/builds"), options.merge(variables: { key: %w(1 2) }, ref: 'master')
+ expect(response).to have_http_status(400)
+ expect(json_response['message']).to eq('variables needs to be a map of key-valued strings')
+ end
+
+ it 'creates trigger request with variables' do
+ post v3_api("/projects/#{project.id}/trigger/builds"), options.merge(variables: variables, ref: 'master')
+ expect(response).to have_http_status(201)
+ pipeline.builds.reload
+ expect(pipeline.builds.first.trigger_request.variables).to eq(variables)
+ end
+ end
+ end
+ end
+
+ describe 'GET /projects/:id/triggers' do
+ context 'authenticated user with valid permissions' do
+ it 'returns list of triggers' do
+ get v3_api("/projects/#{project.id}/triggers", user)
+
+ expect(response).to have_http_status(200)
+ expect(response).to include_pagination_headers
+ expect(json_response).to be_a(Array)
+ expect(json_response[0]).to have_key('token')
+ end
+ end
+
+ context 'authenticated user with invalid permissions' do
+ it 'does not return triggers list' do
+ get v3_api("/projects/#{project.id}/triggers", user2)
+
+ expect(response).to have_http_status(403)
+ end
+ end
+
+ context 'unauthenticated user' do
+ it 'does not return triggers list' do
+ get v3_api("/projects/#{project.id}/triggers")
+
+ expect(response).to have_http_status(401)
+ end
+ end
+ end
+
+ describe 'GET /projects/:id/triggers/:token' do
+ context 'authenticated user with valid permissions' do
+ it 'returns trigger details' do
+ get v3_api("/projects/#{project.id}/triggers/#{trigger.token}", user)
+
+ expect(response).to have_http_status(200)
+ expect(json_response).to be_a(Hash)
+ end
+
+ it 'responds with 404 Not Found if requesting non-existing trigger' do
+ get v3_api("/projects/#{project.id}/triggers/abcdef012345", user)
+
+ expect(response).to have_http_status(404)
+ end
+ end
+
+ context 'authenticated user with invalid permissions' do
+ it 'does not return triggers list' do
+ get v3_api("/projects/#{project.id}/triggers/#{trigger.token}", user2)
+
+ expect(response).to have_http_status(403)
+ end
+ end
+
+ context 'unauthenticated user' do
+ it 'does not return triggers list' do
+ get v3_api("/projects/#{project.id}/triggers/#{trigger.token}")
+
+ expect(response).to have_http_status(401)
+ end
+ end
+ end
+
+ describe 'POST /projects/:id/triggers' do
+ context 'authenticated user with valid permissions' do
+ it 'creates trigger' do
+ expect do
+ post v3_api("/projects/#{project.id}/triggers", user)
+ end.to change{project.triggers.count}.by(1)
+
+ expect(response).to have_http_status(201)
+ expect(json_response).to be_a(Hash)
+ end
+ end
+
+ context 'authenticated user with invalid permissions' do
+ it 'does not create trigger' do
+ post v3_api("/projects/#{project.id}/triggers", user2)
+
+ expect(response).to have_http_status(403)
+ end
+ end
+
+ context 'unauthenticated user' do
+ it 'does not create trigger' do
+ post v3_api("/projects/#{project.id}/triggers")
+
+ expect(response).to have_http_status(401)
+ end
+ end
+ end
+
describe 'DELETE /projects/:id/triggers/:token' do
context 'authenticated user with valid permissions' do
it 'deletes trigger' do
diff --git a/spec/routing/project_routing_spec.rb b/spec/routing/project_routing_spec.rb
index a5bc62ef6c2..d31f1bdfb7c 100644
--- a/spec/routing/project_routing_spec.rb
+++ b/spec/routing/project_routing_spec.rb
@@ -431,12 +431,22 @@ describe 'project routing' do
end
end
- # project_notes GET /:project_id/notes(.:format) notes#index
- # POST /:project_id/notes(.:format) notes#create
- # project_note DELETE /:project_id/notes/:id(.:format) notes#destroy
+ # project_noteable_notes GET /:project_id/noteable/:target_type/:target_id/notes notes#index
+ # POST /:project_id/notes(.:format) notes#create
+ # project_note DELETE /:project_id/notes/:id(.:format) notes#destroy
describe Projects::NotesController, 'routing' do
+ it 'to #index' do
+ expect(get('/gitlab/gitlabhq/noteable/issue/1/notes')).to route_to(
+ 'projects/notes#index',
+ namespace_id: 'gitlab',
+ project_id: 'gitlabhq',
+ target_type: 'issue',
+ target_id: '1'
+ )
+ end
+
it_behaves_like 'RESTful project resources' do
- let(:actions) { [:index, :create, :destroy] }
+ let(:actions) { [:create, :destroy] }
let(:controller) { 'notes' }
end
end
diff --git a/spec/services/ci/create_trigger_request_service_spec.rb b/spec/services/ci/create_trigger_request_service_spec.rb
index d8c443d29d5..5e68343784d 100644
--- a/spec/services/ci/create_trigger_request_service_spec.rb
+++ b/spec/services/ci/create_trigger_request_service_spec.rb
@@ -13,8 +13,22 @@ describe Ci::CreateTriggerRequestService, services: true do
context 'valid params' do
subject { service.execute(project, trigger, 'master') }
- it { expect(subject).to be_kind_of(Ci::TriggerRequest) }
- it { expect(subject.builds.first).to be_kind_of(Ci::Build) }
+ context 'without owner' do
+ it { expect(subject).to be_kind_of(Ci::TriggerRequest) }
+ it { expect(subject.pipeline).to be_kind_of(Ci::Pipeline) }
+ it { expect(subject.builds.first).to be_kind_of(Ci::Build) }
+ end
+
+ context 'with owner' do
+ let(:owner) { create(:user) }
+ let(:trigger) { create(:ci_trigger, project: project, owner: owner) }
+
+ it { expect(subject).to be_kind_of(Ci::TriggerRequest) }
+ it { expect(subject.pipeline).to be_kind_of(Ci::Pipeline) }
+ it { expect(subject.pipeline.user).to eq(owner) }
+ it { expect(subject.builds.first).to be_kind_of(Ci::Build) }
+ it { expect(subject.builds.first.user).to eq(owner) }
+ end
end
context 'no commit for ref' do
diff --git a/spec/services/projects/update_pages_service_spec.rb b/spec/services/projects/update_pages_service_spec.rb
index 411b22a0fb8..f75fdd9e03f 100644
--- a/spec/services/projects/update_pages_service_spec.rb
+++ b/spec/services/projects/update_pages_service_spec.rb
@@ -26,6 +26,28 @@ describe Projects::UpdatePagesService do
build.update_attributes(artifacts_metadata: metadata)
end
+ describe 'pages artifacts' do
+ context 'with expiry date' do
+ before do
+ build.artifacts_expire_in = "2 days"
+ end
+
+ it "doesn't delete artifacts" do
+ expect(execute).to eq(:success)
+
+ expect(build.reload.artifacts_file?).to eq(true)
+ end
+ end
+
+ context 'without expiry date' do
+ it "does delete artifacts" do
+ expect(execute).to eq(:success)
+
+ expect(build.reload.artifacts_file?).to eq(false)
+ end
+ end
+ end
+
it 'succeeds' do
expect(project.pages_deployed?).to be_falsey
expect(execute).to eq(:success)
diff --git a/spec/tasks/gitlab/backup_rake_spec.rb b/spec/tasks/gitlab/backup_rake_spec.rb
index df8a47893f9..dfbfbd05f43 100644
--- a/spec/tasks/gitlab/backup_rake_spec.rb
+++ b/spec/tasks/gitlab/backup_rake_spec.rb
@@ -108,7 +108,7 @@ describe 'gitlab:app namespace rake task' do
$stdout = orig_stdout
end
- describe 'backup creation and deletion using annex and custom_hooks' do
+ describe 'backup creation and deletion using custom_hooks' do
let(:project) { create(:project) }
let(:user_backup_path) { "repositories/#{project.path_with_namespace}" }
@@ -132,25 +132,6 @@ describe 'gitlab:app namespace rake task' do
Dir.chdir(@origin_cd)
end
- context 'project uses git-annex and successfully creates backup' do
- let(:filename) { "annex" }
-
- it 'creates annex.tar and project bundle' do
- tar_contents, exit_status = Gitlab::Popen.popen(%W{tar -tvf #{@backup_tar}})
-
- expect(exit_status).to eq(0)
- expect(tar_contents).to match(user_backup_path)
- expect(tar_contents).to match("#{user_backup_path}/annex.tar")
- expect(tar_contents).to match("#{user_backup_path}.bundle")
- end
-
- it 'restores files correctly' do
- restore_backup
-
- expect(Dir.entries(File.join(project.repository.path, "annex"))).to include("dummy.txt")
- end
- end
-
context 'project uses custom_hooks and successfully creates backup' do
let(:filename) { "custom_hooks" }