summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/assets/javascripts/monitoring/components/dashboard.vue61
-rw-r--r--app/assets/javascripts/monitoring/services/monitoring_service.js49
-rw-r--r--app/helpers/auto_devops_helper.rb4
-rw-r--r--app/helpers/projects_helper.rb2
-rw-r--r--app/models/issue.rb3
-rw-r--r--app/services/ci/pipeline_trigger_service.rb2
-rw-r--r--changelogs/unreleased/18308-escape-characters.yml5
-rw-r--r--changelogs/unreleased/fix-gpg-tmp-dir-removal-race-condition.yml5
-rw-r--r--changelogs/unreleased/fix-sm-37559-pipeline-triggered-through-api-not-showing-trigger-variables.yml6
-rw-r--r--changelogs/unreleased/refactor-monitoring-service.yml5
-rw-r--r--changelogs/unreleased/replace_profile_active_tab-feature.yml5
-rw-r--r--changelogs/unreleased/zj-auto-devops-banner.yml6
-rw-r--r--features/profile/active_tab.feature29
-rw-r--r--features/steps/profile/active_tab.rb25
-rw-r--r--lib/api/api.rb1
-rw-r--r--lib/gitlab/gpg.rb14
-rw-r--r--spec/features/profiles/user_visits_profile_account_page_spec.rb16
-rw-r--r--spec/features/profiles/user_visits_profile_authentication_log_page_spec.rb16
-rw-r--r--spec/features/profiles/user_visits_profile_page_spec.rb16
-rw-r--r--spec/features/profiles/user_visits_profile_preferences_page_spec.rb (renamed from spec/features/profiles/preferences_spec.rb)14
-rw-r--r--spec/features/profiles/user_visits_profile_ssh_keys_page_spec.rb16
-rw-r--r--spec/helpers/auto_devops_helper_spec.rb16
-rw-r--r--spec/helpers/projects_helper_spec.rb11
-rw-r--r--spec/models/abuse_report_spec.rb7
-rw-r--r--spec/models/appearance_spec.rb2
-rw-r--r--spec/models/chat_name_spec.rb3
-rw-r--r--spec/models/chat_team_spec.rb3
-rw-r--r--spec/models/ci/build_spec.rb48
-rw-r--r--spec/models/lfs_objects_project_spec.rb15
-rw-r--r--spec/requests/api/services_spec.rb13
-rw-r--r--spec/services/ci/pipeline_trigger_service_spec.rb2
-rw-r--r--spec/services/ci/retry_build_service_spec.rb9
32 files changed, 265 insertions, 164 deletions
diff --git a/app/assets/javascripts/monitoring/components/dashboard.vue b/app/assets/javascripts/monitoring/components/dashboard.vue
index b596c4f383f..5d96b193fce 100644
--- a/app/assets/javascripts/monitoring/components/dashboard.vue
+++ b/app/assets/javascripts/monitoring/components/dashboard.vue
@@ -1,7 +1,6 @@
<script>
/* global Flash */
import _ from 'underscore';
- import statusCodes from '../../lib/utils/http_status';
import MonitoringService from '../services/monitoring_service';
import GraphGroup from './graph_group.vue';
import Graph from './graph.vue';
@@ -21,10 +20,9 @@
hasMetrics: gl.utils.convertPermissionToBoolean(metricsData.hasMetrics),
documentationPath: metricsData.documentationPath,
settingsPath: metricsData.settingsPath,
- endpoint: metricsData.additionalMetrics,
+ metricsEndpoint: metricsData.additionalMetrics,
deploymentEndpoint: metricsData.deploymentEndpoint,
showEmptyState: true,
- backOffRequestCounter: 0,
updateAspectRatio: false,
updatedAspectRatios: 0,
resizeThrottled: {},
@@ -39,50 +37,16 @@
methods: {
getGraphsData() {
- const maxNumberOfRequests = 3;
this.state = 'loading';
- gl.utils.backOff((next, stop) => {
- this.service.get().then((resp) => {
- if (resp.status === statusCodes.NO_CONTENT) {
- this.backOffRequestCounter = this.backOffRequestCounter += 1;
- if (this.backOffRequestCounter < maxNumberOfRequests) {
- next();
- } else {
- stop(new Error('Failed to connect to the prometheus server'));
- }
- } else {
- stop(resp);
- }
- }).catch(stop);
- })
- .then((resp) => {
- if (resp.status === statusCodes.NO_CONTENT) {
- this.state = 'unableToConnect';
- return false;
- }
- return resp.json();
- })
- .then((metricGroupsData) => {
- if (!metricGroupsData) return false;
- this.store.storeMetrics(metricGroupsData.data);
- return this.getDeploymentData();
- })
- .then((deploymentData) => {
- if (deploymentData !== false) {
- this.store.storeDeploymentData(deploymentData.deployments);
- this.showEmptyState = false;
- }
- return {};
- })
- .catch(() => {
- this.state = 'unableToConnect';
- });
- },
-
- getDeploymentData() {
- return this.service.getDeploymentData(this.deploymentEndpoint)
- .then(resp => resp.json())
- .catch(() => new Flash('Error getting deployment information.'));
+ Promise.all([
+ this.service.getGraphsData()
+ .then(data => this.store.storeMetrics(data)),
+ this.service.getDeploymentData()
+ .then(data => this.store.storeDeploymentData(data))
+ .catch(() => new Flash('Error getting deployment information.')),
+ ])
+ .then(() => { this.showEmptyState = false; })
+ .catch(() => { this.state = 'unableToConnect'; });
},
resize() {
@@ -99,7 +63,10 @@
},
created() {
- this.service = new MonitoringService(this.endpoint);
+ this.service = new MonitoringService({
+ metricsEndpoint: this.metricsEndpoint,
+ deploymentEndpoint: this.deploymentEndpoint,
+ });
eventHub.$on('toggleAspectRatio', this.toggleAspectRatio);
},
diff --git a/app/assets/javascripts/monitoring/services/monitoring_service.js b/app/assets/javascripts/monitoring/services/monitoring_service.js
index 1e9ae934853..4ed651d5740 100644
--- a/app/assets/javascripts/monitoring/services/monitoring_service.js
+++ b/app/assets/javascripts/monitoring/services/monitoring_service.js
@@ -1,19 +1,54 @@
import Vue from 'vue';
import VueResource from 'vue-resource';
+import statusCodes from '../../lib/utils/http_status';
Vue.use(VueResource);
+const MAX_REQUESTS = 3;
+
+function backOffRequest(makeRequestCallback) {
+ let requestCounter = 0;
+ return gl.utils.backOff((next, stop) => {
+ makeRequestCallback().then((resp) => {
+ if (resp.status === statusCodes.NO_CONTENT) {
+ requestCounter += 1;
+ if (requestCounter < MAX_REQUESTS) {
+ next();
+ } else {
+ stop(new Error('Failed to connect to the prometheus server'));
+ }
+ } else {
+ stop(resp);
+ }
+ }).catch(stop);
+ });
+}
+
export default class MonitoringService {
- constructor(endpoint) {
- this.graphs = Vue.resource(endpoint);
+ constructor({ metricsEndpoint, deploymentEndpoint }) {
+ this.metricsEndpoint = metricsEndpoint;
+ this.deploymentEndpoint = deploymentEndpoint;
}
- get() {
- return this.graphs.get();
+ getGraphsData() {
+ return backOffRequest(() => Vue.http.get(this.metricsEndpoint))
+ .then(resp => resp.json())
+ .then((response) => {
+ if (!response || !response.data) {
+ throw new Error('Unexpected metrics data response from prometheus endpoint');
+ }
+ return response.data;
+ });
}
- // eslint-disable-next-line class-methods-use-this
- getDeploymentData(endpoint) {
- return Vue.http.get(endpoint);
+ getDeploymentData() {
+ return backOffRequest(() => Vue.http.get(this.deploymentEndpoint))
+ .then(resp => resp.json())
+ .then((response) => {
+ if (!response || !response.deployments) {
+ throw new Error('Unexpected deployment data response from prometheus endpoint');
+ }
+ return response.deployments;
+ });
}
}
diff --git a/app/helpers/auto_devops_helper.rb b/app/helpers/auto_devops_helper.rb
index c132daed323..c455d18cff8 100644
--- a/app/helpers/auto_devops_helper.rb
+++ b/app/helpers/auto_devops_helper.rb
@@ -3,6 +3,8 @@ module AutoDevopsHelper
Feature.get(:auto_devops_banner_disabled).off? &&
show_callout?('auto_devops_settings_dismissed') &&
can?(current_user, :admin_pipeline, project) &&
- project.has_auto_devops_implicitly_disabled?
+ project.has_auto_devops_implicitly_disabled? &&
+ !project.repository.gitlab_ci_yml &&
+ project.ci_services.active.none?
end
end
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index 0c8cb9ba235..ddeff490d3a 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -320,7 +320,7 @@ module ProjectsHelper
def git_user_name
if current_user
- current_user.name
+ current_user.name.gsub('"', '\"')
else
_("Your name")
end
diff --git a/app/models/issue.rb b/app/models/issue.rb
index 8c7d492e605..cd5056aae5e 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -30,9 +30,6 @@ class Issue < ActiveRecord::Base
has_many :issue_assignees
has_many :assignees, class_name: "User", through: :issue_assignees
- has_many :issue_assignees
- has_many :assignees, class_name: "User", through: :issue_assignees
-
validates :project, presence: true
scope :in_projects, ->(project_ids) { where(project_id: project_ids) }
diff --git a/app/services/ci/pipeline_trigger_service.rb b/app/services/ci/pipeline_trigger_service.rb
index 1e5ad28ba57..120af8c1e61 100644
--- a/app/services/ci/pipeline_trigger_service.rb
+++ b/app/services/ci/pipeline_trigger_service.rb
@@ -14,7 +14,7 @@ module Ci
pipeline = Ci::CreatePipelineService.new(project, trigger.owner, ref: params[:ref])
.execute(:trigger, ignore_skip_ci: true) do |pipeline|
- trigger.trigger_requests.create!(pipeline: pipeline)
+ pipeline.trigger_requests.create!(trigger: trigger)
create_pipeline_variables!(pipeline)
end
diff --git a/changelogs/unreleased/18308-escape-characters.yml b/changelogs/unreleased/18308-escape-characters.yml
new file mode 100644
index 00000000000..8766e971490
--- /dev/null
+++ b/changelogs/unreleased/18308-escape-characters.yml
@@ -0,0 +1,5 @@
+---
+title: Escape quotes in git username
+merge_request: 14020
+author: Brandon Everett
+type: fixed
diff --git a/changelogs/unreleased/fix-gpg-tmp-dir-removal-race-condition.yml b/changelogs/unreleased/fix-gpg-tmp-dir-removal-race-condition.yml
new file mode 100644
index 00000000000..e75f188913f
--- /dev/null
+++ b/changelogs/unreleased/fix-gpg-tmp-dir-removal-race-condition.yml
@@ -0,0 +1,5 @@
+---
+title: Fixes the 500 errors caused by a race condition in GPG's tmp directory handling
+merge_request: 14194
+author: Alexis Reigel
+type: fixed
diff --git a/changelogs/unreleased/fix-sm-37559-pipeline-triggered-through-api-not-showing-trigger-variables.yml b/changelogs/unreleased/fix-sm-37559-pipeline-triggered-through-api-not-showing-trigger-variables.yml
new file mode 100644
index 00000000000..8aae0f6f5b6
--- /dev/null
+++ b/changelogs/unreleased/fix-sm-37559-pipeline-triggered-through-api-not-showing-trigger-variables.yml
@@ -0,0 +1,6 @@
+---
+title: Fix Pipeline Triggers to show triggered label and predefined variables (e.g.
+ CI_PIPELINE_TRIGGERED)
+merge_request: 14244
+author:
+type: fixed
diff --git a/changelogs/unreleased/refactor-monitoring-service.yml b/changelogs/unreleased/refactor-monitoring-service.yml
new file mode 100644
index 00000000000..685397cadb8
--- /dev/null
+++ b/changelogs/unreleased/refactor-monitoring-service.yml
@@ -0,0 +1,5 @@
+---
+title: Perform prometheus data endpoint requests in parallel
+merge_request: 14003
+author:
+type: fixed
diff --git a/changelogs/unreleased/replace_profile_active_tab-feature.yml b/changelogs/unreleased/replace_profile_active_tab-feature.yml
new file mode 100644
index 00000000000..e911396a2b9
--- /dev/null
+++ b/changelogs/unreleased/replace_profile_active_tab-feature.yml
@@ -0,0 +1,5 @@
+---
+title: Replace the 'profile/active_tab.feature' spinach test with an rspec analog
+merge_request: 14239
+author: Vitaliy @blackst0ne Klachkov
+type: other
diff --git a/changelogs/unreleased/zj-auto-devops-banner.yml b/changelogs/unreleased/zj-auto-devops-banner.yml
new file mode 100644
index 00000000000..a2abed0b2ec
--- /dev/null
+++ b/changelogs/unreleased/zj-auto-devops-banner.yml
@@ -0,0 +1,6 @@
+---
+title: Do not show the Auto DevOps banner when the project has a .gitlab-ci.yml on
+ master
+merge_request:
+author:
+type: fixed
diff --git a/features/profile/active_tab.feature b/features/profile/active_tab.feature
deleted file mode 100644
index 21d7d6c3800..00000000000
--- a/features/profile/active_tab.feature
+++ /dev/null
@@ -1,29 +0,0 @@
-@profile
-Feature: Profile Active Tab
- Background:
- Given I sign in as a user
-
- Scenario: On Profile Home
- Given I visit profile page
- Then the active main tab should be Home
- And no other main tabs should be active
-
- Scenario: On Profile Account
- Given I visit profile account page
- Then the active main tab should be Account
- And no other main tabs should be active
-
- Scenario: On Profile SSH Keys
- Given I visit profile SSH keys page
- Then the active main tab should be SSH Keys
- And no other main tabs should be active
-
- Scenario: On Profile Preferences
- Given I visit profile preferences page
- Then the active main tab should be Preferences
- And no other main tabs should be active
-
- Scenario: On Profile Authentication log
- Given I visit Authentication log page
- Then the active main tab should be Authentication log
- And no other main tabs should be active
diff --git a/features/steps/profile/active_tab.rb b/features/steps/profile/active_tab.rb
deleted file mode 100644
index 069d4e6a23d..00000000000
--- a/features/steps/profile/active_tab.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-class Spinach::Features::ProfileActiveTab < Spinach::FeatureSteps
- include SharedAuthentication
- include SharedPaths
- include SharedActiveTab
-
- step 'the active main tab should be Home' do
- ensure_active_main_tab('Profile')
- end
-
- step 'the active main tab should be Account' do
- ensure_active_main_tab('Account')
- end
-
- step 'the active main tab should be SSH Keys' do
- ensure_active_main_tab('SSH Keys')
- end
-
- step 'the active main tab should be Preferences' do
- ensure_active_main_tab('Preferences')
- end
-
- step 'the active main tab should be Authentication log' do
- ensure_active_main_tab('Authentication log')
- end
-end
diff --git a/lib/api/api.rb b/lib/api/api.rb
index ee4e1688e12..79e55a2f4f7 100644
--- a/lib/api/api.rb
+++ b/lib/api/api.rb
@@ -8,7 +8,6 @@ module API
logger: Logger.new(LOG_FILENAME),
formatter: Gitlab::GrapeLogging::Formatters::LogrageWithTimestamp.new,
include: [
- GrapeLogging::Loggers::Response.new,
GrapeLogging::Loggers::FilterParameters.new,
GrapeLogging::Loggers::ClientEnv.new
]
diff --git a/lib/gitlab/gpg.rb b/lib/gitlab/gpg.rb
index 025f826e65f..0d5039ddf5f 100644
--- a/lib/gitlab/gpg.rb
+++ b/lib/gitlab/gpg.rb
@@ -69,11 +69,17 @@ module Gitlab
def optimistic_using_tmp_keychain
previous_dir = current_home_dir
- Dir.mktmpdir do |dir|
- GPGME::Engine.home_dir = dir
- yield
- end
+ tmp_dir = Dir.mktmpdir
+ GPGME::Engine.home_dir = tmp_dir
+ yield
ensure
+ # Ignore any errors when removing the tmp directory, as we may run into a
+ # race condition:
+ # The `gpg-agent` agent process may clean up some files as well while
+ # `FileUtils.remove_entry` is iterating the directory and removing all
+ # its contained files and directories recursively, which could raise an
+ # error.
+ FileUtils.remove_entry(tmp_dir, true)
GPGME::Engine.home_dir = previous_dir
end
end
diff --git a/spec/features/profiles/user_visits_profile_account_page_spec.rb b/spec/features/profiles/user_visits_profile_account_page_spec.rb
new file mode 100644
index 00000000000..8c7233c77ad
--- /dev/null
+++ b/spec/features/profiles/user_visits_profile_account_page_spec.rb
@@ -0,0 +1,16 @@
+require 'spec_helper'
+
+describe 'User visits the profile account page' do
+ let(:user) { create(:user) }
+
+ before do
+ sign_in(user)
+
+ visit(profile_account_path)
+ end
+
+ it 'shows correct menu item' do
+ expect(find('.sidebar-top-level-items > li.active')).to have_content('Account')
+ expect(page).to have_selector('.sidebar-top-level-items > li.active', count: 1)
+ end
+end
diff --git a/spec/features/profiles/user_visits_profile_authentication_log_page_spec.rb b/spec/features/profiles/user_visits_profile_authentication_log_page_spec.rb
new file mode 100644
index 00000000000..ffb504cc573
--- /dev/null
+++ b/spec/features/profiles/user_visits_profile_authentication_log_page_spec.rb
@@ -0,0 +1,16 @@
+require 'spec_helper'
+
+describe 'User visits the authentication log page' do
+ let(:user) { create(:user) }
+
+ before do
+ sign_in(user)
+
+ visit(audit_log_profile_path)
+ end
+
+ it 'shows correct menu item' do
+ expect(find('.sidebar-top-level-items > li.active')).to have_content('Authentication log')
+ expect(page).to have_selector('.sidebar-top-level-items > li.active', count: 1)
+ end
+end
diff --git a/spec/features/profiles/user_visits_profile_page_spec.rb b/spec/features/profiles/user_visits_profile_page_spec.rb
new file mode 100644
index 00000000000..3bf6d718bc7
--- /dev/null
+++ b/spec/features/profiles/user_visits_profile_page_spec.rb
@@ -0,0 +1,16 @@
+require 'spec_helper'
+
+describe 'User visits the profile page' do
+ let(:user) { create(:user) }
+
+ before do
+ sign_in(user)
+
+ visit(profile_path)
+ end
+
+ it 'shows correct menu item' do
+ expect(find('.sidebar-top-level-items > li.active')).to have_content('Profile')
+ expect(page).to have_selector('.sidebar-top-level-items > li.active', count: 1)
+ end
+end
diff --git a/spec/features/profiles/preferences_spec.rb b/spec/features/profiles/user_visits_profile_preferences_page_spec.rb
index c935cdfd5c4..d1776b3d7c2 100644
--- a/spec/features/profiles/preferences_spec.rb
+++ b/spec/features/profiles/user_visits_profile_preferences_page_spec.rb
@@ -1,14 +1,20 @@
require 'spec_helper'
-describe 'Profile > Preferences', :js do
+describe 'User visits the profile preferences page' do
let(:user) { create(:user) }
before do
sign_in(user)
- visit profile_preferences_path
+
+ visit(profile_preferences_path)
+ end
+
+ it 'shows correct menu item' do
+ expect(find('.sidebar-top-level-items > li.active')).to have_content('Preferences')
+ expect(page).to have_selector('.sidebar-top-level-items > li.active', count: 1)
end
- describe 'User changes their syntax highlighting theme' do
+ describe 'User changes their syntax highlighting theme', :js do
it 'creates a flash message' do
choose 'user_color_scheme_id_5'
@@ -27,7 +33,7 @@ describe 'Profile > Preferences', :js do
end
end
- describe 'User changes their default dashboard' do
+ describe 'User changes their default dashboard', :js do
it 'creates a flash message' do
select 'Starred Projects', from: 'user_dashboard'
click_button 'Save'
diff --git a/spec/features/profiles/user_visits_profile_ssh_keys_page_spec.rb b/spec/features/profiles/user_visits_profile_ssh_keys_page_spec.rb
new file mode 100644
index 00000000000..0b7a63b54b4
--- /dev/null
+++ b/spec/features/profiles/user_visits_profile_ssh_keys_page_spec.rb
@@ -0,0 +1,16 @@
+require 'spec_helper'
+
+describe 'User visits the profile SSH keys page' do
+ let(:user) { create(:user) }
+
+ before do
+ sign_in(user)
+
+ visit(profile_keys_path)
+ end
+
+ it 'shows correct menu item' do
+ expect(find('.sidebar-top-level-items > li.active')).to have_content('SSH Keys')
+ expect(page).to have_selector('.sidebar-top-level-items > li.active', count: 1)
+ end
+end
diff --git a/spec/helpers/auto_devops_helper_spec.rb b/spec/helpers/auto_devops_helper_spec.rb
index 80d58ff6bf7..5e272af6073 100644
--- a/spec/helpers/auto_devops_helper_spec.rb
+++ b/spec/helpers/auto_devops_helper_spec.rb
@@ -65,5 +65,21 @@ describe AutoDevopsHelper do
it { is_expected.to eq(false) }
end
+
+ context 'when master contains a .gitlab-ci.yml file' do
+ before do
+ allow(project.repository).to receive(:gitlab_ci_yml).and_return("script: ['test']")
+ end
+
+ it { is_expected.to eq(false) }
+ end
+
+ context 'when another service is enabled' do
+ before do
+ create(:service, project: project, category: :ci, active: true)
+ end
+
+ it { is_expected.to eq(false) }
+ end
end
end
diff --git a/spec/helpers/projects_helper_spec.rb b/spec/helpers/projects_helper_spec.rb
index 1437479831e..a76c75e0c08 100644
--- a/spec/helpers/projects_helper_spec.rb
+++ b/spec/helpers/projects_helper_spec.rb
@@ -469,4 +469,15 @@ describe ProjectsHelper do
expect(recorder.count).to eq(1)
end
end
+
+ describe '#git_user_name' do
+ let(:user) { double(:user, name: 'John "A" Doe53') }
+ before do
+ allow(helper).to receive(:current_user).and_return(user)
+ end
+
+ it 'parses quotes in name' do
+ expect(helper.send(:git_user_name)).to eq('John \"A\" Doe53')
+ end
+ end
end
diff --git a/spec/models/abuse_report_spec.rb b/spec/models/abuse_report_spec.rb
index d4da30b1641..f49a61062c1 100644
--- a/spec/models/abuse_report_spec.rb
+++ b/spec/models/abuse_report_spec.rb
@@ -1,8 +1,9 @@
require 'rails_helper'
-RSpec.describe AbuseReport do
- subject { create(:abuse_report) }
- let(:user) { create(:admin) }
+describe AbuseReport do
+ set(:report) { create(:abuse_report) }
+ set(:user) { create(:admin) }
+ subject { report }
it { expect(subject).to be_valid }
diff --git a/spec/models/appearance_spec.rb b/spec/models/appearance_spec.rb
index b5d5d58697b..49f44525b29 100644
--- a/spec/models/appearance_spec.rb
+++ b/spec/models/appearance_spec.rb
@@ -1,6 +1,6 @@
require 'rails_helper'
-RSpec.describe Appearance do
+describe Appearance do
subject { build(:appearance) }
it { is_expected.to be_valid }
diff --git a/spec/models/chat_name_spec.rb b/spec/models/chat_name_spec.rb
index 8581bcbb08b..e89e534d914 100644
--- a/spec/models/chat_name_spec.rb
+++ b/spec/models/chat_name_spec.rb
@@ -1,7 +1,8 @@
require 'spec_helper'
describe ChatName do
- subject { create(:chat_name) }
+ set(:chat_name) { create(:chat_name) }
+ subject { chat_name }
it { is_expected.to belong_to(:service) }
it { is_expected.to belong_to(:user) }
diff --git a/spec/models/chat_team_spec.rb b/spec/models/chat_team_spec.rb
index e0e5f73e6fe..70a9a206faa 100644
--- a/spec/models/chat_team_spec.rb
+++ b/spec/models/chat_team_spec.rb
@@ -1,7 +1,8 @@
require 'spec_helper'
describe ChatTeam do
- subject { create(:chat_team) }
+ set(:chat_team) { create(:chat_team) }
+ subject { chat_team }
# Associations
it { is_expected.to belong_to(:namespace) }
diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb
index c2c9f1c12d1..451968c7342 100644
--- a/spec/models/ci/build_spec.rb
+++ b/spec/models/ci/build_spec.rb
@@ -1,18 +1,19 @@
require 'spec_helper'
describe Ci::Build do
- let(:user) { create(:user) }
- let(:project) { create(:project, :repository) }
- let(:build) { create(:ci_build, pipeline: pipeline) }
- let(:test_trace) { 'This is a test' }
+ set(:user) { create(:user) }
+ set(:group) { create(:group, :access_requestable) }
+ set(:project) { create(:project, :repository, group: group) }
- let(:pipeline) do
+ set(:pipeline) do
create(:ci_pipeline, project: project,
sha: project.commit.id,
ref: project.default_branch,
status: 'success')
end
+ let(:build) { create(:ci_build, pipeline: pipeline) }
+
it { is_expected.to belong_to(:runner) }
it { is_expected.to belong_to(:trigger_request) }
it { is_expected.to belong_to(:erased_by) }
@@ -282,7 +283,7 @@ describe Ci::Build do
let(:project_regex) { '\(\d+\.\d+\) covered' }
before do
- project.build_coverage_regex = project_regex
+ project.update_column(:build_coverage_regex, project_regex)
end
context 'and coverage_regex attribute is not set' do
@@ -1096,9 +1097,6 @@ describe Ci::Build do
end
describe '#repo_url' do
- let(:build) { create(:ci_build) }
- let(:project) { build.project }
-
subject { build.repo_url }
it { is_expected.to be_a(String) }
@@ -1199,6 +1197,8 @@ describe Ci::Build do
end
context 'use from gitlab-ci.yml' do
+ let(:pipeline) { create(:ci_pipeline) }
+
before do
stub_ci_pipeline_yaml_file(config)
end
@@ -1442,11 +1442,7 @@ describe Ci::Build do
{ key: 'SECRET_KEY', value: 'secret_value', public: false }
end
- let(:group) { create(:group, :access_requestable) }
-
before do
- build.project.update(group: group)
-
create(:ci_group_variable,
secret_variable.slice(:key, :value).merge(group: group))
end
@@ -1459,11 +1455,7 @@ describe Ci::Build do
{ key: 'PROTECTED_KEY', value: 'protected_value', public: false }
end
- let(:group) { create(:group, :access_requestable) }
-
before do
- build.project.update(group: group)
-
create(:ci_group_variable,
:protected,
protected_variable.slice(:key, :value).merge(group: group))
@@ -1486,6 +1478,10 @@ describe Ci::Build do
end
context 'when the ref is not protected' do
+ before do
+ build.update_column(:ref, 'some/feature')
+ end
+
it { is_expected.not_to include(protected_variable) }
end
end
@@ -1552,6 +1548,8 @@ describe Ci::Build do
end
context 'when yaml_variables are undefined' do
+ let(:pipeline) { create(:ci_pipeline, project: project) }
+
before do
build.yaml_variables = nil
end
@@ -1645,7 +1643,10 @@ describe Ci::Build do
before do
build.environment = 'production'
- allow(project).to receive(:deployment_variables).and_return([deployment_variable])
+
+ allow_any_instance_of(Project)
+ .to receive(:deployment_variables)
+ .and_return([deployment_variable])
end
it { is_expected.to include(deployment_variable) }
@@ -1669,14 +1670,19 @@ describe Ci::Build do
before do
allow(build).to receive(:predefined_variables) { [build_pre_var] }
- allow(project).to receive(:predefined_variables) { [project_pre_var] }
- allow(pipeline).to receive(:predefined_variables) { [pipeline_pre_var] }
allow(build).to receive(:yaml_variables) { [build_yaml_var] }
- allow(project).to receive(:secret_variables_for)
+ allow_any_instance_of(Project)
+ .to receive(:predefined_variables) { [project_pre_var] }
+
+ allow_any_instance_of(Project)
+ .to receive(:secret_variables_for)
.with(ref: 'master', environment: nil) do
[create(:ci_variable, key: 'secret', value: 'value')]
end
+
+ allow_any_instance_of(Ci::Pipeline)
+ .to receive(:predefined_variables) { [pipeline_pre_var] }
end
it do
diff --git a/spec/models/lfs_objects_project_spec.rb b/spec/models/lfs_objects_project_spec.rb
index d24d4cf7695..0a3180f43e8 100644
--- a/spec/models/lfs_objects_project_spec.rb
+++ b/spec/models/lfs_objects_project_spec.rb
@@ -1,8 +1,11 @@
require 'spec_helper'
describe LfsObjectsProject do
- subject { create(:lfs_objects_project, project: project) }
- let(:project) { create(:project) }
+ set(:project) { create(:project) }
+
+ subject do
+ create(:lfs_objects_project, project: project)
+ end
describe 'associations' do
it { is_expected.to belong_to(:project) }
@@ -11,9 +14,13 @@ describe LfsObjectsProject do
describe 'validation' do
it { is_expected.to validate_presence_of(:lfs_object_id) }
- it { is_expected.to validate_uniqueness_of(:lfs_object_id).scoped_to(:project_id).with_message("already exists in project") }
-
it { is_expected.to validate_presence_of(:project_id) }
+
+ it 'validates object id' do
+ is_expected.to validate_uniqueness_of(:lfs_object_id)
+ .scoped_to(:project_id)
+ .with_message("already exists in project")
+ end
end
describe '#update_project_statistics' do
diff --git a/spec/requests/api/services_spec.rb b/spec/requests/api/services_spec.rb
index 48d99841385..7e174903918 100644
--- a/spec/requests/api/services_spec.rb
+++ b/spec/requests/api/services_spec.rb
@@ -1,10 +1,13 @@
require "spec_helper"
describe API::Services do
- let(:user) { create(:user) }
- let(:admin) { create(:admin) }
- let(:user2) { create(:user) }
- let(:project) { create(:project, creator_id: user.id, namespace: user.namespace) }
+ set(:user) { create(:user) }
+ set(:admin) { create(:admin) }
+ set(:user2) { create(:user) }
+
+ set(:project) do
+ create(:project, creator_id: user.id, namespace: user.namespace)
+ end
Service.available_services_names.each do |service|
describe "PUT /projects/:id/services/#{service.dasherize}" do
@@ -98,8 +101,6 @@ describe API::Services do
end
describe 'POST /projects/:id/services/:slug/trigger' do
- let!(:project) { create(:project) }
-
describe 'Mattermost Service' do
let(:service_name) { 'mattermost_slash_commands' }
diff --git a/spec/services/ci/pipeline_trigger_service_spec.rb b/spec/services/ci/pipeline_trigger_service_spec.rb
index 9a6875e448c..f4ff818c479 100644
--- a/spec/services/ci/pipeline_trigger_service_spec.rb
+++ b/spec/services/ci/pipeline_trigger_service_spec.rb
@@ -34,6 +34,8 @@ describe Ci::PipelineTriggerService do
expect(result[:pipeline].ref).to eq('master')
expect(result[:pipeline].project).to eq(project)
expect(result[:pipeline].user).to eq(trigger.owner)
+ expect(result[:pipeline].trigger_requests.to_a)
+ .to eq(result[:pipeline].builds.map(&:trigger_request).uniq)
expect(result[:status]).to eq(:success)
end
diff --git a/spec/services/ci/retry_build_service_spec.rb b/spec/services/ci/retry_build_service_spec.rb
index bbc3a8c79f5..fbb3213f42b 100644
--- a/spec/services/ci/retry_build_service_spec.rb
+++ b/spec/services/ci/retry_build_service_spec.rb
@@ -1,9 +1,10 @@
require 'spec_helper'
describe Ci::RetryBuildService do
- let(:user) { create(:user) }
- let(:project) { create(:project) }
- let(:pipeline) { create(:ci_pipeline, project: project) }
+ set(:user) { create(:user) }
+ set(:project) { create(:project) }
+ set(:pipeline) { create(:ci_pipeline, project: project) }
+
let(:build) { create(:ci_build, pipeline: pipeline) }
let(:service) do
@@ -37,7 +38,7 @@ describe Ci::RetryBuildService do
:queued, :coverage, :tags, :allowed_to_fail, :on_tag,
:triggered, :trace, :teardown_environment,
description: 'my-job', stage: 'test', pipeline: pipeline,
- auto_canceled_by: create(:ci_empty_pipeline)) do |build|
+ auto_canceled_by: create(:ci_empty_pipeline, project: project)) do |build|
##
# TODO, workaround for FactoryGirl limitation when having both
# stage (text) and stage_id (integer) columns in the table.