diff options
author | Phil Hughes <me@iamphill.com> | 2017-07-06 17:27:12 +0100 |
---|---|---|
committer | Phil Hughes <me@iamphill.com> | 2017-07-06 17:27:12 +0100 |
commit | e5183d907e9db2bdf87dae83708b35a970a829ba (patch) | |
tree | edc05f30dd515cbe7ef3966a2b7aab7e835c4286 | |
parent | c85df8105e3b8982ecf6a16f8ae9f3af2f130030 (diff) | |
parent | e1a64f0c6d769c38918c50fdbd9b72b0f6fcfa4a (diff) | |
download | gitlab-ce-e5183d907e9db2bdf87dae83708b35a970a829ba.tar.gz |
Merge branch 'master' into new-nav-fix-contextual-breadcrumbs
991 files changed, 9409 insertions, 5155 deletions
diff --git a/.gitignore b/.gitignore index e529e33530a..0d6194dd1e5 100644 --- a/.gitignore +++ b/.gitignore @@ -60,3 +60,4 @@ eslint-report.html /.gitlab_workhorse_secret /webpack-report/ /locale/**/LC_MESSAGES +/.rspec diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5723b836c76..a3ce1de50c2 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -474,8 +474,6 @@ codeclimate: services: - docker:dind script: - - docker pull stedolan/jq - - docker pull codeclimate/codeclimate - docker run --env CODECLIMATE_CODE="$PWD" --volume "$PWD":/code --volume /var/run/docker.sock:/var/run/docker.sock --volume /tmp/cc:/tmp/cc codeclimate/codeclimate analyze -f json > raw_codeclimate.json - cat raw_codeclimate.json | docker run -i stedolan/jq -c 'map({check_name,fingerprint,location})' > codeclimate.json artifacts: diff --git a/.rspec b/.rspec deleted file mode 100644 index 35f4d7441e0..00000000000 --- a/.rspec +++ /dev/null @@ -1,2 +0,0 @@ ---color ---format Fuubar diff --git a/.rubocop.yml b/.rubocop.yml index 32ec60f540b..9785e7626f9 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -965,6 +965,10 @@ RSpec/AnyInstance: RSpec/BeEql: Enabled: true +# We don't enforce this as we use this technique in a few places. +RSpec/BeforeAfterAll: + Enabled: false + # Check that the first argument to the top level describe is the tested class or # module. RSpec/DescribeClass: @@ -1024,6 +1028,12 @@ RSpec/FilePath: RSpec/Focus: Enabled: true +# Configuration parameters: EnforcedStyle, SupportedStyles. +# SupportedStyles: is_expected, should +RSpec/ImplicitExpect: + Enabled: true + EnforcedStyle: is_expected + # Checks for the usage of instance variables. RSpec/InstanceVariable: Enabled: false diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 5ab4692dd60..2ec558e274f 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -6,10 +6,6 @@ # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. -# Offense count: 54 -RSpec/BeforeAfterAll: - Enabled: false - # Offense count: 233 RSpec/EmptyLineAfterFinalLet: Enabled: false @@ -24,12 +20,6 @@ RSpec/EmptyLineAfterSubject: RSpec/HookArgument: Enabled: false -# Offense count: 12 -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: is_expected, should -RSpec/ImplicitExpect: - Enabled: false - # Offense count: 11 # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: it_behaves_like, it_should_behave_like diff --git a/CHANGELOG.md b/CHANGELOG.md index 7591559da22..4d2adb47a80 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,18 @@ documentation](doc/development/changelog.md) for instructions on adding your own entry. +## 9.3.5 (2017-07-05) + +- Remove "Remove from board" button from backlog and closed list. !12430 +- Do not delete protected branches when deleting all merged branches. !12624 +- Set default for Remove source branch to false. +- Prevent accidental deletion of protected MR source branch by repeating checks before actual deletion. +- Expires full_path cache after a repository is renamed/transferred. + +## 9.3.4 (2017-07-03) + +- No changes. + ## 9.3.3 (2017-06-30) - Fix head pipeline stored in merge request for external pipelines. !12478 diff --git a/GITLAB_SHELL_VERSION b/GITLAB_SHELL_VERSION index c20c645d7e4..ac14c3dfaa8 100644 --- a/GITLAB_SHELL_VERSION +++ b/GITLAB_SHELL_VERSION @@ -1 +1 @@ -5.0.6 +5.1.1 @@ -255,7 +255,7 @@ gem 'net-ssh', '~> 3.0.1' gem 'base32', '~> 0.3.0' # Sentry integration -gem 'sentry-raven', '~> 2.4.0' +gem 'sentry-raven', '~> 2.5.3' gem 'premailer-rails', '~> 1.9.7' @@ -285,6 +285,7 @@ group :metrics do # Prometheus gem 'prometheus-client-mmap', '~>0.7.0.beta5' + gem 'raindrops', '~> 0.18' end group :development do diff --git a/Gemfile.lock b/Gemfile.lock index f4ddd30da1b..70abc0669df 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -599,8 +599,8 @@ GEM premailer-rails (1.9.7) actionmailer (>= 3, < 6) premailer (~> 1.7, >= 1.7.9) - prometheus-client-mmap (0.7.0.beta5) - mmap2 (~> 2.2.6) + prometheus-client-mmap (0.7.0.beta8) + mmap2 (~> 2.2, >= 2.2.7) pry (0.10.4) coderay (~> 1.1.0) method_source (~> 0.8.1) @@ -658,7 +658,7 @@ GEM thor (>= 0.18.1, < 2.0) rainbow (2.2.2) rake - raindrops (0.17.0) + raindrops (0.18.0) rake (10.5.0) rblineprof (0.3.6) debugger-ruby_core_source (~> 1.3) @@ -775,7 +775,7 @@ GEM activesupport (>= 3.1) select2-rails (3.5.9.3) thor (~> 0.14) - sentry-raven (2.4.0) + sentry-raven (2.5.3) faraday (>= 0.7.6, < 1.0) settingslogic (2.0.9) sexp_processor (4.9.0) @@ -1062,6 +1062,7 @@ DEPENDENCIES rails-deprecated_sanitizer (~> 1.0.3) rails-i18n (~> 4.0.9) rainbow (~> 2.2) + raindrops (~> 0.18) rblineprof (~> 0.3.6) rdoc (~> 4.2) recaptcha (~> 3.0) @@ -1089,7 +1090,7 @@ DEPENDENCIES scss_lint (~> 0.47.0) seed-fu (~> 2.3.5) select2-rails (~> 3.5.9) - sentry-raven (~> 2.4.0) + sentry-raven (~> 2.5.3) settingslogic (~> 2.0.9) sham_rack (~> 1.3.6) shoulda-matchers (~> 2.8.0) diff --git a/app/assets/javascripts/behaviors/autosize.js b/app/assets/javascripts/behaviors/autosize.js index 3bea460dcc6..e00af4b2fa8 100644 --- a/app/assets/javascripts/behaviors/autosize.js +++ b/app/assets/javascripts/behaviors/autosize.js @@ -1,23 +1,8 @@ import autosize from 'vendor/autosize'; -$(() => { - const $fields = $('.js-autosize'); +document.addEventListener('DOMContentLoaded', () => { + const autosizeEls = document.querySelectorAll('.js-autosize'); - $fields.on('autosize:resized', function resized() { - const $field = $(this); - $field.data('height', $field.outerHeight()); - }); - - $fields.on('resize.autosize', function resize() { - const $field = $(this); - if ($field.data('height') !== $field.outerHeight()) { - $field.data('height', $field.outerHeight()); - autosize.destroy($field); - $field.css('max-height', window.outerHeight); - } - }); - - autosize($fields); - autosize.update($fields); - $fields.css('resize', 'vertical'); + autosize(autosizeEls); + autosize.update(autosizeEls); }); diff --git a/app/assets/javascripts/build.js b/app/assets/javascripts/build.js index 60103155ce0..1dfa064acfd 100644 --- a/app/assets/javascripts/build.js +++ b/app/assets/javascripts/build.js @@ -13,25 +13,21 @@ window.Build = (function () { this.options = options || $('.js-build-options').data(); this.pageUrl = this.options.pageUrl; - this.buildUrl = this.options.buildUrl; this.buildStatus = this.options.buildStatus; this.state = this.options.logState; this.buildStage = this.options.buildStage; this.$document = $(document); this.logBytes = 0; - this.scrollOffsetPadding = 30; this.hasBeenScrolled = false; this.updateDropdown = this.updateDropdown.bind(this); this.getBuildTrace = this.getBuildTrace.bind(this); - this.scrollToBottom = this.scrollToBottom.bind(this); - this.$body = $('body'); this.$buildTrace = $('#build-trace'); this.$buildRefreshAnimation = $('.js-build-refresh'); this.$truncatedInfo = $('.js-truncated-info'); this.$buildTraceOutput = $('.js-build-output'); - this.$scrollContainer = $('.js-scroll-container'); + this.$topBar = $('.js-top-bar'); // Scroll controllers this.$scrollTopBtn = $('.js-scroll-up'); @@ -63,13 +59,22 @@ window.Build = (function () { .off('click') .on('click', this.scrollToBottom.bind(this)); - const scrollThrottled = _.throttle(this.toggleScroll.bind(this), 100); + this.scrollThrottled = _.throttle(this.toggleScroll.bind(this), 100); - this.$scrollContainer + $(window) .off('scroll') .on('scroll', () => { - this.hasBeenScrolled = true; - scrollThrottled(); + const contentHeight = this.$buildTraceOutput.prop('scrollHeight'); + if (contentHeight > this.windowSize) { + // means the user did not scroll, the content was updated. + this.windowSize = contentHeight; + } else { + // User scrolled + this.hasBeenScrolled = true; + this.toggleScrollAnimation(false); + } + + this.scrollThrottled(); }); $(window) @@ -77,59 +82,73 @@ window.Build = (function () { .on('resize.build', _.throttle(this.sidebarOnResize.bind(this), 100)); this.updateArtifactRemoveDate(); + this.initAffixTopArea(); - // eslint-disable-next-line - this.getBuildTrace() - .then(() => this.toggleScroll()) - .then(() => { - if (!this.hasBeenScrolled) { - this.scrollToBottom(); - } - }) - .then(() => this.verifyTopPosition()); + this.getBuildTrace(); } + Build.prototype.initAffixTopArea = function () { + /** + If the browser does not support position sticky, it returns the position as static. + If the browser does support sticky, then we allow the browser to handle it, if not + then we default back to Bootstraps affix + **/ + if (this.$topBar.css('position') !== 'static') return; + + const offsetTop = this.$buildTrace.offset().top; + + this.$topBar.affix({ + offset: { + top: offsetTop, + }, + }); + }; + Build.prototype.canScroll = function () { - return (this.$scrollContainer.prop('scrollHeight') - this.scrollOffsetPadding) > this.$scrollContainer.height(); + return document.body.scrollHeight > window.innerHeight; }; - /** - * | | Up | Down | - * |--------------------------|----------|----------| - * | on scroll bottom | active | disabled | - * | on scroll top | disabled | active | - * | no scroll | disabled | disabled | - * | on.('scroll') is on top | disabled | active | - * | on('scroll) is on bottom | active | disabled | - * - */ Build.prototype.toggleScroll = function () { - const currentPosition = this.$scrollContainer.scrollTop(); - const bottomScroll = currentPosition + this.$scrollContainer.innerHeight(); + const currentPosition = document.body.scrollTop; + const windowHeight = window.innerHeight; if (this.canScroll()) { - if (currentPosition === 0) { + if (currentPosition > 0 && + (document.body.scrollHeight - currentPosition !== windowHeight)) { + // User is in the middle of the log + + this.toggleDisableButton(this.$scrollTopBtn, false); + this.toggleDisableButton(this.$scrollBottomBtn, false); + } else if (currentPosition === 0) { + // User is at Top of Build Log + this.toggleDisableButton(this.$scrollTopBtn, true); this.toggleDisableButton(this.$scrollBottomBtn, false); - } else if (bottomScroll === this.$scrollContainer.prop('scrollHeight')) { + } else if (document.body.scrollHeight - currentPosition === windowHeight) { + // User is at the bottom of the build log. + this.toggleDisableButton(this.$scrollTopBtn, false); this.toggleDisableButton(this.$scrollBottomBtn, true); - } else { - this.toggleDisableButton(this.$scrollTopBtn, false); - this.toggleDisableButton(this.$scrollBottomBtn, false); } + } else { + this.toggleDisableButton(this.$scrollTopBtn, true); + this.toggleDisableButton(this.$scrollBottomBtn, true); } }; - Build.prototype.scrollToTop = function () { + Build.prototype.scrollDown = function () { + document.body.scrollTop = document.body.scrollHeight; + }; + + Build.prototype.scrollToBottom = function () { + this.scrollDown(); this.hasBeenScrolled = true; - this.$scrollContainer.scrollTop(0); this.toggleScroll(); }; - Build.prototype.scrollToBottom = function () { + Build.prototype.scrollToTop = function () { + document.body.scrollTop = 0; this.hasBeenScrolled = true; - this.$scrollContainer.scrollTop(this.$scrollContainer.prop('scrollHeight')); this.toggleScroll(); }; @@ -142,47 +161,6 @@ window.Build = (function () { this.$scrollBottomBtn.toggleClass('animate', toggle); }; - /** - * Build trace top position depends on the space ocupied by the elments rendered before - */ - Build.prototype.verifyTopPosition = function () { - const $buildPage = $('.build-page'); - - const $flashError = $('.alert-wrapper'); - const $header = $('.build-header', $buildPage); - const $runnersStuck = $('.js-build-stuck', $buildPage); - const $startsEnvironment = $('.js-environment-container', $buildPage); - const $erased = $('.js-build-erased', $buildPage); - const prependTopDefault = 20; - - // header + navigation + margin - let topPostion = 168; - - if ($header.length) { - topPostion += $header.outerHeight(); - } - - if ($runnersStuck.length) { - topPostion += $runnersStuck.outerHeight(); - } - - if ($startsEnvironment.length) { - topPostion += $startsEnvironment.outerHeight() + prependTopDefault; - } - - if ($erased.length) { - topPostion += $erased.outerHeight() + prependTopDefault; - } - - if ($flashError.length) { - topPostion += $flashError.outerHeight() + prependTopDefault; - } - - this.$buildTrace.css({ - top: topPostion, - }); - }; - Build.prototype.initSidebar = function () { this.$sidebar = $('.js-build-sidebar'); this.$sidebar.niceScroll(); @@ -200,6 +178,8 @@ window.Build = (function () { this.state = log.state; } + this.windowSize = this.$buildTraceOutput.prop('scrollHeight'); + if (log.append) { this.$buildTraceOutput.append(log.html); this.logBytes += log.size; @@ -227,14 +207,7 @@ window.Build = (function () { } Build.timeout = setTimeout(() => { - //eslint-disable-next-line - this.getBuildTrace() - .then(() => { - if (!this.hasBeenScrolled) { - this.scrollToBottom(); - } - }) - .then(() => this.verifyTopPosition()); + this.getBuildTrace(); }, 4000); } else { this.$buildRefreshAnimation.remove(); @@ -247,7 +220,13 @@ window.Build = (function () { }) .fail(() => { this.$buildRefreshAnimation.remove(); - }); + }) + .then(() => { + if (!this.hasBeenScrolled) { + this.scrollDown(); + } + }) + .then(() => this.toggleScroll()); }; Build.prototype.shouldHideSidebarForViewport = function () { @@ -259,14 +238,11 @@ window.Build = (function () { const shouldShow = typeof shouldHide === 'boolean' ? !shouldHide : undefined; const $toggleButton = $('.js-sidebar-build-toggle-header'); - this.$buildTrace - .toggleClass('sidebar-expanded', shouldShow) - .toggleClass('sidebar-collapsed', shouldHide); this.$sidebar .toggleClass('right-sidebar-expanded', shouldShow) .toggleClass('right-sidebar-collapsed', shouldHide); - $('.js-build-page') + this.$topBar .toggleClass('sidebar-expanded', shouldShow) .toggleClass('sidebar-collapsed', shouldHide); @@ -279,17 +255,10 @@ window.Build = (function () { Build.prototype.sidebarOnResize = function () { this.toggleSidebar(this.shouldHideSidebarForViewport()); - - this.verifyTopPosition(); - - if (this.canScroll()) { - this.toggleScroll(); - } }; Build.prototype.sidebarOnClick = function () { if (this.shouldHideSidebarForViewport()) this.toggleSidebar(); - this.verifyTopPosition(); }; Build.prototype.updateArtifactRemoveDate = function () { diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js index c42be091097..72a39fcb283 100644 --- a/app/assets/javascripts/dispatcher.js +++ b/app/assets/javascripts/dispatcher.js @@ -57,6 +57,7 @@ import GfmAutoComplete from './gfm_auto_complete'; import ShortcutsBlob from './shortcuts_blob'; import initSettingsPanels from './settings_panels'; import initExperimentalFlags from './experimental_flags'; +import OAuthRememberMe from './oauth_remember_me'; (function() { var Dispatcher; @@ -128,6 +129,7 @@ import initExperimentalFlags from './experimental_flags'; case 'sessions:new': new UsernameValidator(); new ActiveTabMemoizer(); + new OAuthRememberMe({ container: $(".omniauth-container") }).bindEvents(); break; case 'projects:boards:show': case 'projects:boards:index': diff --git a/app/assets/javascripts/environments/components/environment.vue b/app/assets/javascripts/environments/components/environment.vue index 8120ef182d4..91ed8c8467f 100644 --- a/app/assets/javascripts/environments/components/environment.vue +++ b/app/assets/javascripts/environments/components/environment.vue @@ -32,7 +32,6 @@ export default { state: store.state, visibility: 'available', isLoading: false, - isLoadingFolderContent: false, cssContainerClass: environmentsData.cssClass, endpoint: environmentsData.environmentsDataEndpoint, canCreateDeployment: environmentsData.canCreateDeployment, @@ -86,9 +85,6 @@ export default { errorCallback: this.errorCallback, notificationCallback: (isMakingRequest) => { this.isMakingRequest = isMakingRequest; - - // We need to verify if any folder is open to also fecth it - this.openFolders = this.store.getOpenFolders(); }, }); @@ -119,7 +115,7 @@ export default { this.store.toggleFolder(folder); if (!folder.isOpen) { - this.fetchChildEnvironments(folder, folderUrl); + this.fetchChildEnvironments(folder, folderUrl, true); } }, @@ -147,19 +143,17 @@ export default { .catch(this.errorCallback); }, - fetchChildEnvironments(folder, folderUrl) { - this.isLoadingFolderContent = true; + fetchChildEnvironments(folder, folderUrl, showLoader = false) { + this.store.updateEnvironmentProp(folder, 'isLoadingFolderContent', showLoader); this.service.getFolderContent(folderUrl) .then(resp => resp.json()) - .then((response) => { - this.store.setfolderContent(folder, response.environments); - this.isLoadingFolderContent = false; - }) + .then(response => this.store.setfolderContent(folder, response.environments)) + .then(() => this.store.updateEnvironmentProp(folder, 'isLoadingFolderContent', false)) .catch(() => { - this.isLoadingFolderContent = false; // eslint-disable-next-line no-new new Flash('An error occurred while fetching the environments.'); + this.store.updateEnvironmentProp(folder, 'isLoadingFolderContent', false); }); }, @@ -176,13 +170,13 @@ export default { successCallback(resp) { this.saveData(resp); - // If folders are open while polling we need to open them again - if (this.openFolders.length) { - this.openFolders.map((folder) => { + // We need to verify if any folder is open to also update it + const openFolders = this.store.getOpenFolders(); + if (openFolders.length) { + openFolders.forEach((folder) => { // TODO - Move this to the backend const folderUrl = `${window.location.pathname}/folders/${folder.folderName}`; - this.store.updateFolder(folder, 'isOpen', true); return this.fetchChildEnvironments(folder, folderUrl); }); } @@ -267,7 +261,7 @@ export default { :environments="state.environments" :can-create-deployment="canCreateDeploymentParsed" :can-read-environment="canReadEnvironmentParsed" - :is-loading-folder-content="isLoadingFolderContent" /> + /> </div> <table-pagination diff --git a/app/assets/javascripts/environments/components/environments_table.vue b/app/assets/javascripts/environments/components/environments_table.vue index b1fd9db650b..175cc8f1f72 100644 --- a/app/assets/javascripts/environments/components/environments_table.vue +++ b/app/assets/javascripts/environments/components/environments_table.vue @@ -29,12 +29,6 @@ export default { required: false, default: false, }, - - isLoadingFolderContent: { - type: Boolean, - required: false, - default: false, - }, }, methods: { @@ -74,7 +68,7 @@ export default { /> <template v-if="model.isFolder && model.isOpen && model.children && model.children.length > 0"> - <div v-if="isLoadingFolderContent"> + <div v-if="model.isLoadingFolderContent"> <loading-icon size="2" /> </div> diff --git a/app/assets/javascripts/environments/stores/environments_store.js b/app/assets/javascripts/environments/stores/environments_store.js index a5773dd7e4f..038c149be2d 100644 --- a/app/assets/javascripts/environments/stores/environments_store.js +++ b/app/assets/javascripts/environments/stores/environments_store.js @@ -35,14 +35,18 @@ export default class EnvironmentsStore { */ storeEnvironments(environments = []) { const filteredEnvironments = environments.map((env) => { + const oldEnvironmentState = this.state.environments + .find(element => element.id === env.latest.id) || {}; + let filtered = {}; if (env.size > 1) { filtered = Object.assign({}, env, { isFolder: true, + isLoadingFolderContent: oldEnvironmentState.isLoading || false, folderName: env.name, - isOpen: false, - children: [], + isOpen: oldEnvironmentState.isOpen || false, + children: oldEnvironmentState.children || [], }); } @@ -98,7 +102,7 @@ export default class EnvironmentsStore { * @return {Array} */ toggleFolder(folder) { - return this.updateFolder(folder, 'isOpen', !folder.isOpen); + return this.updateEnvironmentProp(folder, 'isOpen', !folder.isOpen); } /** @@ -125,23 +129,23 @@ export default class EnvironmentsStore { return updated; }); - return this.updateFolder(folder, 'children', updatedEnvironments); + return this.updateEnvironmentProp(folder, 'children', updatedEnvironments); } /** - * Given a folder a prop and a new value updates the correct folder. + * Given a environment, a prop and a new value updates the correct environment. * - * @param {Object} folder + * @param {Object} environment * @param {String} prop * @param {String|Boolean|Object|Array} newValue * @return {Array} */ - updateFolder(folder, prop, newValue) { + updateEnvironmentProp(environment, prop, newValue) { const environments = this.state.environments; const updatedEnvironments = environments.map((env) => { const updateEnv = Object.assign({}, env); - if (env.isFolder && env.id === folder.id) { + if (env.id === environment.id) { updateEnv[prop] = newValue; } @@ -149,8 +153,6 @@ export default class EnvironmentsStore { }); this.state.environments = updatedEnvironments; - - return updatedEnvironments; } getOpenFolders() { diff --git a/app/assets/javascripts/jobs/job_details_bundle.js b/app/assets/javascripts/jobs/job_details_bundle.js index 939d17129de..f92e669414a 100644 --- a/app/assets/javascripts/jobs/job_details_bundle.js +++ b/app/assets/javascripts/jobs/job_details_bundle.js @@ -26,14 +26,6 @@ document.addEventListener('DOMContentLoaded', () => { mounted() { this.mediator.initBuildClass(); }, - updated() { - // Wait for flash message to be appended - Vue.nextTick(() => { - if (this.mediator.build) { - this.mediator.build.verifyTopPosition(); - } - }); - }, render(createElement) { return createElement('job-header', { props: { diff --git a/app/assets/javascripts/monitoring/components/monitoring_column.vue b/app/assets/javascripts/monitoring/components/monitoring_column.vue index 4f4792877ee..0cd62053d14 100644 --- a/app/assets/javascripts/monitoring/components/monitoring_column.vue +++ b/app/assets/javascripts/monitoring/components/monitoring_column.vue @@ -35,7 +35,7 @@ data() { return { - graphHeight: 500, + graphHeight: 450, graphWidth: 600, graphHeightOffset: 120, xScale: {}, @@ -88,7 +88,9 @@ }, paddingBottomRootSvg() { - return (Math.ceil(this.graphHeight * 100) / this.graphWidth) || 0; + return { + paddingBottom: `${(Math.ceil(this.graphHeight * 100) / this.graphWidth) || 0}%`, + }; }, }, @@ -104,7 +106,7 @@ } this.data = query.result[0].values; this.unitOfDisplay = query.unit || 'N/A'; - this.yAxisLabel = this.columnData.y_axis || 'Values'; + this.yAxisLabel = this.columnData.y_label || 'Values'; this.legendTitle = query.legend || 'Average'; this.graphWidth = this.$refs.baseSvg.clientWidth - this.margin.left - this.margin.right; @@ -157,12 +159,12 @@ const xAxis = d3.svg.axis() .scale(axisXScale) - .ticks(measurements.ticks) + .ticks(measurements.xTicks) .orient('bottom'); const yAxis = d3.svg.axis() .scale(this.yScale) - .ticks(measurements.ticks) + .ticks(measurements.yTicks) .orient('left'); d3.select(this.$refs.baseSvg).select('.x-axis').call(xAxis); @@ -170,8 +172,12 @@ const width = this.graphWidth; d3.select(this.$refs.baseSvg).select('.y-axis').call(yAxis) .selectAll('.tick') - .each(function createTickLines() { - d3.select(this).select('line').attr('x2', width); + .each(function createTickLines(d, i) { + if (i > 0) { + d3.select(this).select('line') + .attr('x2', width) + .attr('class', 'axis-tick'); + } // Avoid adding the class to the first tick, to prevent coloring }); // This will select all of the ticks once they're rendered this.xScale = d3.time.scale() @@ -198,7 +204,7 @@ watch: { updateAspectRatio() { if (this.updateAspectRatio) { - this.graphHeight = 500; + this.graphHeight = 450; this.graphWidth = 600; this.measurements = measurements.large; this.draw(); @@ -216,14 +222,14 @@ <div :class="classType"> <h5 - class="text-center"> + class="text-center graph-title"> {{columnData.title}} </h5> - <div - class="prometheus-svg-container"> + <div + class="prometheus-svg-container" + :style="paddingBottomRootSvg"> <svg :viewBox="outterViewBox" - :style="{ 'padding-bottom': paddingBottomRootSvg }" ref="baseSvg"> <g class="x-axis" diff --git a/app/assets/javascripts/monitoring/components/monitoring_flag.vue b/app/assets/javascripts/monitoring/components/monitoring_flag.vue index 180a771415b..5a0e50fcab3 100644 --- a/app/assets/javascripts/monitoring/components/monitoring_flag.vue +++ b/app/assets/javascripts/monitoring/components/monitoring_flag.vue @@ -87,14 +87,14 @@ </rect> <text class="text-metric text-metric-bold" - x="8" + x="16" y="35" transform="translate(-5, 20)"> {{formatTime}} </text> <text - class="text-metric-date" - x="8" + class="text-metric" + x="16" y="15" transform="translate(-5, 20)"> {{formatDate}} diff --git a/app/assets/javascripts/monitoring/components/monitoring_legends.vue b/app/assets/javascripts/monitoring/components/monitoring_legends.vue index b30ed3cc889..922a5e1bf0e 100644 --- a/app/assets/javascripts/monitoring/components/monitoring_legends.vue +++ b/app/assets/javascripts/monitoring/components/monitoring_legends.vue @@ -109,13 +109,13 @@ </text> <rect class="rect-axis-text" - :x="xPosition + 50" + :x="xPosition + 60" :y="graphHeight - 80" - width="50" + width="35" height="50"> </rect> <text - class="label-axis-text" + class="label-axis-text x-label-text" :x="xPosition + 60" :y="yPosition" dy=".35em"> @@ -131,13 +131,13 @@ <text class="text-metric-title" x="50" - :y="graphHeight - 40"> + :y="graphHeight - 25"> {{legendTitle}} </text> <text class="text-metric-usage" x="50" - :y="graphHeight - 25"> + :y="graphHeight - 10"> {{metricUsage}} </text> </g> diff --git a/app/assets/javascripts/monitoring/utils/measurements.js b/app/assets/javascripts/monitoring/utils/measurements.js index a60d2522f49..62cd19c86e1 100644 --- a/app/assets/javascripts/monitoring/utils/measurements.js +++ b/app/assets/javascripts/monitoring/utils/measurements.js @@ -8,14 +8,14 @@ export default { }, legends: { width: 15, - height: 30, + height: 25, }, backgroundLegend: { width: 30, height: 50, }, axisLabelLineOffset: -20, - legendOffset: 52, + legendOffset: 35, }, large: { // This covers both md and lg screen sizes margin: { @@ -26,14 +26,15 @@ export default { }, legends: { width: 20, - height: 35, + height: 30, }, backgroundLegend: { width: 30, height: 150, }, axisLabelLineOffset: 20, - legendOffset: 55, + legendOffset: 38, }, - ticks: 3, + xTicks: 8, + yTicks: 3, }; diff --git a/app/assets/javascripts/oauth_remember_me.js b/app/assets/javascripts/oauth_remember_me.js new file mode 100644 index 00000000000..ffc2dd6bbca --- /dev/null +++ b/app/assets/javascripts/oauth_remember_me.js @@ -0,0 +1,32 @@ +/** + * OAuth-based login buttons have a separate "remember me" checkbox. + * + * Toggling this checkbox adds/removes a `remember_me` parameter to the + * login buttons' href, which is passed on to the omniauth callback. + **/ + +export default class OAuthRememberMe { + constructor(opts = {}) { + this.container = opts.container || ''; + this.loginLinkSelector = '.oauth-login'; + } + + bindEvents() { + $('#remember_me', this.container).on('click', this.toggleRememberMe); + } + + // eslint-disable-next-line class-methods-use-this + toggleRememberMe(event) { + const rememberMe = $(event.target).is(':checked'); + + $('.oauth-login', this.container).each((i, element) => { + const href = $(element).attr('href'); + + if (rememberMe) { + $(element).attr('href', `${href}?remember_me=1`); + } else { + $(element).attr('href', href.replace('?remember_me=1', '')); + } + }); + } +} diff --git a/app/assets/javascripts/signin_tabs_memoizer.js b/app/assets/javascripts/signin_tabs_memoizer.js index 2587facc582..3997a695d15 100644 --- a/app/assets/javascripts/signin_tabs_memoizer.js +++ b/app/assets/javascripts/signin_tabs_memoizer.js @@ -2,56 +2,54 @@ /* eslint no-new: "off" */ import AccessorUtilities from './lib/utils/accessor'; -((global) => { - /** - * Memorize the last selected tab after reloading a page. - * Does that setting the current selected tab in the localStorage - */ - class ActiveTabMemoizer { - constructor({ currentTabKey = 'current_signin_tab', tabSelector = 'ul.nav-tabs' } = {}) { - this.currentTabKey = currentTabKey; - this.tabSelector = tabSelector; - this.isLocalStorageAvailable = AccessorUtilities.isLocalStorageAccessSafe(); - - this.bootstrap(); - } - - bootstrap() { - const tabs = document.querySelectorAll(this.tabSelector); - if (tabs.length > 0) { - tabs[0].addEventListener('click', (e) => { - if (e.target && e.target.nodeName === 'A') { - const anchorName = e.target.getAttribute('href'); - this.saveData(anchorName); - } - }); - } +/** + * Memorize the last selected tab after reloading a page. + * Does that setting the current selected tab in the localStorage + */ +class ActiveTabMemoizer { + constructor({ currentTabKey = 'current_signin_tab', tabSelector = 'ul.nav-tabs' } = {}) { + this.currentTabKey = currentTabKey; + this.tabSelector = tabSelector; + this.isLocalStorageAvailable = AccessorUtilities.isLocalStorageAccessSafe(); + + this.bootstrap(); + } - this.showTab(); + bootstrap() { + const tabs = document.querySelectorAll(this.tabSelector); + if (tabs.length > 0) { + tabs[0].addEventListener('click', (e) => { + if (e.target && e.target.nodeName === 'A') { + const anchorName = e.target.getAttribute('href'); + this.saveData(anchorName); + } + }); } - showTab() { - const anchorName = this.readData(); - if (anchorName) { - const tab = document.querySelector(`${this.tabSelector} a[href="${anchorName}"]`); - if (tab) { - tab.click(); - } + this.showTab(); + } + + showTab() { + const anchorName = this.readData(); + if (anchorName) { + const tab = document.querySelector(`${this.tabSelector} a[href="${anchorName}"]`); + if (tab) { + tab.click(); } } + } - saveData(val) { - if (!this.isLocalStorageAvailable) return undefined; + saveData(val) { + if (!this.isLocalStorageAvailable) return undefined; - return window.localStorage.setItem(this.currentTabKey, val); - } + return window.localStorage.setItem(this.currentTabKey, val); + } - readData() { - if (!this.isLocalStorageAvailable) return null; + readData() { + if (!this.isLocalStorageAvailable) return null; - return window.localStorage.getItem(this.currentTabKey); - } + return window.localStorage.getItem(this.currentTabKey); } +} - global.ActiveTabMemoizer = ActiveTabMemoizer; -})(window); +window.ActiveTabMemoizer = ActiveTabMemoizer; diff --git a/app/assets/javascripts/single_file_diff.js b/app/assets/javascripts/single_file_diff.js index 9316a2af0b7..00d04ce0c33 100644 --- a/app/assets/javascripts/single_file_diff.js +++ b/app/assets/javascripts/single_file_diff.js @@ -2,99 +2,97 @@ import FilesCommentButton from './files_comment_button'; -(function() { - window.SingleFileDiff = (function() { - var COLLAPSED_HTML, ERROR_HTML, LOADING_HTML, WRAPPER; +window.SingleFileDiff = (function() { + var COLLAPSED_HTML, ERROR_HTML, LOADING_HTML, WRAPPER; - WRAPPER = '<div class="diff-content"></div>'; + WRAPPER = '<div class="diff-content"></div>'; - LOADING_HTML = '<i class="fa fa-spinner fa-spin"></i>'; + LOADING_HTML = '<i class="fa fa-spinner fa-spin"></i>'; - ERROR_HTML = '<div class="nothing-here-block"><i class="fa fa-warning"></i> Could not load diff</div>'; + ERROR_HTML = '<div class="nothing-here-block"><i class="fa fa-warning"></i> Could not load diff</div>'; - COLLAPSED_HTML = '<div class="nothing-here-block diff-collapsed">This diff is collapsed. <a class="click-to-expand">Click to expand it.</a></div>'; + COLLAPSED_HTML = '<div class="nothing-here-block diff-collapsed">This diff is collapsed. <a class="click-to-expand">Click to expand it.</a></div>'; - function SingleFileDiff(file) { - this.file = file; - this.toggleDiff = this.toggleDiff.bind(this); - this.content = $('.diff-content', this.file); - this.$toggleIcon = $('.diff-toggle-caret', this.file); - this.diffForPath = this.content.find('[data-diff-for-path]').data('diff-for-path'); - this.isOpen = !this.diffForPath; - if (this.diffForPath) { - this.collapsedContent = this.content; - this.loadingContent = $(WRAPPER).addClass('loading').html(LOADING_HTML).hide(); - this.content = null; - this.collapsedContent.after(this.loadingContent); - this.$toggleIcon.addClass('fa-caret-right'); - } else { - this.collapsedContent = $(WRAPPER).html(COLLAPSED_HTML).hide(); - this.content.after(this.collapsedContent); - this.$toggleIcon.addClass('fa-caret-down'); - } + function SingleFileDiff(file) { + this.file = file; + this.toggleDiff = this.toggleDiff.bind(this); + this.content = $('.diff-content', this.file); + this.$toggleIcon = $('.diff-toggle-caret', this.file); + this.diffForPath = this.content.find('[data-diff-for-path]').data('diff-for-path'); + this.isOpen = !this.diffForPath; + if (this.diffForPath) { + this.collapsedContent = this.content; + this.loadingContent = $(WRAPPER).addClass('loading').html(LOADING_HTML).hide(); + this.content = null; + this.collapsedContent.after(this.loadingContent); + this.$toggleIcon.addClass('fa-caret-right'); + } else { + this.collapsedContent = $(WRAPPER).html(COLLAPSED_HTML).hide(); + this.content.after(this.collapsedContent); + this.$toggleIcon.addClass('fa-caret-down'); + } + + $('.js-file-title, .click-to-expand', this.file).on('click', (function (e) { + this.toggleDiff($(e.target)); + }).bind(this)); + } - $('.js-file-title, .click-to-expand', this.file).on('click', (function (e) { - this.toggleDiff($(e.target)); - }).bind(this)); + SingleFileDiff.prototype.toggleDiff = function($target, cb) { + if (!$target.hasClass('js-file-title') && !$target.hasClass('click-to-expand') && !$target.hasClass('diff-toggle-caret')) return; + this.isOpen = !this.isOpen; + if (!this.isOpen && !this.hasError) { + this.content.hide(); + this.$toggleIcon.addClass('fa-caret-right').removeClass('fa-caret-down'); + this.collapsedContent.show(); + if (typeof gl.diffNotesCompileComponents !== 'undefined') { + gl.diffNotesCompileComponents(); + } + } else if (this.content) { + this.collapsedContent.hide(); + this.content.show(); + this.$toggleIcon.addClass('fa-caret-down').removeClass('fa-caret-right'); + if (typeof gl.diffNotesCompileComponents !== 'undefined') { + gl.diffNotesCompileComponents(); + } + } else { + this.$toggleIcon.addClass('fa-caret-down').removeClass('fa-caret-right'); + return this.getContentHTML(cb); } + }; - SingleFileDiff.prototype.toggleDiff = function($target, cb) { - if (!$target.hasClass('js-file-title') && !$target.hasClass('click-to-expand') && !$target.hasClass('diff-toggle-caret')) return; - this.isOpen = !this.isOpen; - if (!this.isOpen && !this.hasError) { - this.content.hide(); - this.$toggleIcon.addClass('fa-caret-right').removeClass('fa-caret-down'); - this.collapsedContent.show(); - if (typeof gl.diffNotesCompileComponents !== 'undefined') { - gl.diffNotesCompileComponents(); + SingleFileDiff.prototype.getContentHTML = function(cb) { + this.collapsedContent.hide(); + this.loadingContent.show(); + $.get(this.diffForPath, (function(_this) { + return function(data) { + _this.loadingContent.hide(); + if (data.html) { + _this.content = $(data.html); + _this.content.syntaxHighlight(); + } else { + _this.hasError = true; + _this.content = $(ERROR_HTML); } - } else if (this.content) { - this.collapsedContent.hide(); - this.content.show(); - this.$toggleIcon.addClass('fa-caret-down').removeClass('fa-caret-right'); + _this.collapsedContent.after(_this.content); + if (typeof gl.diffNotesCompileComponents !== 'undefined') { gl.diffNotesCompileComponents(); } - } else { - this.$toggleIcon.addClass('fa-caret-down').removeClass('fa-caret-right'); - return this.getContentHTML(cb); - } - }; - - SingleFileDiff.prototype.getContentHTML = function(cb) { - this.collapsedContent.hide(); - this.loadingContent.show(); - $.get(this.diffForPath, (function(_this) { - return function(data) { - _this.loadingContent.hide(); - if (data.html) { - _this.content = $(data.html); - _this.content.syntaxHighlight(); - } else { - _this.hasError = true; - _this.content = $(ERROR_HTML); - } - _this.collapsedContent.after(_this.content); - - if (typeof gl.diffNotesCompileComponents !== 'undefined') { - gl.diffNotesCompileComponents(); - } - FilesCommentButton.init($(_this.file)); + FilesCommentButton.init($(_this.file)); - if (cb) cb(); - }; - })(this)); - }; + if (cb) cb(); + }; + })(this)); + }; - return SingleFileDiff; - })(); + return SingleFileDiff; +})(); - $.fn.singleFileDiff = function() { - return this.each(function() { - if (!$.data(this, 'singleFileDiff')) { - return $.data(this, 'singleFileDiff', new window.SingleFileDiff(this)); - } - }); - }; -}).call(window); +$.fn.singleFileDiff = function() { + return this.each(function() { + if (!$.data(this, 'singleFileDiff')) { + return $.data(this, 'singleFileDiff', new window.SingleFileDiff(this)); + } + }); +}; diff --git a/app/assets/javascripts/smart_interval.js b/app/assets/javascripts/smart_interval.js index d1bdc353be2..2bf7a3a5d61 100644 --- a/app/assets/javascripts/smart_interval.js +++ b/app/assets/javascripts/smart_interval.js @@ -1,158 +1,157 @@ -/* -* Instances of SmartInterval extend the functionality of `setInterval`, make it configurable -* and controllable by a public API. -* -* */ - -(() => { - class SmartInterval { - /** - * @param { function } opts.callback Function to be called on each iteration (required) - * @param { milliseconds } opts.startingInterval `currentInterval` is set to this initially - * @param { milliseconds } opts.maxInterval `currentInterval` will be incremented to this - * @param { milliseconds } opts.hiddenInterval `currentInterval` is set to this - * when the page is hidden - * @param { integer } opts.incrementByFactorOf `currentInterval` is incremented by this factor - * @param { boolean } opts.lazyStart Configure if timer is initialized on - * instantiation or lazily - * @param { boolean } opts.immediateExecution Configure if callback should - * be executed before the first interval. - */ - constructor(opts = {}) { - this.cfg = { - callback: opts.callback, - startingInterval: opts.startingInterval, - maxInterval: opts.maxInterval, - hiddenInterval: opts.hiddenInterval, - incrementByFactorOf: opts.incrementByFactorOf, - lazyStart: opts.lazyStart, - immediateExecution: opts.immediateExecution, - }; - - this.state = { - intervalId: null, - currentInterval: this.cfg.startingInterval, - pageVisibility: 'visible', - }; - - this.initInterval(); - } - /* public */ - - start() { - const cfg = this.cfg; - const state = this.state; - - if (cfg.immediateExecution) { - cfg.immediateExecution = false; - cfg.callback(); - } +/** + * Instances of SmartInterval extend the functionality of `setInterval`, make it configurable + * and controllable by a public API. + */ + +class SmartInterval { + /** + * @param { function } opts.callback Function to be called on each iteration (required) + * @param { milliseconds } opts.startingInterval `currentInterval` is set to this initially + * @param { milliseconds } opts.maxInterval `currentInterval` will be incremented to this + * @param { milliseconds } opts.hiddenInterval `currentInterval` is set to this + * when the page is hidden + * @param { integer } opts.incrementByFactorOf `currentInterval` is incremented by this factor + * @param { boolean } opts.lazyStart Configure if timer is initialized on + * instantiation or lazily + * @param { boolean } opts.immediateExecution Configure if callback should + * be executed before the first interval. + */ + constructor(opts = {}) { + this.cfg = { + callback: opts.callback, + startingInterval: opts.startingInterval, + maxInterval: opts.maxInterval, + hiddenInterval: opts.hiddenInterval, + incrementByFactorOf: opts.incrementByFactorOf, + lazyStart: opts.lazyStart, + immediateExecution: opts.immediateExecution, + }; + + this.state = { + intervalId: null, + currentInterval: this.cfg.startingInterval, + pageVisibility: 'visible', + }; + + this.initInterval(); + } - state.intervalId = window.setInterval(() => { - cfg.callback(); + /* public */ - if (this.getCurrentInterval() === cfg.maxInterval) { - return; - } + start() { + const cfg = this.cfg; + const state = this.state; - this.incrementInterval(); - this.resume(); - }, this.getCurrentInterval()); + if (cfg.immediateExecution) { + cfg.immediateExecution = false; + cfg.callback(); } - // cancel the existing timer, setting the currentInterval back to startingInterval - cancel() { - this.setCurrentInterval(this.cfg.startingInterval); - this.stopTimer(); - } + state.intervalId = window.setInterval(() => { + cfg.callback(); - onVisibilityHidden() { - if (this.cfg.hiddenInterval) { - this.setCurrentInterval(this.cfg.hiddenInterval); - this.resume(); - } else { - this.cancel(); + if (this.getCurrentInterval() === cfg.maxInterval) { + return; } - } - // start a timer, using the existing interval - resume() { - this.stopTimer(); // stop exsiting timer, in case timer was not previously stopped - this.start(); - } + this.incrementInterval(); + this.resume(); + }, this.getCurrentInterval()); + } - onVisibilityVisible() { - this.cancel(); - this.start(); - } + // cancel the existing timer, setting the currentInterval back to startingInterval + cancel() { + this.setCurrentInterval(this.cfg.startingInterval); + this.stopTimer(); + } - destroy() { + onVisibilityHidden() { + if (this.cfg.hiddenInterval) { + this.setCurrentInterval(this.cfg.hiddenInterval); + this.resume(); + } else { this.cancel(); - document.removeEventListener('visibilitychange', this.handleVisibilityChange); - $(document).off('visibilitychange').off('beforeunload'); } + } - /* private */ + // start a timer, using the existing interval + resume() { + this.stopTimer(); // stop exsiting timer, in case timer was not previously stopped + this.start(); + } - initInterval() { - const cfg = this.cfg; + onVisibilityVisible() { + this.cancel(); + this.start(); + } - if (!cfg.lazyStart) { - this.start(); - } + destroy() { + this.cancel(); + document.removeEventListener('visibilitychange', this.handleVisibilityChange); + $(document).off('visibilitychange').off('beforeunload'); + } - this.initVisibilityChangeHandling(); - this.initPageUnloadHandling(); - } + /* private */ - initVisibilityChangeHandling() { - // cancel interval when tab no longer shown (prevents cached pages from polling) - document.addEventListener('visibilitychange', this.handleVisibilityChange.bind(this)); - } + initInterval() { + const cfg = this.cfg; - initPageUnloadHandling() { - // TODO: Consider refactoring in light of turbolinks removal. - // prevent interval continuing after page change, when kept in cache by Turbolinks - $(document).on('beforeunload', () => this.cancel()); + if (!cfg.lazyStart) { + this.start(); } - handleVisibilityChange(e) { - this.state.pageVisibility = e.target.visibilityState; - const intervalAction = this.isPageVisible() ? - this.onVisibilityVisible : - this.onVisibilityHidden; + this.initVisibilityChangeHandling(); + this.initPageUnloadHandling(); + } - intervalAction.apply(this); - } + initVisibilityChangeHandling() { + // cancel interval when tab no longer shown (prevents cached pages from polling) + document.addEventListener('visibilitychange', this.handleVisibilityChange.bind(this)); + } - getCurrentInterval() { - return this.state.currentInterval; - } + initPageUnloadHandling() { + // TODO: Consider refactoring in light of turbolinks removal. + // prevent interval continuing after page change, when kept in cache by Turbolinks + $(document).on('beforeunload', () => this.cancel()); + } - setCurrentInterval(newInterval) { - this.state.currentInterval = newInterval; - } + handleVisibilityChange(e) { + this.state.pageVisibility = e.target.visibilityState; + const intervalAction = this.isPageVisible() ? + this.onVisibilityVisible : + this.onVisibilityHidden; - incrementInterval() { - const cfg = this.cfg; - const currentInterval = this.getCurrentInterval(); - if (cfg.hiddenInterval && !this.isPageVisible()) return; - let nextInterval = currentInterval * cfg.incrementByFactorOf; + intervalAction.apply(this); + } - if (nextInterval > cfg.maxInterval) { - nextInterval = cfg.maxInterval; - } + getCurrentInterval() { + return this.state.currentInterval; + } + + setCurrentInterval(newInterval) { + this.state.currentInterval = newInterval; + } + + incrementInterval() { + const cfg = this.cfg; + const currentInterval = this.getCurrentInterval(); + if (cfg.hiddenInterval && !this.isPageVisible()) return; + let nextInterval = currentInterval * cfg.incrementByFactorOf; - this.setCurrentInterval(nextInterval); + if (nextInterval > cfg.maxInterval) { + nextInterval = cfg.maxInterval; } - isPageVisible() { return this.state.pageVisibility === 'visible'; } + this.setCurrentInterval(nextInterval); + } - stopTimer() { - const state = this.state; + isPageVisible() { return this.state.pageVisibility === 'visible'; } - state.intervalId = window.clearInterval(state.intervalId); - } + stopTimer() { + const state = this.state; + + state.intervalId = window.clearInterval(state.intervalId); } - gl.SmartInterval = SmartInterval; -})(window.gl || (window.gl = {})); +} + +window.gl.SmartInterval = SmartInterval; diff --git a/app/assets/javascripts/snippets_list.js b/app/assets/javascripts/snippets_list.js index 2128007113f..da7b9e08447 100644 --- a/app/assets/javascripts/snippets_list.js +++ b/app/assets/javascripts/snippets_list.js @@ -1,13 +1,9 @@ /* eslint-disable arrow-parens, no-param-reassign, space-before-function-paren, func-names, no-var, max-len */ -(global => { - global.gl = global.gl || {}; +window.gl.SnippetsList = function() { + var $holder = $('.snippets-list-holder'); - gl.SnippetsList = function() { - var $holder = $('.snippets-list-holder'); - - $holder.find('.pagination').on('ajax:success', (e, data) => { - $holder.replaceWith(data.html); - }); - }; -})(window); + $holder.find('.pagination').on('ajax:success', (e, data) => { + $holder.replaceWith(data.html); + }); +}; diff --git a/app/assets/javascripts/star.js b/app/assets/javascripts/star.js index c75b44cc2fd..840ae1edd9d 100644 --- a/app/assets/javascripts/star.js +++ b/app/assets/javascripts/star.js @@ -1,30 +1,28 @@ /* eslint-disable func-names, space-before-function-paren, wrap-iife, no-unused-vars, one-var, no-var, one-var-declaration-per-line, prefer-arrow-callback, no-new, max-len */ /* global Flash */ -(function() { - this.Star = (function() { - function Star() { - $('.project-home-panel .toggle-star').on('ajax:success', function(e, data, status, xhr) { - var $starIcon, $starSpan, $this, toggleStar; - $this = $(this); - $starSpan = $this.find('span'); - $starIcon = $this.find('i'); - toggleStar = function(isStarred) { - $this.parent().find('.star-count').text(data.star_count); - if (isStarred) { - $starSpan.removeClass('starred').text('Star'); - $starIcon.removeClass('fa-star').addClass('fa-star-o'); - } else { - $starSpan.addClass('starred').text('Unstar'); - $starIcon.removeClass('fa-star-o').addClass('fa-star'); - } - }; - toggleStar($starSpan.hasClass('starred')); - }).on('ajax:error', function(e, xhr, status, error) { - new Flash('Star toggle failed. Try again later.', 'alert'); - }); - } +window.Star = (function() { + function Star() { + $('.project-home-panel .toggle-star').on('ajax:success', function(e, data, status, xhr) { + var $starIcon, $starSpan, $this, toggleStar; + $this = $(this); + $starSpan = $this.find('span'); + $starIcon = $this.find('i'); + toggleStar = function(isStarred) { + $this.parent().find('.star-count').text(data.star_count); + if (isStarred) { + $starSpan.removeClass('starred').text('Star'); + $starIcon.removeClass('fa-star').addClass('fa-star-o'); + } else { + $starSpan.addClass('starred').text('Unstar'); + $starIcon.removeClass('fa-star-o').addClass('fa-star'); + } + }; + toggleStar($starSpan.hasClass('starred')); + }).on('ajax:error', function(e, xhr, status, error) { + new Flash('Star toggle failed. Try again later.', 'alert'); + }); + } - return Star; - })(); -}).call(window); + return Star; +})(); diff --git a/app/assets/javascripts/subscription.js b/app/assets/javascripts/subscription.js index 5f9a3e00c22..bb4d68fcd49 100644 --- a/app/assets/javascripts/subscription.js +++ b/app/assets/javascripts/subscription.js @@ -1,47 +1,45 @@ -(() => { - class Subscription { - constructor(containerElm) { - this.containerElm = containerElm; +class Subscription { + constructor(containerElm) { + this.containerElm = containerElm; - const subscribeButton = containerElm.querySelector('.js-subscribe-button'); - if (subscribeButton) { - // remove class so we don't bind twice - subscribeButton.classList.remove('js-subscribe-button'); - subscribeButton.addEventListener('click', this.toggleSubscription.bind(this)); - } + const subscribeButton = containerElm.querySelector('.js-subscribe-button'); + if (subscribeButton) { + // remove class so we don't bind twice + subscribeButton.classList.remove('js-subscribe-button'); + subscribeButton.addEventListener('click', this.toggleSubscription.bind(this)); } + } - toggleSubscription(event) { - const button = event.currentTarget; - const buttonSpan = button.querySelector('span'); - if (!buttonSpan || button.classList.contains('disabled')) { - return; - } - button.classList.add('disabled'); + toggleSubscription(event) { + const button = event.currentTarget; + const buttonSpan = button.querySelector('span'); + if (!buttonSpan || button.classList.contains('disabled')) { + return; + } + button.classList.add('disabled'); - const isSubscribed = buttonSpan.innerHTML.trim().toLowerCase() !== 'subscribe'; - const toggleActionUrl = this.containerElm.dataset.url; + const isSubscribed = buttonSpan.innerHTML.trim().toLowerCase() !== 'subscribe'; + const toggleActionUrl = this.containerElm.dataset.url; - $.post(toggleActionUrl, () => { - button.classList.remove('disabled'); + $.post(toggleActionUrl, () => { + button.classList.remove('disabled'); - // hack to allow this to work with the issue boards Vue object - if (document.querySelector('html').classList.contains('issue-boards-page')) { - gl.issueBoards.boardStoreIssueSet( - 'subscribed', - !gl.issueBoards.BoardsStore.detail.issue.subscribed, - ); - } else { - buttonSpan.innerHTML = isSubscribed ? 'Subscribe' : 'Unsubscribe'; - } - }); - } + // hack to allow this to work with the issue boards Vue object + if (document.querySelector('html').classList.contains('issue-boards-page')) { + gl.issueBoards.boardStoreIssueSet( + 'subscribed', + !gl.issueBoards.BoardsStore.detail.issue.subscribed, + ); + } else { + buttonSpan.innerHTML = isSubscribed ? 'Subscribe' : 'Unsubscribe'; + } + }); + } - static bindAll(selector) { - [].forEach.call(document.querySelectorAll(selector), elm => new Subscription(elm)); - } + static bindAll(selector) { + [].forEach.call(document.querySelectorAll(selector), elm => new Subscription(elm)); } +} - window.gl = window.gl || {}; - window.gl.Subscription = Subscription; -})(); +window.gl = window.gl || {}; +window.gl.Subscription = Subscription; diff --git a/app/assets/javascripts/subscription_select.js b/app/assets/javascripts/subscription_select.js index 0cd591c7320..a48434181b6 100644 --- a/app/assets/javascripts/subscription_select.js +++ b/app/assets/javascripts/subscription_select.js @@ -1,34 +1,33 @@ /* eslint-disable func-names, space-before-function-paren, wrap-iife, no-var, quotes, object-shorthand, no-unused-vars, no-shadow, one-var, one-var-declaration-per-line, comma-dangle, max-len */ -(function() { - this.SubscriptionSelect = (function() { - function SubscriptionSelect() { - $('.js-subscription-event').each(function(i, el) { - var fieldName; - fieldName = $(el).data("field-name"); - return $(el).glDropdown({ - selectable: true, - fieldName: fieldName, - toggleLabel: (function(_this) { - return function(selected, el, instance) { - var $item, label; - label = 'Subscription'; - $item = instance.dropdown.find('.is-active'); - if ($item.length) { - label = $item.text(); - } - return label; - }; - })(this), - clicked: function(options) { - return options.e.preventDefault(); - }, - id: function(obj, el) { - return $(el).data("id"); - } - }); + +window.SubscriptionSelect = (function() { + function SubscriptionSelect() { + $('.js-subscription-event').each(function(i, el) { + var fieldName; + fieldName = $(el).data("field-name"); + return $(el).glDropdown({ + selectable: true, + fieldName: fieldName, + toggleLabel: (function(_this) { + return function(selected, el, instance) { + var $item, label; + label = 'Subscription'; + $item = instance.dropdown.find('.is-active'); + if ($item.length) { + label = $item.text(); + } + return label; + }; + })(this), + clicked: function(options) { + return options.e.preventDefault(); + }, + id: function(obj, el) { + return $(el).data("id"); + } }); - } + }); + } - return SubscriptionSelect; - })(); -}).call(window); + return SubscriptionSelect; +})(); diff --git a/app/assets/javascripts/syntax_highlight.js b/app/assets/javascripts/syntax_highlight.js index 7c063fae045..662d6b36c16 100644 --- a/app/assets/javascripts/syntax_highlight.js +++ b/app/assets/javascripts/syntax_highlight.js @@ -9,19 +9,18 @@ // // <div class="js-syntax-highlight"></div> // -(function() { - $.fn.syntaxHighlight = function() { - var $children; - if ($(this).hasClass('js-syntax-highlight')) { - // Given the element itself, apply highlighting - return $(this).addClass(gon.user_color_scheme); - } else { - // Given a parent element, recurse to any of its applicable children - $children = $(this).find('.js-syntax-highlight'); - if ($children.length) { - return $children.syntaxHighlight(); - } +$.fn.syntaxHighlight = function() { + var $children; + + if ($(this).hasClass('js-syntax-highlight')) { + // Given the element itself, apply highlighting + return $(this).addClass(gon.user_color_scheme); + } else { + // Given a parent element, recurse to any of its applicable children + $children = $(this).find('.js-syntax-highlight'); + if ($children.length) { + return $children.syntaxHighlight(); } - }; -}).call(window); + } +}; diff --git a/app/assets/javascripts/tree.js b/app/assets/javascripts/tree.js index 76a821c7a17..77ae6109bc6 100644 --- a/app/assets/javascripts/tree.js +++ b/app/assets/javascripts/tree.js @@ -1,68 +1,66 @@ /* eslint-disable func-names, space-before-function-paren, wrap-iife, max-len, quotes, consistent-return, no-var, one-var, one-var-declaration-per-line, no-else-return, prefer-arrow-callback, max-len */ -(function() { - this.TreeView = (function() { - function TreeView() { - this.initKeyNav(); - // Code browser tree slider - // Make the entire tree-item row clickable, but not if clicking another link (like a commit message) - $(".tree-content-holder .tree-item").on('click', function(e) { - var $clickedEl, path; - $clickedEl = $(e.target); - path = $('.tree-item-file-name a', this).attr('href'); - if (!$clickedEl.is('a') && !$clickedEl.is('.str-truncated')) { - if (e.metaKey || e.which === 2) { - e.preventDefault(); - return window.open(path, '_blank'); - } else { - return gl.utils.visitUrl(path); - } +window.TreeView = (function() { + function TreeView() { + this.initKeyNav(); + // Code browser tree slider + // Make the entire tree-item row clickable, but not if clicking another link (like a commit message) + $(".tree-content-holder .tree-item").on('click', function(e) { + var $clickedEl, path; + $clickedEl = $(e.target); + path = $('.tree-item-file-name a', this).attr('href'); + if (!$clickedEl.is('a') && !$clickedEl.is('.str-truncated')) { + if (e.metaKey || e.which === 2) { + e.preventDefault(); + return window.open(path, '_blank'); + } else { + return gl.utils.visitUrl(path); } - }); - // Show the "Loading commit data" for only the first element - $('span.log_loading:first').removeClass('hide'); - } + } + }); + // Show the "Loading commit data" for only the first element + $('span.log_loading:first').removeClass('hide'); + } - TreeView.prototype.initKeyNav = function() { - var li, liSelected; - li = $("tr.tree-item"); - liSelected = null; - return $('body').keydown(function(e) { - var next, path; - if ($("input:focus").length > 0 && (e.which === 38 || e.which === 40)) { - return false; - } - if (e.which === 40) { - if (liSelected) { - next = liSelected.next(); - if (next.length > 0) { - liSelected.removeClass("selected"); - liSelected = next.addClass("selected"); - } - } else { - liSelected = li.eq(0).addClass("selected"); - } - return $(liSelected).focus(); - } else if (e.which === 38) { - if (liSelected) { - next = liSelected.prev(); - if (next.length > 0) { - liSelected.removeClass("selected"); - liSelected = next.addClass("selected"); - } - } else { - liSelected = li.last().addClass("selected"); + TreeView.prototype.initKeyNav = function() { + var li, liSelected; + li = $("tr.tree-item"); + liSelected = null; + return $('body').keydown(function(e) { + var next, path; + if ($("input:focus").length > 0 && (e.which === 38 || e.which === 40)) { + return false; + } + if (e.which === 40) { + if (liSelected) { + next = liSelected.next(); + if (next.length > 0) { + liSelected.removeClass("selected"); + liSelected = next.addClass("selected"); } - return $(liSelected).focus(); - } else if (e.which === 13) { - path = $('.tree-item.selected .tree-item-file-name a').attr('href'); - if (path) { - return gl.utils.visitUrl(path); + } else { + liSelected = li.eq(0).addClass("selected"); + } + return $(liSelected).focus(); + } else if (e.which === 38) { + if (liSelected) { + next = liSelected.prev(); + if (next.length > 0) { + liSelected.removeClass("selected"); + liSelected = next.addClass("selected"); } + } else { + liSelected = li.last().addClass("selected"); + } + return $(liSelected).focus(); + } else if (e.which === 13) { + path = $('.tree-item.selected .tree-item-file-name a').attr('href'); + if (path) { + return gl.utils.visitUrl(path); } - }); - }; + } + }); + }; - return TreeView; - })(); -}).call(window); + return TreeView; +})(); diff --git a/app/assets/javascripts/user.js b/app/assets/javascripts/user.js index 19c9efe7fbd..3ab9ef5408e 100644 --- a/app/assets/javascripts/user.js +++ b/app/assets/javascripts/user.js @@ -2,34 +2,35 @@ import Cookies from 'js-cookie'; -((global) => { - global.User = class { - constructor({ action }) { - this.action = action; - this.placeProfileAvatarsToTop(); - this.initTabs(); - this.hideProjectLimitMessage(); - } +class User { + constructor({ action }) { + this.action = action; + this.placeProfileAvatarsToTop(); + this.initTabs(); + this.hideProjectLimitMessage(); + } - placeProfileAvatarsToTop() { - $('.profile-groups-avatars').tooltip({ - placement: 'top' - }); - } + placeProfileAvatarsToTop() { + $('.profile-groups-avatars').tooltip({ + placement: 'top' + }); + } - initTabs() { - return new global.UserTabs({ - parentEl: '.user-profile', - action: this.action - }); - } + initTabs() { + return new window.gl.UserTabs({ + parentEl: '.user-profile', + action: this.action + }); + } - hideProjectLimitMessage() { - $('.hide-project-limit-message').on('click', e => { - e.preventDefault(); - Cookies.set('hide_project_limit_message', 'false'); - $(this).parents('.project-limit-message').remove(); - }); - } - }; -})(window.gl || (window.gl = {})); + hideProjectLimitMessage() { + $('.hide-project-limit-message').on('click', e => { + e.preventDefault(); + Cookies.set('hide_project_limit_message', 'false'); + $(this).parents('.project-limit-message').remove(); + }); + } +} + +window.gl = window.gl || {}; +window.gl.User = User; diff --git a/app/assets/javascripts/user_tabs.js b/app/assets/javascripts/user_tabs.js index ce7eb76dc71..be70f4cb4e2 100644 --- a/app/assets/javascripts/user_tabs.js +++ b/app/assets/javascripts/user_tabs.js @@ -59,117 +59,118 @@ content on the Users#show page. </div> </div> */ -((global) => { - class UserTabs { - constructor ({ defaultAction, action, parentEl }) { - this.loaded = {}; - this.defaultAction = defaultAction || 'activity'; - this.action = action || this.defaultAction; - this.$parentEl = $(parentEl) || $(document); - this._location = window.location; - this.$parentEl.find('.nav-links a') - .each((i, navLink) => { - this.loaded[$(navLink).attr('data-action')] = false; - }); - this.actions = Object.keys(this.loaded); - this.bindEvents(); - - if (this.action === 'show') { - this.action = this.defaultAction; - } - this.activateTab(this.action); +class UserTabs { + constructor ({ defaultAction, action, parentEl }) { + this.loaded = {}; + this.defaultAction = defaultAction || 'activity'; + this.action = action || this.defaultAction; + this.$parentEl = $(parentEl) || $(document); + this._location = window.location; + this.$parentEl.find('.nav-links a') + .each((i, navLink) => { + this.loaded[$(navLink).attr('data-action')] = false; + }); + this.actions = Object.keys(this.loaded); + this.bindEvents(); + + if (this.action === 'show') { + this.action = this.defaultAction; } - bindEvents() { - this.changeProjectsPageWrapper = this.changeProjectsPage.bind(this); + this.activateTab(this.action); + } - this.$parentEl.off('shown.bs.tab', '.nav-links a[data-toggle="tab"]') - .on('shown.bs.tab', '.nav-links a[data-toggle="tab"]', event => this.tabShown(event)); + bindEvents() { + this.changeProjectsPageWrapper = this.changeProjectsPage.bind(this); - this.$parentEl.on('click', '.gl-pagination a', this.changeProjectsPageWrapper); - } + this.$parentEl.off('shown.bs.tab', '.nav-links a[data-toggle="tab"]') + .on('shown.bs.tab', '.nav-links a[data-toggle="tab"]', event => this.tabShown(event)); - changeProjectsPage(e) { - e.preventDefault(); + this.$parentEl.on('click', '.gl-pagination a', this.changeProjectsPageWrapper); + } - $('.tab-pane.active').empty(); - const endpoint = $(e.target).attr('href'); - this.loadTab(this.getCurrentAction(), endpoint); - } + changeProjectsPage(e) { + e.preventDefault(); - tabShown(event) { - const $target = $(event.target); - const action = $target.data('action'); - const source = $target.attr('href'); - const endpoint = $target.data('endpoint'); - this.setTab(action, endpoint); - return this.setCurrentAction(source); - } + $('.tab-pane.active').empty(); + const endpoint = $(e.target).attr('href'); + this.loadTab(this.getCurrentAction(), endpoint); + } - activateTab(action) { - return this.$parentEl.find(`.nav-links .js-${action}-tab a`) - .tab('show'); - } + tabShown(event) { + const $target = $(event.target); + const action = $target.data('action'); + const source = $target.attr('href'); + const endpoint = $target.data('endpoint'); + this.setTab(action, endpoint); + return this.setCurrentAction(source); + } - setTab(action, endpoint) { - if (this.loaded[action]) { - return; - } - if (action === 'activity') { - this.loadActivities(); - } + activateTab(action) { + return this.$parentEl.find(`.nav-links .js-${action}-tab a`) + .tab('show'); + } - const loadableActions = ['groups', 'contributed', 'projects', 'snippets']; - if (loadableActions.indexOf(action) > -1) { - return this.loadTab(action, endpoint); - } + setTab(action, endpoint) { + if (this.loaded[action]) { + return; + } + if (action === 'activity') { + this.loadActivities(); } - loadTab(action, endpoint) { - return $.ajax({ - beforeSend: () => this.toggleLoading(true), - complete: () => this.toggleLoading(false), - dataType: 'json', - type: 'GET', - url: endpoint, - success: (data) => { - const tabSelector = `div#${action}`; - this.$parentEl.find(tabSelector).html(data.html); - this.loaded[action] = true; - return gl.utils.localTimeAgo($('.js-timeago', tabSelector)); - } - }); + const loadableActions = ['groups', 'contributed', 'projects', 'snippets']; + if (loadableActions.indexOf(action) > -1) { + return this.loadTab(action, endpoint); } + } - loadActivities() { - if (this.loaded['activity']) { - return; + loadTab(action, endpoint) { + return $.ajax({ + beforeSend: () => this.toggleLoading(true), + complete: () => this.toggleLoading(false), + dataType: 'json', + type: 'GET', + url: endpoint, + success: (data) => { + const tabSelector = `div#${action}`; + this.$parentEl.find(tabSelector).html(data.html); + this.loaded[action] = true; + return gl.utils.localTimeAgo($('.js-timeago', tabSelector)); } - const $calendarWrap = this.$parentEl.find('.user-calendar'); - $calendarWrap.load($calendarWrap.data('href')); - new gl.Activities(); - return this.loaded['activity'] = true; - } + }); + } - toggleLoading(status) { - return this.$parentEl.find('.loading-status .loading') - .toggle(status); + loadActivities() { + if (this.loaded['activity']) { + return; } + const $calendarWrap = this.$parentEl.find('.user-calendar'); + $calendarWrap.load($calendarWrap.data('href')); + new gl.Activities(); + return this.loaded['activity'] = true; + } - setCurrentAction(source) { - let new_state = source; - new_state = new_state.replace(/\/+$/, ''); - new_state += this._location.search + this._location.hash; - history.replaceState({ - url: new_state - }, document.title, new_state); - return new_state; - } + toggleLoading(status) { + return this.$parentEl.find('.loading-status .loading') + .toggle(status); + } - getCurrentAction() { - return this.$parentEl.find('.nav-links .active a').data('action'); - } + setCurrentAction(source) { + let new_state = source; + new_state = new_state.replace(/\/+$/, ''); + new_state += this._location.search + this._location.hash; + history.replaceState({ + url: new_state + }, document.title, new_state); + return new_state; } - global.UserTabs = UserTabs; -})(window.gl || (window.gl = {})); + + getCurrentAction() { + return this.$parentEl.find('.nav-links .active a').data('action'); + } +} + +window.gl = window.gl || {}; +window.gl.UserTabs = UserTabs; diff --git a/app/assets/javascripts/username_validator.js b/app/assets/javascripts/username_validator.js index 137cefa3b8e..abe6c30f4f3 100644 --- a/app/assets/javascripts/username_validator.js +++ b/app/assets/javascripts/username_validator.js @@ -1,135 +1,133 @@ /* eslint-disable comma-dangle, consistent-return, class-methods-use-this, arrow-parens, no-param-reassign, max-len */ -((global) => { - const debounceTimeoutDuration = 1000; - const invalidInputClass = 'gl-field-error-outline'; - const successInputClass = 'gl-field-success-outline'; - const unavailableMessageSelector = '.username .validation-error'; - const successMessageSelector = '.username .validation-success'; - const pendingMessageSelector = '.username .validation-pending'; - const invalidMessageSelector = '.username .gl-field-error'; - - class UsernameValidator { - constructor() { - this.inputElement = $('#new_user_username'); - this.inputDomElement = this.inputElement.get(0); - this.state = { - available: false, - valid: false, - pending: false, - empty: true - }; - - const debounceTimeout = _.debounce((username) => { - this.validateUsername(username); - }, debounceTimeoutDuration); - - this.inputElement.on('keyup.username_check', () => { - const username = this.inputElement.val(); - - this.state.valid = this.inputDomElement.validity.valid; - this.state.empty = !username.length; - - if (this.state.valid) { - return debounceTimeout(username); - } - - this.renderState(); - }); - - // Override generic field validation - this.inputElement.on('invalid', this.interceptInvalid.bind(this)); - } +const debounceTimeoutDuration = 1000; +const invalidInputClass = 'gl-field-error-outline'; +const successInputClass = 'gl-field-success-outline'; +const unavailableMessageSelector = '.username .validation-error'; +const successMessageSelector = '.username .validation-success'; +const pendingMessageSelector = '.username .validation-pending'; +const invalidMessageSelector = '.username .gl-field-error'; + +class UsernameValidator { + constructor() { + this.inputElement = $('#new_user_username'); + this.inputDomElement = this.inputElement.get(0); + this.state = { + available: false, + valid: false, + pending: false, + empty: true + }; + + const debounceTimeout = _.debounce((username) => { + this.validateUsername(username); + }, debounceTimeoutDuration); + + this.inputElement.on('keyup.username_check', () => { + const username = this.inputElement.val(); + + this.state.valid = this.inputDomElement.validity.valid; + this.state.empty = !username.length; - renderState() { - // Clear all state - this.clearFieldValidationState(); - - if (this.state.valid && this.state.available) { - return this.setSuccessState(); + if (this.state.valid) { + return debounceTimeout(username); } - if (this.state.empty) { - return this.clearFieldValidationState(); - } + this.renderState(); + }); - if (this.state.pending) { - return this.setPendingState(); - } + // Override generic field validation + this.inputElement.on('invalid', this.interceptInvalid.bind(this)); + } - if (!this.state.available) { - return this.setUnavailableState(); - } + renderState() { + // Clear all state + this.clearFieldValidationState(); - if (!this.state.valid) { - return this.setInvalidState(); - } + if (this.state.valid && this.state.available) { + return this.setSuccessState(); } - interceptInvalid(event) { - event.preventDefault(); - event.stopPropagation(); + if (this.state.empty) { + return this.clearFieldValidationState(); } - validateUsername(username) { - if (this.state.valid) { - this.state.pending = true; - this.state.available = false; - this.renderState(); - return $.ajax({ - type: 'GET', - url: `${gon.relative_url_root}/users/${username}/exists`, - dataType: 'json', - success: (res) => this.setAvailabilityState(res.exists) - }); - } + if (this.state.pending) { + return this.setPendingState(); } - setAvailabilityState(usernameTaken) { - if (usernameTaken) { - this.state.valid = false; - this.state.available = false; - } else { - this.state.available = true; - } - this.state.pending = false; - this.renderState(); + if (!this.state.available) { + return this.setUnavailableState(); } - clearFieldValidationState() { - this.inputElement.siblings('p').hide(); - - this.inputElement.removeClass(invalidInputClass) - .removeClass(successInputClass); + if (!this.state.valid) { + return this.setInvalidState(); } + } - setUnavailableState() { - const $usernameUnavailableMessage = this.inputElement.siblings(unavailableMessageSelector); - this.inputElement.addClass(invalidInputClass).removeClass(successInputClass); - $usernameUnavailableMessage.show(); - } + interceptInvalid(event) { + event.preventDefault(); + event.stopPropagation(); + } - setSuccessState() { - const $usernameSuccessMessage = this.inputElement.siblings(successMessageSelector); - this.inputElement.addClass(successInputClass).removeClass(invalidInputClass); - $usernameSuccessMessage.show(); + validateUsername(username) { + if (this.state.valid) { + this.state.pending = true; + this.state.available = false; + this.renderState(); + return $.ajax({ + type: 'GET', + url: `${gon.relative_url_root}/users/${username}/exists`, + dataType: 'json', + success: (res) => this.setAvailabilityState(res.exists) + }); } + } - setPendingState() { - const $usernamePendingMessage = $(pendingMessageSelector); - if (this.state.pending) { - $usernamePendingMessage.show(); - } else { - $usernamePendingMessage.hide(); - } + setAvailabilityState(usernameTaken) { + if (usernameTaken) { + this.state.valid = false; + this.state.available = false; + } else { + this.state.available = true; } + this.state.pending = false; + this.renderState(); + } + + clearFieldValidationState() { + this.inputElement.siblings('p').hide(); - setInvalidState() { - const $inputErrorMessage = $(invalidMessageSelector); - this.inputElement.addClass(invalidInputClass).removeClass(successInputClass); - $inputErrorMessage.show(); + this.inputElement.removeClass(invalidInputClass) + .removeClass(successInputClass); + } + + setUnavailableState() { + const $usernameUnavailableMessage = this.inputElement.siblings(unavailableMessageSelector); + this.inputElement.addClass(invalidInputClass).removeClass(successInputClass); + $usernameUnavailableMessage.show(); + } + + setSuccessState() { + const $usernameSuccessMessage = this.inputElement.siblings(successMessageSelector); + this.inputElement.addClass(successInputClass).removeClass(invalidInputClass); + $usernameSuccessMessage.show(); + } + + setPendingState() { + const $usernamePendingMessage = $(pendingMessageSelector); + if (this.state.pending) { + $usernamePendingMessage.show(); + } else { + $usernamePendingMessage.hide(); } } - global.UsernameValidator = UsernameValidator; -})(window); + setInvalidState() { + const $inputErrorMessage = $(invalidMessageSelector); + this.inputElement.addClass(invalidInputClass).removeClass(successInputClass); + $inputErrorMessage.show(); + } +} + +window.UsernameValidator = UsernameValidator; diff --git a/app/assets/javascripts/users_select.js b/app/assets/javascripts/users_select.js index 46efdcf4202..5728afb4c59 100644 --- a/app/assets/javascripts/users_select.js +++ b/app/assets/javascripts/users_select.js @@ -206,8 +206,6 @@ function UsersSelect(currentUser, els) { return $dropdown.glDropdown({ showMenuAbove: showMenuAbove, data: function(term, callback) { - var isAuthorFilter; - isAuthorFilter = $('.js-author-search'); return _this.users(term, options, function(users) { // GitLabDropdownFilter returns this.instance // GitLabDropdownRemote returns this.options.instance diff --git a/app/assets/javascripts/visibility_select.js b/app/assets/javascripts/visibility_select.js index f712d7ba930..b6bbbaa0936 100644 --- a/app/assets/javascripts/visibility_select.js +++ b/app/assets/javascripts/visibility_select.js @@ -1,27 +1,24 @@ -(() => { - const gl = window.gl || (window.gl = {}); - - class VisibilitySelect { - constructor(container) { - if (!container) throw new Error('VisibilitySelect requires a container element as argument 1'); - this.container = container; - this.helpBlock = this.container.querySelector('.help-block'); - this.select = this.container.querySelector('select'); - } +class VisibilitySelect { + constructor(container) { + if (!container) throw new Error('VisibilitySelect requires a container element as argument 1'); + this.container = container; + this.helpBlock = this.container.querySelector('.help-block'); + this.select = this.container.querySelector('select'); + } - init() { - if (this.select) { - this.updateHelpText(); - this.select.addEventListener('change', this.updateHelpText.bind(this)); - } else { - this.helpBlock.textContent = this.container.querySelector('.js-locked').dataset.helpBlock; - } + init() { + if (this.select) { + this.updateHelpText(); + this.select.addEventListener('change', this.updateHelpText.bind(this)); + } else { + this.helpBlock.textContent = this.container.querySelector('.js-locked').dataset.helpBlock; } + } - updateHelpText() { - this.helpBlock.textContent = this.select.querySelector('option:checked').dataset.description; - } + updateHelpText() { + this.helpBlock.textContent = this.select.querySelector('option:checked').dataset.description; } +} - gl.VisibilitySelect = VisibilitySelect; -})(); +window.gl = window.gl || {}; +window.gl.VisibilitySelect = VisibilitySelect; diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.js b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.js index e8b3cf2f729..c02e10128e2 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.js +++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.js @@ -17,9 +17,6 @@ export default { return hasCI && !ciStatus; }, - hasPipeline() { - return Object.keys(this.mr.pipeline || {}).length > 0; - }, svg() { return statusIconEntityMap.icon_status_failed; }, @@ -33,11 +30,7 @@ export default { template: ` <div class="mr-widget-heading"> <div class="ci-widget"> - <template v-if="!hasPipeline"> - <i class="fa fa-spinner fa-spin append-right-10" aria-hidden="true"></i> - Waiting for pipeline... - </template> - <template v-else-if="hasCIError"> + <template v-if="hasCIError"> <div class="ci-status-icon ci-status-icon-failed ci-error js-ci-error"> <span class="js-icon-link icon-link"> <span diff --git a/app/assets/javascripts/wikis.js b/app/assets/javascripts/wikis.js index 4194c1bc08d..03d183ebd84 100644 --- a/app/assets/javascripts/wikis.js +++ b/app/assets/javascripts/wikis.js @@ -4,66 +4,65 @@ import 'vendor/jquery.nicescroll'; import './breakpoints'; -((global) => { - class Wikis { - constructor() { - this.bp = Breakpoints.get(); - this.sidebarEl = document.querySelector('.js-wiki-sidebar'); - this.sidebarExpanded = false; - $(this.sidebarEl).niceScroll(); +class Wikis { + constructor() { + this.bp = Breakpoints.get(); + this.sidebarEl = document.querySelector('.js-wiki-sidebar'); + this.sidebarExpanded = false; + $(this.sidebarEl).niceScroll(); - const sidebarToggles = document.querySelectorAll('.js-sidebar-wiki-toggle'); - for (let i = 0; i < sidebarToggles.length; i += 1) { - sidebarToggles[i].addEventListener('click', e => this.handleToggleSidebar(e)); - } - - this.newWikiForm = document.querySelector('form.new-wiki-page'); - if (this.newWikiForm) { - this.newWikiForm.addEventListener('submit', e => this.handleNewWikiSubmit(e)); - } + const sidebarToggles = document.querySelectorAll('.js-sidebar-wiki-toggle'); + for (let i = 0; i < sidebarToggles.length; i += 1) { + sidebarToggles[i].addEventListener('click', e => this.handleToggleSidebar(e)); + } - window.addEventListener('resize', () => this.renderSidebar()); - this.renderSidebar(); + this.newWikiForm = document.querySelector('form.new-wiki-page'); + if (this.newWikiForm) { + this.newWikiForm.addEventListener('submit', e => this.handleNewWikiSubmit(e)); } - handleNewWikiSubmit(e) { - if (!this.newWikiForm) return; + window.addEventListener('resize', () => this.renderSidebar()); + this.renderSidebar(); + } - const slugInput = this.newWikiForm.querySelector('#new_wiki_path'); - const slug = gl.text.slugify(slugInput.value); + handleNewWikiSubmit(e) { + if (!this.newWikiForm) return; - if (slug.length > 0) { - const wikisPath = slugInput.getAttribute('data-wikis-path'); - window.location.href = `${wikisPath}/${slug}`; - e.preventDefault(); - } - } + const slugInput = this.newWikiForm.querySelector('#new_wiki_path'); + const slug = gl.text.slugify(slugInput.value); - handleToggleSidebar(e) { + if (slug.length > 0) { + const wikisPath = slugInput.getAttribute('data-wikis-path'); + window.location.href = `${wikisPath}/${slug}`; e.preventDefault(); - this.sidebarExpanded = !this.sidebarExpanded; - this.renderSidebar(); } + } - sidebarCanCollapse() { - const bootstrapBreakpoint = this.bp.getBreakpointSize(); - return bootstrapBreakpoint === 'xs' || bootstrapBreakpoint === 'sm'; - } + handleToggleSidebar(e) { + e.preventDefault(); + this.sidebarExpanded = !this.sidebarExpanded; + this.renderSidebar(); + } + + sidebarCanCollapse() { + const bootstrapBreakpoint = this.bp.getBreakpointSize(); + return bootstrapBreakpoint === 'xs' || bootstrapBreakpoint === 'sm'; + } - renderSidebar() { - if (!this.sidebarEl) return; - const { classList } = this.sidebarEl; - if (this.sidebarExpanded || !this.sidebarCanCollapse()) { - if (!classList.contains('right-sidebar-expanded')) { - classList.remove('right-sidebar-collapsed'); - classList.add('right-sidebar-expanded'); - } - } else if (classList.contains('right-sidebar-expanded')) { - classList.add('right-sidebar-collapsed'); - classList.remove('right-sidebar-expanded'); + renderSidebar() { + if (!this.sidebarEl) return; + const { classList } = this.sidebarEl; + if (this.sidebarExpanded || !this.sidebarCanCollapse()) { + if (!classList.contains('right-sidebar-expanded')) { + classList.remove('right-sidebar-collapsed'); + classList.add('right-sidebar-expanded'); } + } else if (classList.contains('right-sidebar-expanded')) { + classList.add('right-sidebar-collapsed'); + classList.remove('right-sidebar-expanded'); } } +} - global.Wikis = Wikis; -})(window.gl || (window.gl = {})); +window.gl = window.gl || {}; +window.gl.Wikis = Wikis; diff --git a/app/assets/javascripts/zen_mode.js b/app/assets/javascripts/zen_mode.js index b7fe552dec2..08f80735e93 100644 --- a/app/assets/javascripts/zen_mode.js +++ b/app/assets/javascripts/zen_mode.js @@ -34,65 +34,64 @@ window.Dropzone = Dropzone; // **Cancelable** No // **Target** a.js-zen-leave // -(function() { - this.ZenMode = (function() { - function ZenMode() { - this.active_backdrop = null; - this.active_textarea = null; - $(document).on('click', '.js-zen-enter', function(e) { - e.preventDefault(); - return $(e.currentTarget).trigger('zen_mode:enter'); - }); - $(document).on('click', '.js-zen-leave', function(e) { + +window.ZenMode = (function() { + function ZenMode() { + this.active_backdrop = null; + this.active_textarea = null; + $(document).on('click', '.js-zen-enter', function(e) { + e.preventDefault(); + return $(e.currentTarget).trigger('zen_mode:enter'); + }); + $(document).on('click', '.js-zen-leave', function(e) { + e.preventDefault(); + return $(e.currentTarget).trigger('zen_mode:leave'); + }); + $(document).on('zen_mode:enter', (function(_this) { + return function(e) { + return _this.enter($(e.target).closest('.md-area').find('.zen-backdrop')); + }; + })(this)); + $(document).on('zen_mode:leave', (function(_this) { + return function(e) { + return _this.exit(); + }; + })(this)); + $(document).on('keydown', function(e) { + // Esc + if (e.keyCode === 27) { e.preventDefault(); - return $(e.currentTarget).trigger('zen_mode:leave'); - }); - $(document).on('zen_mode:enter', (function(_this) { - return function(e) { - return _this.enter($(e.target).closest('.md-area').find('.zen-backdrop')); - }; - })(this)); - $(document).on('zen_mode:leave', (function(_this) { - return function(e) { - return _this.exit(); - }; - })(this)); - $(document).on('keydown', function(e) { - // Esc - if (e.keyCode === 27) { - e.preventDefault(); - return $(document).trigger('zen_mode:leave'); - } - }); - } + return $(document).trigger('zen_mode:leave'); + } + }); + } - ZenMode.prototype.enter = function(backdrop) { - Mousetrap.pause(); - this.active_backdrop = $(backdrop); - this.active_backdrop.addClass('fullscreen'); - this.active_textarea = this.active_backdrop.find('textarea'); - // Prevent a user-resized textarea from persisting to fullscreen - this.active_textarea.removeAttr('style'); - return this.active_textarea.focus(); - }; + ZenMode.prototype.enter = function(backdrop) { + Mousetrap.pause(); + this.active_backdrop = $(backdrop); + this.active_backdrop.addClass('fullscreen'); + this.active_textarea = this.active_backdrop.find('textarea'); + // Prevent a user-resized textarea from persisting to fullscreen + this.active_textarea.removeAttr('style'); + return this.active_textarea.focus(); + }; - ZenMode.prototype.exit = function() { - if (this.active_textarea) { - Mousetrap.unpause(); - this.active_textarea.closest('.zen-backdrop').removeClass('fullscreen'); - this.scrollTo(this.active_textarea); - this.active_textarea = null; - this.active_backdrop = null; - return Dropzone.forElement('.div-dropzone').enable(); - } - }; + ZenMode.prototype.exit = function() { + if (this.active_textarea) { + Mousetrap.unpause(); + this.active_textarea.closest('.zen-backdrop').removeClass('fullscreen'); + this.scrollTo(this.active_textarea); + this.active_textarea = null; + this.active_backdrop = null; + return Dropzone.forElement('.div-dropzone').enable(); + } + }; - ZenMode.prototype.scrollTo = function(zen_area) { - return $.scrollTo(zen_area, 0, { - offset: -150 - }); - }; + ZenMode.prototype.scrollTo = function(zen_area) { + return $.scrollTo(zen_area, 0, { + offset: -150 + }); + }; - return ZenMode; - })(); -}).call(window); + return ZenMode; +})(); diff --git a/app/assets/stylesheets/framework/files.scss b/app/assets/stylesheets/framework/files.scss index 245117b2559..c7c2684d548 100644 --- a/app/assets/stylesheets/framework/files.scss +++ b/app/assets/stylesheets/framework/files.scss @@ -17,6 +17,8 @@ max-width: $limited-layout-width-sm; margin-left: auto; margin-right: auto; + padding-top: 64px; + padding-bottom: 64px; } } diff --git a/app/assets/stylesheets/framework/sidebar.scss b/app/assets/stylesheets/framework/sidebar.scss index 5cf9330b8f8..542b641e3dd 100644 --- a/app/assets/stylesheets/framework/sidebar.scss +++ b/app/assets/stylesheets/framework/sidebar.scss @@ -92,7 +92,7 @@ @mixin maintain-sidebar-dimensions { display: block; width: $gutter-width; - padding: 10px 20px; + padding: 10px 0; } .issues-bulk-update.right-sidebar { diff --git a/app/assets/stylesheets/framework/wells.scss b/app/assets/stylesheets/framework/wells.scss index 1c1392f8f67..b1ff2659131 100644 --- a/app/assets/stylesheets/framework/wells.scss +++ b/app/assets/stylesheets/framework/wells.scss @@ -3,6 +3,7 @@ color: $gl-text-color; border: 1px solid $border-color; border-radius: $border-radius-default; + margin-bottom: $gl-padding; .well-segment { padding: $gl-padding; @@ -21,6 +22,11 @@ font-size: 12px; } } + + &.admin-well h4 { + border-bottom: 1px solid $border-color; + padding-bottom: 8px; + } } .icon-container { @@ -53,6 +59,14 @@ padding: 15px; } +.dark-well { + background-color: $gray-normal; + + .btn { + width: 100%; + } +} + .well-centered { h1 { font-weight: normal; diff --git a/app/assets/stylesheets/pages/builds.scss b/app/assets/stylesheets/pages/builds.scss index 9cff99b839c..23c06eca3c3 100644 --- a/app/assets/stylesheets/pages/builds.scss +++ b/app/assets/stylesheets/pages/builds.scss @@ -37,65 +37,77 @@ } .build-page { - .sticky { - position: absolute; - left: 0; - right: 0; + .build-trace-container { + position: relative; } - .build-trace-container { - position: absolute; - top: 225px; - left: 15px; - bottom: 10px; + .build-trace { background: $black; color: $gray-darkest; - font-family: $monospace_font; + white-space: pre; + overflow-x: auto; font-size: 12px; + border-radius: 0; + border: none; - &.sidebar-expanded { - right: 305px; + .bash { + display: block; } + } - &.sidebar-collapsed { - right: 16px; + .top-bar { + height: 35px; + display: flex; + justify-content: flex-end; + background: $gray-light; + border: 1px solid $border-color; + color: $gl-text-color; + position: sticky; + position: -webkit-sticky; + top: 50px; + + &.affix { + top: 50px; } - code { - background: $black; - color: $gray-darkest; + // with sidebar + &.affix.sidebar-expanded { + right: 306px; + left: 16px; } - .top-bar { - top: 0; - height: 35px; - display: flex; - justify-content: flex-end; - background: $gray-light; - border: 1px solid $border-color; - color: $gl-text-color; + // without sidebar + &.affix.sidebar-collapsed { + right: 16px; + left: 16px; + } - .truncated-info { - margin: 0 auto; - align-self: center; + &.affix-top { + position: absolute; + right: 0; + left: 0; + } - .truncated-info-size { - margin: 0 5px; - } + .truncated-info { + margin: 0 auto; + align-self: center; - .raw-link { - color: $gl-text-color; - margin-left: 5px; - text-decoration: underline; - } + .truncated-info-size { + margin: 0 5px; + } + + .raw-link { + color: $gl-text-color; + margin-left: 5px; + text-decoration: underline; } } .controllers { display: flex; - align-self: center; font-size: 15px; - margin-bottom: 4px; + justify-content: center; + align-items: center; svg { height: 15px; @@ -103,17 +115,9 @@ fill: $gl-text-color; } - .controllers-buttons, - .btn-scroll { - color: $gl-text-color; - height: 15px; - vertical-align: middle; - padding: 0; - width: 12px; - } - .controllers-buttons { - margin: 1px 10px; + color: $gl-text-color; + margin: 0 10px; } .btn-scroll.animate { @@ -143,15 +147,6 @@ } } - .bash { - top: 35px; - left: 10px; - bottom: 0; - padding: 10px 20px 20px 5px; - white-space: pre-wrap; - overflow: auto; - } - .environment-information { border: 1px solid $border-color; padding: 8px $gl-padding 12px; diff --git a/app/assets/stylesheets/pages/environments.scss b/app/assets/stylesheets/pages/environments.scss index a2be957655f..00ebf4e26ac 100644 --- a/app/assets/stylesheets/pages/environments.scss +++ b/app/assets/stylesheets/pages/environments.scss @@ -187,8 +187,7 @@ } .text-metric { - font-weight: 600; - font-size: 14px; + font-size: 12px; } .selected-metric-line { @@ -232,10 +231,6 @@ width: 100%; padding: 0; padding-bottom: 100%; - - .text-metric-bold { - font-weight: 600; - } } .prometheus-svg-container > svg { @@ -250,11 +245,15 @@ stroke-width: 0; } + .text-metric-bold { + font-weight: 600; + } + .label-axis-text, .text-metric-usage { fill: $black; font-weight: 500; - font-size: 14px; + font-size: 12px; } .legend-axis-text { @@ -262,7 +261,20 @@ } .tick > text { - font-size: 14px; + font-size: 12px; + } + + .text-metric-title { + font-size: 12px; + } + + .y-label-text, + .x-label-text { + fill: $gray-darkest; + } + + .axis-tick { + stroke: $gray-darker; } @media (max-width: $screen-sm-max) { @@ -277,3 +289,9 @@ } } } + +.prometheus-row { + h5 { + font-size: 16px; + } +} diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss index 057d457b3a2..47f50083726 100644 --- a/app/assets/stylesheets/pages/issuable.scss +++ b/app/assets/stylesheets/pages/issuable.scss @@ -200,7 +200,6 @@ right: 0; transition: width .3s; background: $gray-light; - padding: 0 20px; z-index: 200; overflow: hidden; @@ -224,6 +223,10 @@ } } + .issuable-sidebar { + padding: 0 20px; + } + .issuable-sidebar-header { padding-top: 10px; } diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss index ba530bf7f9b..7d7c34115f9 100644 --- a/app/assets/stylesheets/pages/projects.scss +++ b/app/assets/stylesheets/pages/projects.scss @@ -483,11 +483,12 @@ a.deploy-project-label { .project-stats { font-size: 0; text-align: center; + max-width: 100%; + border-bottom: 1px solid $border-color; .nav { padding-top: 12px; padding-bottom: 12px; - border-bottom: 1px solid $border-color; } .nav > li { diff --git a/app/assets/stylesheets/pages/runners.scss b/app/assets/stylesheets/pages/runners.scss index 9b6ff237557..57c73295d1e 100644 --- a/app/assets/stylesheets/pages/runners.scss +++ b/app/assets/stylesheets/pages/runners.scss @@ -33,3 +33,20 @@ font-weight: normal; } } + +.admin-runner-btn-group-cell { + min-width: 150px; + + .btn-sm { + padding: 4px 9px; + } + + .btn-default { + color: $gl-text-color-secondary; + } + + .fa-pause, + .fa-play { + font-size: 11px; + } +} diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb index 4d4b8a8425f..f978ce478c7 100644 --- a/app/controllers/admin/application_settings_controller.rb +++ b/app/controllers/admin/application_settings_controller.rb @@ -71,6 +71,8 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController params[:application_setting][:disabled_oauth_sign_in_sources] = AuthHelper.button_based_providers.map(&:to_s) - Array(enabled_oauth_sign_in_sources) + + params[:application_setting][:restricted_visibility_levels]&.delete("") params.delete(:domain_blacklist_raw) if params[:domain_blacklist_file] params.require(:application_setting).permit( diff --git a/app/controllers/admin/projects_controller.rb b/app/controllers/admin/projects_controller.rb index a1975c0e341..984d5398708 100644 --- a/app/controllers/admin/projects_controller.rb +++ b/app/controllers/admin/projects_controller.rb @@ -40,14 +40,14 @@ class Admin::ProjectsController < Admin::ApplicationController ::Projects::TransferService.new(@project, current_user, params.dup).execute(namespace) @project.reload - redirect_to admin_namespace_project_path(@project.namespace, @project) + redirect_to admin_project_path(@project) end def repository_check RepositoryCheck::SingleRepositoryWorker.perform_async(@project.id) redirect_to( - admin_namespace_project_path(@project.namespace, @project), + admin_project_path(@project), notice: 'Repository check was triggered.' ) end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 824ce845706..b4c0cd0487f 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -110,6 +110,8 @@ class ApplicationController < ActionController::Base end def log_exception(exception) + Raven.capture_exception(exception) if sentry_enabled? + application_trace = ActionDispatch::ExceptionWrapper.new(env, exception).application_trace application_trace.map!{ |t| " #{t}\n" } logger.error "\n#{exception.class.name} (#{exception.message}):\n#{application_trace.join}" diff --git a/app/controllers/concerns/creates_commit.rb b/app/controllers/concerns/creates_commit.rb index f87db4d9e84..782f0be9c4a 100644 --- a/app/controllers/concerns/creates_commit.rb +++ b/app/controllers/concerns/creates_commit.rb @@ -78,8 +78,7 @@ module CreatesCommit end def new_merge_request_path - namespace_project_new_merge_request_path( - @project_to_commit_into.namespace, + project_new_merge_request_path( @project_to_commit_into, merge_request: { source_project_id: @project_to_commit_into.id, @@ -91,7 +90,7 @@ module CreatesCommit end def existing_merge_request_path - namespace_project_merge_request_path(@project.namespace, @project, @merge_request) + project_merge_request_path(@project, @merge_request) end def merge_request_exists? diff --git a/app/controllers/concerns/milestone_actions.rb b/app/controllers/concerns/milestone_actions.rb index 1ff785ac2ca..081f3336780 100644 --- a/app/controllers/concerns/milestone_actions.rb +++ b/app/controllers/concerns/milestone_actions.rb @@ -45,7 +45,7 @@ module MilestoneActions def milestone_redirect_path if @project - namespace_project_milestone_path(@project.namespace, @project, @milestone) + project_milestone_path(@project, @milestone) elsif @group group_milestone_path(@group, @milestone.safe_title, title: @milestone.title) else diff --git a/app/controllers/concerns/repository_settings_redirect.rb b/app/controllers/concerns/repository_settings_redirect.rb index 0854c73a02f..0576f0e6e70 100644 --- a/app/controllers/concerns/repository_settings_redirect.rb +++ b/app/controllers/concerns/repository_settings_redirect.rb @@ -2,6 +2,6 @@ module RepositorySettingsRedirect extend ActiveSupport::Concern def redirect_to_repository_settings(project) - redirect_to namespace_project_settings_repository_path(project.namespace, project) + redirect_to project_settings_repository_path(project) end end diff --git a/app/controllers/concerns/spammable_actions.rb b/app/controllers/concerns/spammable_actions.rb index b68d76aeff0..ada0dde87fb 100644 --- a/app/controllers/concerns/spammable_actions.rb +++ b/app/controllers/concerns/spammable_actions.rb @@ -9,9 +9,9 @@ module SpammableActions def mark_as_spam if SpamService.new(spammable).mark_as_spam! - redirect_to spammable, notice: "#{spammable.spammable_entity_type.titlecase} was submitted to Akismet successfully." + redirect_to spammable_path, notice: "#{spammable.spammable_entity_type.titlecase} was submitted to Akismet successfully." else - redirect_to spammable, alert: 'Error with Akismet. Please check the logs for more info.' + redirect_to spammable_path, alert: 'Error with Akismet. Please check the logs for more info.' end end @@ -25,7 +25,7 @@ module SpammableActions def recaptcha_check_with_fallback(&fallback) if spammable.valid? - redirect_to spammable + redirect_to spammable_path elsif render_recaptcha? ensure_spam_config_loaded! @@ -56,6 +56,10 @@ module SpammableActions raise NotImplementedError, "#{self.class} does not implement #{__method__}" end + def spammable_path + raise NotImplementedError, "#{self.class} does not implement #{__method__}" + end + def authorize_submit_spammable! access_denied! unless current_user.admin? end diff --git a/app/controllers/groups/milestones_controller.rb b/app/controllers/groups/milestones_controller.rb index e52fa766044..6b1d418fc9a 100644 --- a/app/controllers/groups/milestones_controller.rb +++ b/app/controllers/groups/milestones_controller.rb @@ -11,6 +11,9 @@ class Groups::MilestonesController < Groups::ApplicationController @milestone_states = GlobalMilestone.states_count(@projects) @milestones = Kaminari.paginate_array(milestones).page(params[:page]) end + format.json do + render json: milestones.map { |m| m.for_display.slice(:title, :name) } + end end end diff --git a/app/controllers/invites_controller.rb b/app/controllers/invites_controller.rb index 7625187c7be..0982a61902b 100644 --- a/app/controllers/invites_controller.rb +++ b/app/controllers/invites_controller.rb @@ -63,7 +63,7 @@ class InvitesController < ApplicationController when Project project = member.source label = "project #{project.name_with_namespace}" - path = namespace_project_path(project.namespace, project) + path = project_path(project) when Group group = member.source label = "group #{group.name}" diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb index b82681b197e..323d5d26eb6 100644 --- a/app/controllers/omniauth_callbacks_controller.rb +++ b/app/controllers/omniauth_callbacks_controller.rb @@ -1,5 +1,6 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController include AuthenticatesWithTwoFactor + include Devise::Controllers::Rememberable protect_from_forgery except: [:kerberos, :saml, :cas3] @@ -115,8 +116,10 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController if @user.persisted? && @user.valid? log_audit_event(@user, with: oauth['provider']) if @user.two_factor_enabled? + params[:remember_me] = '1' if remember_me? prompt_for_two_factor(@user) else + remember_me(@user) if remember_me? sign_in_and_redirect(@user) end else @@ -147,4 +150,9 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController AuditEventService.new(user, user, options) .for_authentication.security_event end + + def remember_me? + request_params = request.env['omniauth.params'] + (request_params['remember_me'] == '1') if request_params.present? + end end diff --git a/app/controllers/projects/application_controller.rb b/app/controllers/projects/application_controller.rb index 3d7ce4f0222..95de3a44641 100644 --- a/app/controllers/projects/application_controller.rb +++ b/app/controllers/projects/application_controller.rb @@ -76,13 +76,13 @@ class Projects::ApplicationController < ApplicationController def require_non_empty_project # Be sure to return status code 303 to avoid a double DELETE: # http://api.rubyonrails.org/classes/ActionController/Redirecting.html - redirect_to namespace_project_path(@project.namespace, @project), status: 303 if @project.empty_repo? + redirect_to project_path(@project), status: 303 if @project.empty_repo? end def require_branch_head unless @repository.branch_exists?(@ref) redirect_to( - namespace_project_tree_path(@project.namespace, @project, @ref), + project_tree_path(@project, @ref), notice: "This action is not allowed unless you are on a branch" ) end diff --git a/app/controllers/projects/artifacts_controller.rb b/app/controllers/projects/artifacts_controller.rb index ea036b1f705..f637a9a803b 100644 --- a/app/controllers/projects/artifacts_controller.rb +++ b/app/controllers/projects/artifacts_controller.rb @@ -46,7 +46,7 @@ class Projects::ArtifactsController < Projects::ApplicationController def keep build.keep_artifacts! - redirect_to namespace_project_job_path(project.namespace, project, build) + redirect_to project_job_path(project, build) end def latest_succeeded diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb index a82d6fd5a4a..49ea2945675 100644 --- a/app/controllers/projects/blob_controller.rb +++ b/app/controllers/projects/blob_controller.rb @@ -27,9 +27,9 @@ class Projects::BlobController < Projects::ApplicationController def create create_commit(Files::CreateService, success_notice: "The file has been successfully created.", - success_path: -> { namespace_project_blob_path(@project.namespace, @project, File.join(@branch_name, @file_path)) }, + success_path: -> { project_blob_path(@project, File.join(@branch_name, @file_path)) }, failure_view: :new, - failure_path: namespace_project_new_blob_path(@project.namespace, @project, @ref)) + failure_path: project_new_blob_path(@project, @ref)) end def show @@ -63,7 +63,7 @@ class Projects::BlobController < Projects::ApplicationController @path = params[:file_path] if params[:file_path].present? create_commit(Files::UpdateService, success_path: -> { after_edit_path }, failure_view: :edit, - failure_path: namespace_project_blob_path(@project.namespace, @project, @id)) + failure_path: project_blob_path(@project, @id)) rescue Files::UpdateService::FileChangedError @conflict = true @@ -83,9 +83,9 @@ class Projects::BlobController < Projects::ApplicationController def destroy create_commit(Files::DeleteService, success_notice: "The file has been successfully deleted.", - success_path: -> { namespace_project_tree_path(@project.namespace, @project, @branch_name) }, + success_path: -> { project_tree_path(@project, @branch_name) }, failure_view: :show, - failure_path: namespace_project_blob_path(@project.namespace, @project, @id)) + failure_path: project_blob_path(@project, @id)) end def diff @@ -118,7 +118,7 @@ class Projects::BlobController < Projects::ApplicationController else if tree = @repository.tree(@commit.id, @path) if tree.entries.any? - return redirect_to namespace_project_tree_path(@project.namespace, @project, File.join(@ref, @path)) + return redirect_to project_tree_path(@project, File.join(@ref, @path)) end end @@ -143,10 +143,10 @@ class Projects::BlobController < Projects::ApplicationController def after_edit_path from_merge_request = MergeRequestsFinder.new(current_user, project_id: @project.id).execute.find_by(iid: params[:from_merge_request_iid]) if from_merge_request && @branch_name == @ref - diffs_namespace_project_merge_request_path(from_merge_request.target_project.namespace, from_merge_request.target_project, from_merge_request) + + diffs_project_merge_request_path(from_merge_request.target_project, from_merge_request) + "##{hexdigest(@path)}" else - namespace_project_blob_path(@project.namespace, @project, File.join(@branch_name, @path)) + project_blob_path(@project, File.join(@branch_name, @path)) end end diff --git a/app/controllers/projects/branches_controller.rb b/app/controllers/projects/branches_controller.rb index 94a752c21eb..86058531179 100644 --- a/app/controllers/projects/branches_controller.rb +++ b/app/controllers/projects/branches_controller.rb @@ -52,7 +52,7 @@ class Projects::BranchesController < Projects::ApplicationController redirect_to url_to_autodeploy_setup(project, branch_name), notice: view_context.autodeploy_flash_notice(branch_name) else - redirect_to namespace_project_tree_path(@project.namespace, @project, branch_name) + redirect_to project_tree_path(@project, branch_name) end else @error = result[:message] @@ -62,7 +62,7 @@ class Projects::BranchesController < Projects::ApplicationController format.json do if result[:status] == :success - render json: { name: branch_name, url: namespace_project_tree_url(@project.namespace, @project, branch_name) } + render json: { name: branch_name, url: project_tree_url(@project, branch_name) } else render json: result[:messsage], status: :unprocessable_entity end @@ -79,7 +79,7 @@ class Projects::BranchesController < Projects::ApplicationController flash_type = result[:status] == :error ? :alert : :notice flash[flash_type] = result[:message] - redirect_to namespace_project_branches_path(@project.namespace, @project), status: 303 + redirect_to project_branches_path(@project), status: 303 end format.js { render nothing: true, status: result[:return_code] } @@ -90,7 +90,7 @@ class Projects::BranchesController < Projects::ApplicationController def destroy_all_merged DeleteMergedBranchesService.new(@project, current_user).async_execute - redirect_to namespace_project_branches_path(@project.namespace, @project), + redirect_to project_branches_path(@project), notice: 'Merged branches are being deleted. This can take some time depending on the number of branches. Please refresh the page to see changes.' end @@ -106,8 +106,7 @@ class Projects::BranchesController < Projects::ApplicationController end def url_to_autodeploy_setup(project, branch_name) - namespace_project_new_blob_path( - project.namespace, + project_new_blob_path( project, branch_name, file_name: '.gitlab-ci.yml', diff --git a/app/controllers/projects/build_artifacts_controller.rb b/app/controllers/projects/build_artifacts_controller.rb index f34a198634e..b45e5d7ff43 100644 --- a/app/controllers/projects/build_artifacts_controller.rb +++ b/app/controllers/projects/build_artifacts_controller.rb @@ -7,23 +7,23 @@ class Projects::BuildArtifactsController < Projects::ApplicationController before_action :validate_artifacts! def download - redirect_to download_namespace_project_job_artifacts_path(project.namespace, project, job) + redirect_to download_project_job_artifacts_path(project, job) end def browse - redirect_to browse_namespace_project_job_artifacts_path(project.namespace, project, job, path: params[:path]) + redirect_to browse_project_job_artifacts_path(project, job, path: params[:path]) end def file - redirect_to file_namespace_project_job_artifacts_path(project.namespace, project, job, path: params[:path]) + redirect_to file_project_job_artifacts_path(project, job, path: params[:path]) end def raw - redirect_to raw_namespace_project_job_artifacts_path(project.namespace, project, job, path: params[:path]) + redirect_to raw_project_job_artifacts_path(project, job, path: params[:path]) end def latest_succeeded - redirect_to latest_succeeded_namespace_project_artifacts_path(project.namespace, project, job, ref_name_and_path: params[:ref_name_and_path], job: params[:job]) + redirect_to latest_succeeded_project_artifacts_path(project, job, ref_name_and_path: params[:ref_name_and_path], job: params[:job]) end private diff --git a/app/controllers/projects/builds_controller.rb b/app/controllers/projects/builds_controller.rb index 1334a231788..230b072dcea 100644 --- a/app/controllers/projects/builds_controller.rb +++ b/app/controllers/projects/builds_controller.rb @@ -2,15 +2,15 @@ class Projects::BuildsController < Projects::ApplicationController before_action :authorize_read_build! def index - redirect_to namespace_project_jobs_path(project.namespace, project) + redirect_to project_jobs_path(project) end def show - redirect_to namespace_project_job_path(project.namespace, project, job) + redirect_to project_job_path(project, job) end def raw - redirect_to raw_namespace_project_job_path(project.namespace, project, job) + redirect_to raw_project_job_path(project, job) end private diff --git a/app/controllers/projects/commit_controller.rb b/app/controllers/projects/commit_controller.rb index 7c3cce1c241..14a1e11a6ea 100644 --- a/app/controllers/projects/commit_controller.rb +++ b/app/controllers/projects/commit_controller.rb @@ -80,16 +80,16 @@ class Projects::CommitController < Projects::ApplicationController end def successful_change_path - referenced_merge_request_url || namespace_project_commits_url(@project.namespace, @project, @branch_name) + referenced_merge_request_url || project_commits_url(@project, @branch_name) end def failed_change_path - referenced_merge_request_url || namespace_project_commit_url(@project.namespace, @project, params[:id]) + referenced_merge_request_url || project_commit_url(@project, params[:id]) end def referenced_merge_request_url if merge_request = @commit.merged_merge_request(current_user) - namespace_project_merge_request_url(merge_request.target_project.namespace, merge_request.target_project, merge_request) + project_merge_request_url(merge_request.target_project, merge_request) end end diff --git a/app/controllers/projects/compare_controller.rb b/app/controllers/projects/compare_controller.rb index ef400c4d745..c8613c0d634 100644 --- a/app/controllers/projects/compare_controller.rb +++ b/app/controllers/projects/compare_controller.rb @@ -31,9 +31,9 @@ class Projects::CompareController < Projects::ApplicationController from: params[:from].presence, to: params[:to].presence } - redirect_to namespace_project_compare_index_path(@project.namespace, @project, from_to_vars) + redirect_to project_compare_index_path(@project, from_to_vars) else - redirect_to namespace_project_compare_path(@project.namespace, @project, + redirect_to project_compare_path(@project, params[:from], params[:to]) end end diff --git a/app/controllers/projects/environments_controller.rb b/app/controllers/projects/environments_controller.rb index f88a1ffd1e9..29e223a5273 100644 --- a/app/controllers/projects/environments_controller.rb +++ b/app/controllers/projects/environments_controller.rb @@ -15,6 +15,8 @@ class Projects::EnvironmentsController < Projects::ApplicationController respond_to do |format| format.html format.json do + Gitlab::PollingInterval.set_header(response, interval: 3_000) + render json: { environments: EnvironmentSerializer .new(project: @project, current_user: @current_user) @@ -63,7 +65,7 @@ class Projects::EnvironmentsController < Projects::ApplicationController @environment = project.environments.create(environment_params) if @environment.persisted? - redirect_to namespace_project_environment_path(project.namespace, project, @environment) + redirect_to project_environment_path(project, @environment) else render :new end @@ -71,7 +73,7 @@ class Projects::EnvironmentsController < Projects::ApplicationController def update if @environment.update(environment_params) - redirect_to namespace_project_environment_path(project.namespace, project, @environment) + redirect_to project_environment_path(project, @environment) else render :edit end @@ -86,7 +88,7 @@ class Projects::EnvironmentsController < Projects::ApplicationController if stop_action polymorphic_url([project.namespace.becomes(Namespace), project, stop_action]) else - namespace_project_environment_url(project.namespace, project, @environment) + project_environment_url(project, @environment) end respond_to do |format| diff --git a/app/controllers/projects/forks_controller.rb b/app/controllers/projects/forks_controller.rb index 1eb3800e49d..3f83bef2c79 100644 --- a/app/controllers/projects/forks_controller.rb +++ b/app/controllers/projects/forks_controller.rb @@ -44,12 +44,12 @@ class Projects::ForksController < Projects::ApplicationController if @forked_project.saved? && @forked_project.forked? if @forked_project.import_in_progress? - redirect_to namespace_project_import_path(@forked_project.namespace, @forked_project, continue: continue_params) + redirect_to project_import_path(@forked_project, continue: continue_params) else if continue_params redirect_to continue_params[:to], notice: continue_params[:notice] else - redirect_to namespace_project_path(@forked_project.namespace, @forked_project), notice: "The project '#{@forked_project.name}' was successfully forked." + redirect_to project_path(@forked_project), notice: "The project '#{@forked_project.name}' was successfully forked." end end else diff --git a/app/controllers/projects/graphs_controller.rb b/app/controllers/projects/graphs_controller.rb index df5221fe95f..57372f9e79d 100644 --- a/app/controllers/projects/graphs_controller.rb +++ b/app/controllers/projects/graphs_controller.rb @@ -29,7 +29,7 @@ class Projects::GraphsController < Projects::ApplicationController end def ci - redirect_to charts_namespace_project_pipelines_path(@project.namespace, @project) + redirect_to charts_project_pipelines_path(@project) end private diff --git a/app/controllers/projects/group_links_controller.rb b/app/controllers/projects/group_links_controller.rb index deb33a2f0ff..8fc614b414d 100644 --- a/app/controllers/projects/group_links_controller.rb +++ b/app/controllers/projects/group_links_controller.rb @@ -22,7 +22,7 @@ class Projects::GroupLinksController < Projects::ApplicationController flash[:alert] = 'Please select a group.' end - redirect_to namespace_project_settings_members_path(project.namespace, project) + redirect_to project_settings_members_path(project) end def update @@ -36,7 +36,7 @@ class Projects::GroupLinksController < Projects::ApplicationController respond_to do |format| format.html do - redirect_to namespace_project_settings_members_path(project.namespace, project), status: 302 + redirect_to project_settings_members_path(project), status: 302 end format.js { head :ok } end diff --git a/app/controllers/projects/hook_logs_controller.rb b/app/controllers/projects/hook_logs_controller.rb index 354f0d6db3a..b9c4b29580a 100644 --- a/app/controllers/projects/hook_logs_controller.rb +++ b/app/controllers/projects/hook_logs_controller.rb @@ -18,7 +18,7 @@ class Projects::HookLogsController < Projects::ApplicationController set_hook_execution_notice(status, message) - redirect_to edit_namespace_project_hook_path(@project.namespace, @project, @hook) + redirect_to edit_project_hook_path(@project, @hook) end private diff --git a/app/controllers/projects/hooks_controller.rb b/app/controllers/projects/hooks_controller.rb index f5143280154..18895c3f0f3 100644 --- a/app/controllers/projects/hooks_controller.rb +++ b/app/controllers/projects/hooks_controller.rb @@ -17,7 +17,7 @@ class Projects::HooksController < Projects::ApplicationController @hooks = @project.hooks.select(&:persisted?) flash[:alert] = @hook.errors.full_messages.join.html_safe end - redirect_to namespace_project_settings_integrations_path(@project.namespace, @project) + redirect_to project_settings_integrations_path(@project) end def edit @@ -26,7 +26,7 @@ class Projects::HooksController < Projects::ApplicationController def update if hook.update_attributes(hook_params) flash[:notice] = 'Hook was successfully updated.' - redirect_to namespace_project_settings_integrations_path(@project.namespace, @project) + redirect_to project_settings_integrations_path(@project) else render 'edit' end @@ -47,7 +47,7 @@ class Projects::HooksController < Projects::ApplicationController def destroy hook.destroy - redirect_to namespace_project_settings_integrations_path(@project.namespace, @project), status: 302 + redirect_to project_settings_integrations_path(@project), status: 302 end private diff --git a/app/controllers/projects/imports_controller.rb b/app/controllers/projects/imports_controller.rb index 4b143434ea5..49aa32119ef 100644 --- a/app/controllers/projects/imports_controller.rb +++ b/app/controllers/projects/imports_controller.rb @@ -17,7 +17,7 @@ class Projects::ImportsController < Projects::ApplicationController @project.reload.import_schedule end - redirect_to namespace_project_import_path(@project.namespace, @project) + redirect_to project_import_path(@project) end def show @@ -25,10 +25,10 @@ class Projects::ImportsController < Projects::ApplicationController if continue_params redirect_to continue_params[:to], notice: continue_params[:notice] else - redirect_to namespace_project_path(@project.namespace, @project), notice: finished_notice + redirect_to project_path(@project), notice: finished_notice end elsif @project.import_failed? - redirect_to new_namespace_project_import_path(@project.namespace, @project) + redirect_to new_project_import_path(@project) else if continue_params && continue_params[:notice_now] flash.now[:notice] = continue_params[:notice_now] @@ -50,19 +50,19 @@ class Projects::ImportsController < Projects::ApplicationController def require_no_repo if @project.repository_exists? - redirect_to namespace_project_path(@project.namespace, @project) + redirect_to project_path(@project) end end def redirect_if_progress if @project.import_in_progress? - redirect_to namespace_project_import_path(@project.namespace, @project) + redirect_to project_import_path(@project) end end def redirect_if_no_import if @project.repository_exists? && @project.no_import? - redirect_to namespace_project_path(@project.namespace, @project) + redirect_to project_path(@project) end end end diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb index ca483c105b6..c9e636fb65e 100644 --- a/app/controllers/projects/issues_controller.rb +++ b/app/controllers/projects/issues_controller.rb @@ -227,7 +227,7 @@ class Projects::IssuesController < Projects::ApplicationController def issue return @issue if defined?(@issue) # The Sortable default scope causes performance issues when used with find_by - @noteable = @issue ||= @project.issues.where(iid: params[:id]).reorder(nil).take! + @noteable = @issue ||= @project.issues.find_by!(iid: params[:id]) return render_404 unless can?(current_user, :read_issue, @issue) @@ -238,6 +238,10 @@ class Projects::IssuesController < Projects::ApplicationController alias_method :awardable, :issue alias_method :spammable, :issue + def spammable_path + project_issue_path(@project, @issue) + end + def authorize_update_issue! return render_404 unless can?(current_user, :update_issue, @issue) end diff --git a/app/controllers/projects/jobs_controller.rb b/app/controllers/projects/jobs_controller.rb index cb4f46388fd..96abdac91b6 100644 --- a/app/controllers/projects/jobs_controller.rb +++ b/app/controllers/projects/jobs_controller.rb @@ -38,7 +38,7 @@ class Projects::JobsController < Projects::ApplicationController build.cancel if can?(current_user, :update_build, build) end - redirect_to namespace_project_jobs_path(project.namespace, project) + redirect_to project_jobs_path(project) end def show @@ -108,7 +108,7 @@ class Projects::JobsController < Projects::ApplicationController def erase if @build.erase(erased_by: current_user) - redirect_to namespace_project_job_path(project.namespace, project, @build), + redirect_to project_job_path(project, @build), notice: "Build has been successfully erased!" else respond_422 @@ -137,6 +137,6 @@ class Projects::JobsController < Projects::ApplicationController end def build_path(build) - namespace_project_job_path(build.project.namespace, build.project, build) + project_job_path(build.project, build) end end diff --git a/app/controllers/projects/labels_controller.rb b/app/controllers/projects/labels_controller.rb index daa973c9281..480a2dff262 100644 --- a/app/controllers/projects/labels_controller.rb +++ b/app/controllers/projects/labels_controller.rb @@ -33,7 +33,7 @@ class Projects::LabelsController < Projects::ApplicationController if @label.valid? respond_to do |format| - format.html { redirect_to namespace_project_labels_path(@project.namespace, @project) } + format.html { redirect_to project_labels_path(@project) } format.json { render json: @label } end else @@ -51,7 +51,7 @@ class Projects::LabelsController < Projects::ApplicationController @label = Labels::UpdateService.new(label_params).execute(@label) if @label.valid? - redirect_to namespace_project_labels_path(@project.namespace, @project) + redirect_to project_labels_path(@project) else render :edit end @@ -61,12 +61,11 @@ class Projects::LabelsController < Projects::ApplicationController Gitlab::IssuesLabels.generate(@project) if params[:redirect] == 'issues' - redirect_to namespace_project_issues_path(@project.namespace, @project) + redirect_to project_issues_path(@project) elsif params[:redirect] == 'merge_requests' - redirect_to namespace_project_merge_requests_path(@project.namespace, - @project) + redirect_to project_merge_requests_path(@project) else - redirect_to namespace_project_labels_path(@project.namespace, @project) + redirect_to project_labels_path(@project) end end @@ -74,7 +73,7 @@ class Projects::LabelsController < Projects::ApplicationController @label.destroy @labels = find_labels - redirect_to namespace_project_labels_path(@project.namespace, @project), + redirect_to project_labels_path(@project), status: 302, notice: 'Label was removed' end @@ -114,7 +113,7 @@ class Projects::LabelsController < Projects::ApplicationController return render_404 unless promote_service.execute(@label) respond_to do |format| format.html do - redirect_to(namespace_project_labels_path(@project.namespace, @project), + redirect_to(project_labels_path(@project), notice: 'Label was promoted to a Group Label') end format.js @@ -125,7 +124,7 @@ class Projects::LabelsController < Projects::ApplicationController respond_to do |format| format.html do - redirect_to(namespace_project_labels_path(@project.namespace, @project), + redirect_to(project_labels_path(@project), notice: 'Failed to promote label due to internal error. Please contact administrators.') end format.js diff --git a/app/controllers/projects/mattermosts_controller.rb b/app/controllers/projects/mattermosts_controller.rb index 38f7e6eb5e9..0f6add3e287 100644 --- a/app/controllers/projects/mattermosts_controller.rb +++ b/app/controllers/projects/mattermosts_controller.rb @@ -16,12 +16,10 @@ class Projects::MattermostsController < Projects::ApplicationController if result flash[:notice] = 'This service is now configured' - redirect_to edit_namespace_project_service_path( - @project.namespace, @project, service) + redirect_to edit_project_service_path(@project, service) else flash[:alert] = message || 'Failed to configure service' - redirect_to new_namespace_project_mattermost_path( - @project.namespace, @project) + redirect_to new_project_mattermost_path(@project) end end diff --git a/app/controllers/projects/merge_requests/conflicts_controller.rb b/app/controllers/projects/merge_requests/conflicts_controller.rb index a71f23e790d..28afef101a9 100644 --- a/app/controllers/projects/merge_requests/conflicts_controller.rb +++ b/app/controllers/projects/merge_requests/conflicts_controller.rb @@ -52,7 +52,7 @@ class Projects::MergeRequests::ConflictsController < Projects::MergeRequests::Ap flash[:notice] = 'All merge conflicts were resolved. The merge request can now be merged.' - render json: { redirect_to: namespace_project_merge_request_url(@project.namespace, @project, @merge_request, resolved_conflicts: true) } + render json: { redirect_to: project_merge_request_url(@project, @merge_request, resolved_conflicts: true) } rescue Gitlab::Conflict::ResolutionError => e render status: :bad_request, json: { message: e.message } end diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index 04f8e95aa09..a573b392591 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -211,21 +211,18 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo stop_url = if environment.stop_action? && can?(current_user, :create_deployment, environment) - stop_namespace_project_environment_path(project.namespace, project, environment) + stop_project_environment_path(project, environment) end metrics_url = if can?(current_user, :read_environment, environment) && environment.has_metrics? - metrics_namespace_project_environment_deployment_path(environment.project.namespace, - environment.project, - environment, - deployment) + metrics_project_environment_deployment_path(environment.project, environment, deployment) end { id: environment.id, name: environment.name, - url: namespace_project_environment_path(project.namespace, project, environment), + url: project_environment_path(project, environment), metrics_url: metrics_url, stop_url: stop_url, external_url: environment.external_url, diff --git a/app/controllers/projects/milestones_controller.rb b/app/controllers/projects/milestones_controller.rb index 953b1e83e49..a80562e77ce 100644 --- a/app/controllers/projects/milestones_controller.rb +++ b/app/controllers/projects/milestones_controller.rb @@ -51,8 +51,7 @@ class Projects::MilestonesController < Projects::ApplicationController @milestone = Milestones::CreateService.new(project, current_user, milestone_params).execute if @milestone.save - redirect_to namespace_project_milestone_path(@project.namespace, - @project, @milestone) + redirect_to project_milestone_path(@project, @milestone) else render "new" end @@ -65,8 +64,7 @@ class Projects::MilestonesController < Projects::ApplicationController format.js format.html do if @milestone.valid? - redirect_to namespace_project_milestone_path(@project.namespace, - @project, @milestone) + redirect_to project_milestone_path(@project, @milestone) else render :edit end diff --git a/app/controllers/projects/network_controller.rb b/app/controllers/projects/network_controller.rb index 33a152ad34f..dfa5e4f7f46 100644 --- a/app/controllers/projects/network_controller.rb +++ b/app/controllers/projects/network_controller.rb @@ -8,8 +8,8 @@ class Projects::NetworkController < Projects::ApplicationController before_action :assign_commit def show - @url = namespace_project_network_path(@project.namespace, @project, @ref, @options.merge(format: :json)) - @commit_url = namespace_project_commit_path(@project.namespace, @project, 'ae45ca32').gsub("ae45ca32", "%s") + @url = project_network_path(@project, @ref, @options.merge(format: :json)) + @commit_url = project_commit_path(@project, 'ae45ca32').gsub("ae45ca32", "%s") respond_to do |format| format.html do diff --git a/app/controllers/projects/pages_controller.rb b/app/controllers/projects/pages_controller.rb index 28b383e69eb..d421b1a8eb5 100644 --- a/app/controllers/projects/pages_controller.rb +++ b/app/controllers/projects/pages_controller.rb @@ -15,7 +15,7 @@ class Projects::PagesController < Projects::ApplicationController respond_to do |format| format.html do - redirect_to namespace_project_pages_path(@project.namespace, @project), + redirect_to project_pages_path(@project), status: 302, notice: 'Pages were removed' end diff --git a/app/controllers/projects/pages_domains_controller.rb b/app/controllers/projects/pages_domains_controller.rb index dbd011f6c5d..15e77d854dc 100644 --- a/app/controllers/projects/pages_domains_controller.rb +++ b/app/controllers/projects/pages_domains_controller.rb @@ -16,7 +16,7 @@ class Projects::PagesDomainsController < Projects::ApplicationController @domain = @project.pages_domains.create(pages_domain_params) if @domain.valid? - redirect_to namespace_project_pages_path(@project.namespace, @project) + redirect_to project_pages_path(@project) else render 'new' end @@ -27,7 +27,7 @@ class Projects::PagesDomainsController < Projects::ApplicationController respond_to do |format| format.html do - redirect_to namespace_project_pages_path(@project.namespace, @project), + redirect_to project_pages_path(@project), status: 302, notice: 'Domain was removed' end diff --git a/app/controllers/projects/pipeline_schedules_controller.rb b/app/controllers/projects/pipeline_schedules_controller.rb index 60db179277b..0d967a7e691 100644 --- a/app/controllers/projects/pipeline_schedules_controller.rb +++ b/app/controllers/projects/pipeline_schedules_controller.rb @@ -34,7 +34,7 @@ class Projects::PipelineSchedulesController < Projects::ApplicationController def update if schedule.update(schedule_params) - redirect_to namespace_project_pipeline_schedules_path(@project.namespace.becomes(Namespace), @project) + redirect_to project_pipeline_schedules_path(@project) else render :edit end diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb index 303e91a8dc0..a3bfbf0694e 100644 --- a/app/controllers/projects/pipelines_controller.rb +++ b/app/controllers/projects/pipelines_controller.rb @@ -60,7 +60,7 @@ class Projects::PipelinesController < Projects::ApplicationController .execute(:web, ignore_skip_ci: true, save_on_errors: false) if @pipeline.persisted? - redirect_to namespace_project_pipeline_path(project.namespace, project, @pipeline) + redirect_to project_pipeline_path(project, @pipeline) else render 'new' end @@ -111,7 +111,7 @@ class Projects::PipelinesController < Projects::ApplicationController respond_to do |format| format.html do - redirect_back_or_default default: namespace_project_pipelines_path(project.namespace, project) + redirect_back_or_default default: project_pipelines_path(project) end format.json { head :no_content } @@ -123,7 +123,7 @@ class Projects::PipelinesController < Projects::ApplicationController respond_to do |format| format.html do - redirect_back_or_default default: namespace_project_pipelines_path(project.namespace, project) + redirect_back_or_default default: project_pipelines_path(project) end format.json { head :no_content } diff --git a/app/controllers/projects/pipelines_settings_controller.rb b/app/controllers/projects/pipelines_settings_controller.rb index 38a47651000..9d24ebe2138 100644 --- a/app/controllers/projects/pipelines_settings_controller.rb +++ b/app/controllers/projects/pipelines_settings_controller.rb @@ -2,13 +2,13 @@ class Projects::PipelinesSettingsController < Projects::ApplicationController before_action :authorize_admin_pipeline! def show - redirect_to namespace_project_settings_ci_cd_path(@project.namespace, @project, params: params) + redirect_to project_settings_ci_cd_path(@project, params: params) end def update if @project.update_attributes(update_params) flash[:notice] = "Pipelines settings for '#{@project.name}' were successfully updated." - redirect_to namespace_project_settings_ci_cd_path(@project.namespace, @project) + redirect_to project_settings_ci_cd_path(@project) else render 'show' end @@ -23,7 +23,7 @@ class Projects::PipelinesSettingsController < Projects::ApplicationController def update_params params.require(:project).permit( :runners_token, :builds_enabled, :build_allow_git_fetch, :build_timeout_in_minutes, :build_coverage_regex, - :public_builds, :auto_cancel_pending_pipelines + :public_builds, :auto_cancel_pending_pipelines, :ci_config_path ) end end diff --git a/app/controllers/projects/project_members_controller.rb b/app/controllers/projects/project_members_controller.rb index d2d26738582..57a6686f66c 100644 --- a/app/controllers/projects/project_members_controller.rb +++ b/app/controllers/projects/project_members_controller.rb @@ -7,7 +7,7 @@ class Projects::ProjectMembersController < Projects::ApplicationController def index sort = params[:sort].presence || sort_value_name - redirect_to namespace_project_settings_members_path(@project.namespace, @project, sort: sort) + redirect_to project_settings_members_path(@project, sort: sort) end def update @@ -19,7 +19,7 @@ class Projects::ProjectMembersController < Projects::ApplicationController end def resend_invite - redirect_path = namespace_project_settings_members_path(@project.namespace, @project) + redirect_path = project_settings_members_path(@project) @project_member = @project.project_members.find(params[:id]) @@ -42,7 +42,7 @@ class Projects::ProjectMembersController < Projects::ApplicationController return render_404 end - redirect_to(namespace_project_settings_members_path(project.namespace, project), + redirect_to(project_settings_members_path(project), notice: notice) end diff --git a/app/controllers/projects/refs_controller.rb b/app/controllers/projects/refs_controller.rb index 2a0b58fae7c..1eb78d8b522 100644 --- a/app/controllers/projects/refs_controller.rb +++ b/app/controllers/projects/refs_controller.rb @@ -13,21 +13,21 @@ class Projects::RefsController < Projects::ApplicationController new_path = case params[:destination] when "tree" - namespace_project_tree_path(@project.namespace, @project, @id) + project_tree_path(@project, @id) when "blob" - namespace_project_blob_path(@project.namespace, @project, @id) + project_blob_path(@project, @id) when "graph" - namespace_project_network_path(@project.namespace, @project, @id, @options) + project_network_path(@project, @id, @options) when "graphs" - namespace_project_graph_path(@project.namespace, @project, @id) + project_graph_path(@project, @id) when "find_file" - namespace_project_find_file_path(@project.namespace, @project, @id) + project_find_file_path(@project, @id) when "graphs_commits" - commits_namespace_project_graph_path(@project.namespace, @project, @id) + commits_project_graph_path(@project, @id) when "badges" - namespace_project_pipelines_settings_path(@project.namespace, @project, ref: @id) + project_pipelines_settings_path(@project, ref: @id) else - namespace_project_commits_path(@project.namespace, @project, @id) + project_commits_path(@project, @id) end redirect_to new_path @@ -62,7 +62,7 @@ class Projects::RefsController < Projects::ApplicationController offset = (@offset + @limit) if contents.size > offset - @more_log_url = logs_file_namespace_project_ref_path(@project.namespace, @project, @ref, @path || '', offset: offset) + @more_log_url = logs_file_project_ref_path(@project, @ref, @path || '', offset: offset) end respond_to do |format| diff --git a/app/controllers/projects/registry/repositories_controller.rb b/app/controllers/projects/registry/repositories_controller.rb index 98e78585be8..71e7dc70a4d 100644 --- a/app/controllers/projects/registry/repositories_controller.rb +++ b/app/controllers/projects/registry/repositories_controller.rb @@ -10,11 +10,11 @@ module Projects def destroy if image.destroy - redirect_to project_container_registry_path(@project), + redirect_to project_container_registry_index_path(@project), status: 302, notice: 'Image repository has been removed successfully!' else - redirect_to project_container_registry_path(@project), + redirect_to project_container_registry_index_path(@project), status: 302, alert: 'Failed to remove image repository!' end diff --git a/app/controllers/projects/registry/tags_controller.rb b/app/controllers/projects/registry/tags_controller.rb index 5050dba3aab..ae72bd03cfb 100644 --- a/app/controllers/projects/registry/tags_controller.rb +++ b/app/controllers/projects/registry/tags_controller.rb @@ -5,11 +5,11 @@ module Projects def destroy if tag.delete - redirect_to project_container_registry_path(@project), + redirect_to project_container_registry_index_path(@project), status: 302, notice: 'Registry tag has been removed successfully!' else - redirect_to project_container_registry_path(@project), + redirect_to project_container_registry_index_path(@project), status: 302, alert: 'Failed to remove registry tag!' end diff --git a/app/controllers/projects/releases_controller.rb b/app/controllers/projects/releases_controller.rb index 2c097cb4d8d..3e0a530fdb9 100644 --- a/app/controllers/projects/releases_controller.rb +++ b/app/controllers/projects/releases_controller.rb @@ -19,7 +19,7 @@ class Projects::ReleasesController < Projects::ApplicationController release.destroy end - redirect_to namespace_project_tag_path(@project.namespace, @project, @tag.name) + redirect_to project_tag_path(@project, @tag.name) end private diff --git a/app/controllers/projects/runners_controller.rb b/app/controllers/projects/runners_controller.rb index 160e632648a..9f9773575a5 100644 --- a/app/controllers/projects/runners_controller.rb +++ b/app/controllers/projects/runners_controller.rb @@ -5,7 +5,7 @@ class Projects::RunnersController < Projects::ApplicationController layout 'project_settings' def index - redirect_to namespace_project_settings_ci_cd_path(@project.namespace, @project) + redirect_to project_settings_ci_cd_path(@project) end def edit @@ -49,7 +49,7 @@ class Projects::RunnersController < Projects::ApplicationController def toggle_shared_runners project.toggle!(:shared_runners_enabled) - redirect_to namespace_project_settings_ci_cd_path(@project.namespace, @project) + redirect_to project_settings_ci_cd_path(@project) end protected diff --git a/app/controllers/projects/services_controller.rb b/app/controllers/projects/services_controller.rb index 704f8cc8a79..d54a1111f11 100644 --- a/app/controllers/projects/services_controller.rb +++ b/app/controllers/projects/services_controller.rb @@ -15,7 +15,7 @@ class Projects::ServicesController < Projects::ApplicationController def update if @service.save(context: :manual_change) - redirect_to(namespace_project_settings_integrations_path(@project.namespace, @project), notice: success_message) + redirect_to(project_settings_integrations_path(@project), notice: success_message) else render 'edit' end diff --git a/app/controllers/projects/snippets_controller.rb b/app/controllers/projects/snippets_controller.rb index 98dd307bd9d..d07143d294f 100644 --- a/app/controllers/projects/snippets_controller.rb +++ b/app/controllers/projects/snippets_controller.rb @@ -30,7 +30,7 @@ class Projects::SnippetsController < Projects::ApplicationController ).execute @snippets = @snippets.page(params[:page]) if @snippets.out_of_range? && @snippets.total_pages != 0 - redirect_to namespace_project_snippets_path(page: @snippets.total_pages) + redirect_to project_snippets_path(@project, page: @snippets.total_pages) end end @@ -79,7 +79,7 @@ class Projects::SnippetsController < Projects::ApplicationController @snippet.destroy - redirect_to namespace_project_snippets_path(@project.namespace, @project), status: 302 + redirect_to project_snippets_path(@project), status: 302 end protected @@ -90,6 +90,10 @@ class Projects::SnippetsController < Projects::ApplicationController alias_method :awardable, :snippet alias_method :spammable, :snippet + def spammable_path + project_snippet_path(@project, @snippet) + end + def authorize_read_project_snippet! return render_404 unless can?(current_user, :read_project_snippet, @snippet) end diff --git a/app/controllers/projects/tags_controller.rb b/app/controllers/projects/tags_controller.rb index ebc9f4edab4..b62d7d9b7c5 100644 --- a/app/controllers/projects/tags_controller.rb +++ b/app/controllers/projects/tags_controller.rb @@ -35,7 +35,7 @@ class Projects::TagsController < Projects::ApplicationController if result[:status] == :success @tag = result[:tag] - redirect_to namespace_project_tag_path(@project.namespace, @project, @tag.name) + redirect_to project_tag_path(@project, @tag.name) else @error = result[:message] @message = params[:message] @@ -50,7 +50,7 @@ class Projects::TagsController < Projects::ApplicationController respond_to do |format| if result[:status] == :success format.html do - redirect_to namespace_project_tags_path(@project.namespace, @project), status: 303 + redirect_to project_tags_path(@project), status: 303 end format.js @@ -58,7 +58,7 @@ class Projects::TagsController < Projects::ApplicationController @error = result[:message] format.html do - redirect_to namespace_project_tags_path(@project.namespace, @project), + redirect_to project_tags_path(@project), alert: @error, status: 303 end diff --git a/app/controllers/projects/tree_controller.rb b/app/controllers/projects/tree_controller.rb index 266a15c1cf9..30181ac3bdf 100644 --- a/app/controllers/projects/tree_controller.rb +++ b/app/controllers/projects/tree_controller.rb @@ -16,7 +16,7 @@ class Projects::TreeController < Projects::ApplicationController if tree.entries.empty? if @repository.blob_at(@commit.id, @path) return redirect_to( - namespace_project_blob_path(@project.namespace, @project, + project_blob_path(@project, File.join(@ref, @path)) ) elsif @path.present? @@ -37,8 +37,8 @@ class Projects::TreeController < Projects::ApplicationController return render_404 unless @commit_params.values.all? create_commit(Files::CreateDirService, success_notice: "The directory has been successfully created.", - success_path: namespace_project_tree_path(@project.namespace, @project, File.join(@branch_name, @dir_name)), - failure_path: namespace_project_tree_path(@project.namespace, @project, @ref)) + success_path: project_tree_path(@project, File.join(@branch_name, @dir_name)), + failure_path: project_tree_path(@project, @ref)) end private diff --git a/app/controllers/projects/triggers_controller.rb b/app/controllers/projects/triggers_controller.rb index e86adddd77f..a5b17fa65ea 100644 --- a/app/controllers/projects/triggers_controller.rb +++ b/app/controllers/projects/triggers_controller.rb @@ -7,7 +7,7 @@ class Projects::TriggersController < Projects::ApplicationController layout 'project_settings' def index - redirect_to namespace_project_settings_ci_cd_path(@project.namespace, @project) + redirect_to project_settings_ci_cd_path(@project) end def create @@ -19,7 +19,7 @@ class Projects::TriggersController < Projects::ApplicationController flash[:alert] = 'You could not create a new trigger.' end - redirect_to namespace_project_settings_ci_cd_path(@project.namespace, @project) + redirect_to project_settings_ci_cd_path(@project) end def take_ownership @@ -29,7 +29,7 @@ class Projects::TriggersController < Projects::ApplicationController flash[:alert] = 'You could not take ownership of trigger.' end - redirect_to namespace_project_settings_ci_cd_path(@project.namespace, @project) + redirect_to project_settings_ci_cd_path(@project) end def edit @@ -37,7 +37,7 @@ class Projects::TriggersController < Projects::ApplicationController def update if trigger.update(trigger_params) - redirect_to namespace_project_settings_ci_cd_path(@project.namespace, @project), notice: 'Trigger was successfully updated.' + redirect_to project_settings_ci_cd_path(@project), notice: 'Trigger was successfully updated.' else render action: "edit" end @@ -50,7 +50,7 @@ class Projects::TriggersController < Projects::ApplicationController flash[:alert] = "Could not remove the trigger." end - redirect_to namespace_project_settings_ci_cd_path(@project.namespace, @project), status: 302 + redirect_to project_settings_ci_cd_path(@project), status: 302 end private diff --git a/app/controllers/projects/variables_controller.rb b/app/controllers/projects/variables_controller.rb index 50e25a00f03..326d31ecec2 100644 --- a/app/controllers/projects/variables_controller.rb +++ b/app/controllers/projects/variables_controller.rb @@ -4,7 +4,7 @@ class Projects::VariablesController < Projects::ApplicationController layout 'project_settings' def index - redirect_to namespace_project_settings_ci_cd_path(@project.namespace, @project) + redirect_to project_settings_ci_cd_path(@project) end def show @@ -14,19 +14,19 @@ class Projects::VariablesController < Projects::ApplicationController def update @variable = @project.variables.find(params[:id]) - if @variable.update_attributes(project_params) - redirect_to namespace_project_variables_path(project.namespace, project), notice: 'Variable was successfully updated.' + if @variable.update_attributes(variable_params) + redirect_to project_variables_path(project), notice: 'Variable was successfully updated.' else render action: "show" end end def create - @variable = Ci::Variable.new(project_params) + @variable = @project.variables.new(variable_params) - if @variable.valid? && @project.variables << @variable + if @variable.save flash[:notice] = 'Variables were successfully updated.' - redirect_to namespace_project_settings_ci_cd_path(project.namespace, project) + redirect_to project_settings_ci_cd_path(project) else render "show" end @@ -36,15 +36,18 @@ class Projects::VariablesController < Projects::ApplicationController @key = @project.variables.find(params[:id]) @key.destroy - redirect_to namespace_project_settings_ci_cd_path(project.namespace, project), + redirect_to project_settings_ci_cd_path(project), status: 302, notice: 'Variable was successfully removed.' end private - def project_params - params.require(:variable) - .permit([:id, :key, :value, :protected, :_destroy]) + def variable_params + params.require(:variable).permit(*variable_params_attributes) + end + + def variable_params_attributes + %i[id key value protected _destroy] end end diff --git a/app/controllers/projects/wikis_controller.rb b/app/controllers/projects/wikis_controller.rb index e54b90b8d52..ac98470c2b1 100644 --- a/app/controllers/projects/wikis_controller.rb +++ b/app/controllers/projects/wikis_controller.rb @@ -49,7 +49,7 @@ class Projects::WikisController < Projects::ApplicationController if @page.valid? redirect_to( - namespace_project_wiki_path(@project.namespace, @project, @page), + project_wiki_path(@project, @page), notice: 'Wiki was successfully updated.' ) else @@ -62,7 +62,7 @@ class Projects::WikisController < Projects::ApplicationController if @page.persisted? redirect_to( - namespace_project_wiki_path(@project.namespace, @project, @page), + project_wiki_path(@project, @page), notice: 'Wiki was successfully updated.' ) else @@ -75,7 +75,7 @@ class Projects::WikisController < Projects::ApplicationController unless @page redirect_to( - namespace_project_wiki_path(@project.namespace, @project, :home), + project_wiki_path(@project, :home), notice: "Page not found" ) end @@ -85,7 +85,7 @@ class Projects::WikisController < Projects::ApplicationController @page = @project_wiki.find_page(params[:id]) WikiPages::DestroyService.new(@project, current_user).execute(@page) - redirect_to namespace_project_wiki_path(@project.namespace, @project, :home), + redirect_to project_wiki_path(@project, :home), status: 302, notice: "Page was successfully deleted" end diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 450895cdf3a..87a69e8e6f9 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -92,7 +92,7 @@ class ProjectsController < Projects::ApplicationController def show if @project.import_in_progress? - redirect_to namespace_project_import_path(@project.namespace, @project) + redirect_to project_import_path(@project) return end diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index 4a579601785..d58c8d14a75 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -44,7 +44,7 @@ class SearchController < ApplicationController query = params[:search].strip.downcase found_by_commit_sha = Commit.valid_hash?(query) && only_commit.sha.start_with?(query) - redirect_to namespace_project_commit_path(@project.namespace, @project, only_commit) if found_by_commit_sha + redirect_to project_commit_path(@project, only_commit) if found_by_commit_sha end end end diff --git a/app/controllers/snippets_controller.rb b/app/controllers/snippets_controller.rb index 3d86dd2ea2c..8c3abd0a085 100644 --- a/app/controllers/snippets_controller.rb +++ b/app/controllers/snippets_controller.rb @@ -107,6 +107,10 @@ class SnippetsController < ApplicationController alias_method :awardable, :snippet alias_method :spammable, :snippet + def spammable_path + snippet_path(@snippet) + end + def authorize_read_snippet! return if can?(current_user, :read_personal_snippet, @snippet) diff --git a/app/finders/labels_finder.rb b/app/finders/labels_finder.rb index 042d792dada..ce432ddbfe6 100644 --- a/app/finders/labels_finder.rb +++ b/app/finders/labels_finder.rb @@ -83,7 +83,12 @@ class LabelsFinder < UnionFinder def projects return @projects if defined?(@projects) - @projects = skip_authorization ? Project.all : ProjectsFinder.new(current_user: current_user).execute + @projects = if skip_authorization + Project.all + else + ProjectsFinder.new(params: { non_archived: true }, current_user: current_user).execute + end + @projects = @projects.in_namespace(params[:group_id]) if group? @projects = @projects.where(id: params[:project_ids]) if projects? @projects = @projects.reorder(nil) diff --git a/app/finders/projects_finder.rb b/app/finders/projects_finder.rb index 8bfbe37c543..aa80dfc3f37 100644 --- a/app/finders/projects_finder.rb +++ b/app/finders/projects_finder.rb @@ -28,7 +28,14 @@ class ProjectsFinder < UnionFinder end def execute - collection = init_collection + user = params.delete(:user) + collection = + if user + PersonalProjectsFinder.new(user).execute(current_user) + else + init_collection + end + collection = by_ids(collection) collection = by_personal(collection) collection = by_starred(collection) diff --git a/app/finders/users_finder.rb b/app/finders/users_finder.rb index dbd50d1db7c..07deceb827b 100644 --- a/app/finders/users_finder.rb +++ b/app/finders/users_finder.rb @@ -60,13 +60,13 @@ class UsersFinder end def by_external_identity(users) - return users unless current_user.admin? && params[:extern_uid] && params[:provider] + return users unless current_user&.admin? && params[:extern_uid] && params[:provider] users.joins(:identities).merge(Identity.with_extern_uid(params[:provider], params[:extern_uid])) end def by_external(users) - return users = users.where.not(external: true) unless current_user.admin? + return users = users.where.not(external: true) unless current_user&.admin? return users unless params[:external] users.external diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 7be8e3b96cf..1c165700b19 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -298,10 +298,6 @@ module ApplicationHelper end end - def can_toggle_new_nav? - Rails.env.development? - end - def show_new_nav? cookies["new_nav"] == "true" end diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb index ca326dd0627..f652f4901b7 100644 --- a/app/helpers/application_settings_helper.rb +++ b/app/helpers/application_settings_helper.rb @@ -34,17 +34,17 @@ module ApplicationSettingsHelper # Return a group of checkboxes that use Bootstrap's button plugin for a # toggle button effect. - def restricted_level_checkboxes(help_block_id) + def restricted_level_checkboxes(help_block_id, checkbox_name) Gitlab::VisibilityLevel.options.map do |name, level| checked = restricted_visibility_levels(true).include?(level) css_class = checked ? 'active' : '' - checkbox_name = "application_setting[restricted_visibility_levels][]" + tag_name = "application_setting_visibility_level_#{level}" - label_tag(name, class: css_class) do + label_tag(tag_name, class: css_class) do check_box_tag(checkbox_name, level, checked, autocomplete: 'off', 'aria-describedby' => help_block_id, - id: name) + visibility_level_icon(level) + name + id: tag_name) + visibility_level_icon(level) + name end end end diff --git a/app/helpers/award_emoji_helper.rb b/app/helpers/award_emoji_helper.rb index 024cf38469e..86b19368cfd 100644 --- a/app/helpers/award_emoji_helper.rb +++ b/app/helpers/award_emoji_helper.rb @@ -7,7 +7,7 @@ module AwardEmojiHelper if awardable.for_personal_snippet? toggle_award_emoji_snippet_note_path(awardable.noteable, awardable) else - toggle_award_emoji_namespace_project_note_path(@project.namespace, @project, awardable.id) + toggle_award_emoji_project_note_path(@project, awardable.id) end else url_for([:toggle_award_emoji, @project.namespace.becomes(Namespace), @project, awardable]) diff --git a/app/helpers/blob_helper.rb b/app/helpers/blob_helper.rb index ee36617ba9a..e964d7a5e16 100644 --- a/app/helpers/blob_helper.rb +++ b/app/helpers/blob_helper.rb @@ -9,7 +9,7 @@ module BlobHelper end def edit_path(project = @project, ref = @ref, path = @path, options = {}) - namespace_project_edit_blob_path(project.namespace, project, + project_edit_blob_path(project, tree_join(ref, path), options[:link_opts]) end @@ -33,7 +33,7 @@ module BlobHelper notice: edit_in_new_fork_notice, notice_now: edit_in_new_fork_notice_now } - fork_path = namespace_project_forks_path(project.namespace, project, namespace_key: current_user.namespace.id, continue: continue_params) + fork_path = project_forks_path(project, namespace_key: current_user.namespace.id, continue: continue_params) button_tag 'Edit', class: "#{common_classes} js-edit-blob-link-fork-toggler", @@ -62,7 +62,7 @@ module BlobHelper notice: edit_in_new_fork_notice + " Try to #{action} this file again.", notice_now: edit_in_new_fork_notice_now } - fork_path = namespace_project_forks_path(project.namespace, project, namespace_key: current_user.namespace.id, continue: continue_params) + fork_path = project_forks_path(project, namespace_key: current_user.namespace.id, continue: continue_params) button_tag label, class: "#{common_classes} js-edit-blob-link-fork-toggler", @@ -120,15 +120,15 @@ module BlobHelper def blob_raw_url if @build && @entry - raw_namespace_project_job_artifacts_path(@project.namespace, @project, @build, path: @entry.path) + raw_project_job_artifacts_path(@project, @build, path: @entry.path) elsif @snippet if @snippet.project_id - raw_namespace_project_snippet_path(@project.namespace, @project, @snippet) + raw_project_snippet_path(@project, @snippet) else raw_snippet_path(@snippet) end elsif @blob - namespace_project_raw_path(@project.namespace, @project, @id) + project_raw_path(@project, @id) end end @@ -279,12 +279,12 @@ module BlobHelper options = [] if can?(current_user, :create_issue, project) - options << link_to("submit an issue", new_namespace_project_issue_path(project.namespace, project)) + options << link_to("submit an issue", new_project_issue_path(project)) end merge_project = can?(current_user, :create_merge_request, project) ? project : (current_user && current_user.fork_of(project)) if merge_project - options << link_to("create a merge request", namespace_project_new_merge_request_path(project.namespace, project)) + options << link_to("create a merge request", project_new_merge_request_path(project)) end options diff --git a/app/helpers/boards_helper.rb b/app/helpers/boards_helper.rb index e2df52e3833..8b33c362a9c 100644 --- a/app/helpers/boards_helper.rb +++ b/app/helpers/boards_helper.rb @@ -3,12 +3,12 @@ module BoardsHelper board = @board || @boards.first { - endpoint: namespace_project_boards_path(@project.namespace, @project), + endpoint: project_boards_path(@project), board_id: board.id, disabled: "#{!can?(current_user, :admin_list, @project)}", - issue_link_base: namespace_project_issues_path(@project.namespace, @project), + issue_link_base: project_issues_path(@project), root_path: root_path, - bulk_update_path: bulk_update_namespace_project_issues_path(@project.namespace, @project), + bulk_update_path: bulk_update_project_issues_path(@project), default_avatar: image_path(default_avatar) } end diff --git a/app/helpers/branches_helper.rb b/app/helpers/branches_helper.rb index 59519c1335b..686437fc99a 100644 --- a/app/helpers/branches_helper.rb +++ b/app/helpers/branches_helper.rb @@ -7,7 +7,7 @@ module BranchesHelper options = exist_opts.merge(options) - namespace_project_branches_path(@project.namespace, @project, @id, options) + project_branches_path(@project, @id, options) end def can_push_branch?(project, branch_name) diff --git a/app/helpers/builds_helper.rb b/app/helpers/builds_helper.rb index f0a0d245dc0..85bc784d53c 100644 --- a/app/helpers/builds_helper.rb +++ b/app/helpers/builds_helper.rb @@ -20,8 +20,8 @@ module BuildsHelper def javascript_build_options { - page_url: namespace_project_job_url(@project.namespace, @project, @build), - build_url: namespace_project_job_url(@project.namespace, @project, @build, :json), + page_url: project_job_url(@project, @build), + build_url: project_job_url(@project, @build, :json), build_status: @build.status, build_stage: @build.stage, log_state: '' @@ -31,7 +31,7 @@ module BuildsHelper def build_failed_issue_options { title: "Build Failed ##{@build.id}", - description: namespace_project_job_url(@project.namespace, @project, @build) + description: project_job_url(@project, @build) } end end diff --git a/app/helpers/ci_status_helper.rb b/app/helpers/ci_status_helper.rb index 21c0eb8b54c..8022547a6ad 100644 --- a/app/helpers/ci_status_helper.rb +++ b/app/helpers/ci_status_helper.rb @@ -8,7 +8,7 @@ module CiStatusHelper def ci_status_path(pipeline) project = pipeline.project - namespace_project_pipeline_path(project.namespace, project, pipeline) + project_pipeline_path(project, pipeline) end def ci_label_for_status(status) @@ -99,10 +99,7 @@ module CiStatusHelper def render_project_pipeline_status(pipeline_status, tooltip_placement: 'auto left') project = pipeline_status.project - path = pipelines_namespace_project_commit_path( - project.namespace, - project, - pipeline_status.sha) + path = pipelines_project_commit_path(project, pipeline_status.sha) render_status_with_link( 'commit', @@ -113,10 +110,7 @@ module CiStatusHelper def render_commit_status(commit, ref: nil, tooltip_placement: 'auto left') project = commit.project - path = pipelines_namespace_project_commit_path( - project.namespace, - project, - commit) + path = pipelines_project_commit_path(project, commit) render_status_with_link( 'commit', @@ -127,7 +121,7 @@ module CiStatusHelper def render_pipeline_status(pipeline, tooltip_placement: 'auto left') project = pipeline.project - path = namespace_project_pipeline_path(project.namespace, project, pipeline) + path = project_pipeline_path(project, pipeline) render_status_with_link('pipeline', pipeline.status, path, tooltip_placement: tooltip_placement) end diff --git a/app/helpers/commits_helper.rb b/app/helpers/commits_helper.rb index 0accd1f8d77..d08e346d605 100644 --- a/app/helpers/commits_helper.rb +++ b/app/helpers/commits_helper.rb @@ -30,7 +30,7 @@ module CommitsHelper crumbs = content_tag(:li) do link_to( @project.path, - namespace_project_commits_path(@project.namespace, @project, @ref) + project_commits_path(@project, @ref) ) end @@ -42,8 +42,7 @@ module CommitsHelper # The text is just the individual part, but the link needs all the parts before it link_to( part, - namespace_project_commits_path( - @project.namespace, + project_commits_path( @project, tree_join(@ref, parts[0..i].join('/')) ) @@ -86,20 +85,20 @@ module CommitsHelper if @path.blank? return link_to( _("Browse Files"), - namespace_project_tree_path(project.namespace, project, commit), + project_tree_path(project, commit), class: "btn btn-default" ) elsif @repo.blob_at(commit.id, @path) return link_to( _("Browse File"), - namespace_project_blob_path(project.namespace, project, + project_blob_path(project, tree_join(commit.id, @path)), class: "btn btn-default" ) elsif @path.present? return link_to( _("Browse Directory"), - namespace_project_tree_path(project.namespace, project, + project_tree_path(project, tree_join(commit.id, @path)), class: "btn btn-default" ) @@ -165,7 +164,7 @@ module CommitsHelper notice: "#{edit_in_new_fork_notice} Try to #{action} this commit again.", notice_now: edit_in_new_fork_notice_now } - fork_path = namespace_project_forks_path(@project.namespace, @project, + fork_path = project_forks_path(@project, namespace_key: current_user.namespace.id, continue: continue_params) @@ -175,7 +174,7 @@ module CommitsHelper def view_file_button(commit_sha, diff_new_path, project) link_to( - namespace_project_blob_path(project.namespace, project, + project_blob_path(project, tree_join(commit_sha, diff_new_path)), class: 'btn view-file js-view-file' ) do diff --git a/app/helpers/compare_helper.rb b/app/helpers/compare_helper.rb index 424ded2b69d..2c28dd81c87 100644 --- a/app/helpers/compare_helper.rb +++ b/app/helpers/compare_helper.rb @@ -9,8 +9,7 @@ module CompareHelper end def create_mr_path(from = params[:from], to = params[:to], project = @project) - namespace_project_new_merge_request_path( - project.namespace, + project_new_merge_request_path( project, merge_request: { source_branch: to, diff --git a/app/helpers/diff_helper.rb b/app/helpers/diff_helper.rb index 16a99addd0b..926502bf239 100644 --- a/app/helpers/diff_helper.rb +++ b/app/helpers/diff_helper.rb @@ -103,18 +103,18 @@ module DiffHelper end def diff_file_blob_raw_path(diff_file) - namespace_project_raw_path(@project.namespace, @project, tree_join(diff_file.content_sha, diff_file.file_path)) + project_raw_path(@project, tree_join(diff_file.content_sha, diff_file.file_path)) end def diff_file_old_blob_raw_path(diff_file) sha = diff_file.old_content_sha return unless sha - namespace_project_raw_path(@project.namespace, @project, tree_join(diff_file.old_content_sha, diff_file.old_path)) + project_raw_path(@project, tree_join(diff_file.old_content_sha, diff_file.old_path)) end def diff_file_html_data(project, diff_file_path, diff_commit_id) { - blob_diff_path: namespace_project_blob_diff_path(project.namespace, project, + blob_diff_path: project_blob_diff_path(project, tree_join(diff_commit_id, diff_file_path)), view: diff_view } @@ -142,7 +142,7 @@ module DiffHelper diff_file = viewer.diff_file options = [] - blob_url = namespace_project_blob_path(@project.namespace, @project, tree_join(diff_file.content_sha, diff_file.file_path)) + blob_url = project_blob_path(@project, tree_join(diff_file.content_sha, diff_file.file_path)) options << link_to('view the blob', blob_url) options @@ -163,17 +163,17 @@ module DiffHelper end def commit_diff_whitespace_link(project, commit, options) - url = namespace_project_commit_path(project.namespace, project, commit.id, params_with_whitespace) + url = project_commit_path(project, commit.id, params_with_whitespace) toggle_whitespace_link(url, options) end def diff_merge_request_whitespace_link(project, merge_request, options) - url = diffs_namespace_project_merge_request_path(project.namespace, project, merge_request, params_with_whitespace) + url = diffs_project_merge_request_path(project, merge_request, params_with_whitespace) toggle_whitespace_link(url, options) end def diff_compare_whitespace_link(project, from, to, options) - url = namespace_project_compare_path(project.namespace, project, from, to, params_with_whitespace) + url = project_compare_path(project, from, to, params_with_whitespace) toggle_whitespace_link(url, options) end diff --git a/app/helpers/environment_helper.rb b/app/helpers/environment_helper.rb index ff8550439d0..1e78a189c08 100644 --- a/app/helpers/environment_helper.rb +++ b/app/helpers/environment_helper.rb @@ -8,7 +8,7 @@ module EnvironmentHelper def environment_link_for_build(project, build) environment = environment_for_build(project, build) if environment - link_to environment.name, namespace_project_environment_path(project.namespace, project, environment) + link_to environment.name, project_environment_path(project, environment) else content_tag :span, build.expanded_environment_name end diff --git a/app/helpers/environments_helper.rb b/app/helpers/environments_helper.rb index 515e802e01e..4ce89f89fa9 100644 --- a/app/helpers/environments_helper.rb +++ b/app/helpers/environments_helper.rb @@ -1,7 +1,7 @@ module EnvironmentsHelper def environments_list_data { - endpoint: namespace_project_environments_path(@project.namespace, @project, format: :json) + endpoint: project_environments_path(@project, format: :json) } end end diff --git a/app/helpers/events_helper.rb b/app/helpers/events_helper.rb index 751d61955b7..48c87dca217 100644 --- a/app/helpers/events_helper.rb +++ b/app/helpers/events_helper.rb @@ -99,13 +99,12 @@ module EventsHelper def event_feed_url(event) if event.issue? - namespace_project_issue_url(event.project.namespace, event.project, + project_issue_url(event.project, event.issue) elsif event.merge_request? - namespace_project_merge_request_url(event.project.namespace, - event.project, event.merge_request) + project_merge_request_url(event.project, event.merge_request) elsif event.commit_note? - namespace_project_commit_url(event.project.namespace, event.project, + project_commit_url(event.project, event.note_target) elsif event.note? if event.note_target @@ -119,15 +118,15 @@ module EventsHelper def push_event_feed_url(event) if event.push_with_commits? && event.md_ref? if event.commits_count > 1 - namespace_project_compare_url(event.project.namespace, event.project, + project_compare_url(event.project, from: event.commit_from, to: event.commit_to) else - namespace_project_commit_url(event.project.namespace, event.project, + project_commit_url(event.project, id: event.commit_to) end else - namespace_project_commits_url(event.project.namespace, event.project, + project_commits_url(event.project, event.ref_name) end end @@ -146,15 +145,9 @@ module EventsHelper def event_note_target_path(event) if event.commit_note? - namespace_project_commit_path(event.project.namespace, - event.project, - event.note_target, - anchor: dom_id(event.target)) + project_commit_path(event.project, event.note_target, anchor: dom_id(event.target)) elsif event.project_snippet_note? - namespace_project_snippet_path(event.project.namespace, - event.project, - event.note_target, - anchor: dom_id(event.target)) + project_snippet_path(event.project, event.note_target, anchor: dom_id(event.target)) else polymorphic_path([event.project.namespace.becomes(Namespace), event.project, event.note_target], diff --git a/app/helpers/external_wiki_helper.rb b/app/helpers/external_wiki_helper.rb index defd87d6bbe..8cf890b74a8 100644 --- a/app/helpers/external_wiki_helper.rb +++ b/app/helpers/external_wiki_helper.rb @@ -4,7 +4,7 @@ module ExternalWikiHelper if external_wiki_service external_wiki_service.properties['external_wiki_url'] else - namespace_project_wiki_path(project.namespace, project, :home) + project_wiki_path(project, :home) end end end diff --git a/app/helpers/form_helper.rb b/app/helpers/form_helper.rb index 8ceb5c36bda..9247b1f72de 100644 --- a/app/helpers/form_helper.rb +++ b/app/helpers/form_helper.rb @@ -16,8 +16,8 @@ module FormHelper end end - def issue_dropdown_options(issuable, has_multiple_assignees = true) - options = { + def issue_assignees_dropdown_options + { toggle_class: 'js-user-search js-assignee-search js-multiselect js-save-user-data', title: 'Select assignee', filter: true, @@ -27,8 +27,8 @@ module FormHelper first_user: current_user&.username, null_user: true, current_user: true, - project_id: issuable.project.try(:id), - field_name: "#{issuable.class.model_name.param_key}[assignee_ids][]", + project_id: @project.id, + field_name: 'issue[assignee_ids][]', default_label: 'Unassigned', 'max-select': 1, 'dropdown-header': 'Assignee', @@ -38,13 +38,5 @@ module FormHelper current_user_info: current_user.to_json(only: [:id, :name]) } } - - if has_multiple_assignees - options[:title] = 'Select assignee(s)' - options[:data][:'dropdown-header'] = 'Assignee(s)' - options[:data].delete(:'max-select') - end - - options end end diff --git a/app/helpers/gitlab_routing_helper.rb b/app/helpers/gitlab_routing_helper.rb index 8c7af62e199..b5f4bbe97dc 100644 --- a/app/helpers/gitlab_routing_helper.rb +++ b/app/helpers/gitlab_routing_helper.rb @@ -1,144 +1,89 @@ -# Shorter routing method for project and project items -# Since update to rails 4.1.9 we are now allowed to use `/` in project routing -# so we use nested routing for project resources which include project and -# project namespace. To avoid writing long methods every time we define shortcuts for -# some of routing. -# -# For example instead of this: -# -# namespace_project_merge_request_path(merge_request.project.namespace, merge_request.project, merge_request) -# -# We can simply use shortcut: -# -# merge_request_path(merge_request) -# +# Shorter routing method for some project items module GitlabRoutingHelper - # Project - def project_path(project, *args) - namespace_project_path(project.namespace, project, *args) - end - - def project_url(project, *args) - namespace_project_url(project.namespace, project, *args) - end - - def edit_project_path(project, *args) - edit_namespace_project_path(project.namespace, project, *args) - end - - def edit_project_url(project, *args) - edit_namespace_project_url(project.namespace, project, *args) - end - - def project_files_path(project, *args) - namespace_project_tree_path(project.namespace, project, @ref || project.repository.root_ref) - end - - def project_commits_path(project, *args) - namespace_project_commits_path(project.namespace, project, @ref || project.repository.root_ref) - end - - def project_pipelines_path(project, *args) - namespace_project_pipelines_path(project.namespace, project, *args) - end - - def project_environments_path(project, *args) - namespace_project_environments_path(project.namespace, project, *args) - end + extend ActiveSupport::Concern - def project_cycle_analytics_path(project, *args) - namespace_project_cycle_analytics_path(project.namespace, project, *args) + # Project + def project_tree_path(project, ref = nil, *args) + namespace_project_tree_path(project.namespace, project, ref || @ref || project.repository.root_ref, *args) # rubocop:disable Cop/ProjectPathHelper end - def project_jobs_path(project, *args) - namespace_project_jobs_path(project.namespace, project, *args) + def project_commits_path(project, ref = nil, *args) + namespace_project_commits_path(project.namespace, project, ref || @ref || project.repository.root_ref, *args) # rubocop:disable Cop/ProjectPathHelper end def project_ref_path(project, ref_name, *args) - namespace_project_commits_path(project.namespace, project, ref_name, *args) - end - - def project_container_registry_path(project, *args) - namespace_project_container_registry_index_path(project.namespace, project, *args) - end - - def activity_project_path(project, *args) - activity_namespace_project_path(project.namespace, project, *args) + project_commits_path(project, ref_name, *args) end def runners_path(project, *args) - namespace_project_runners_path(project.namespace, project, *args) + project_runners_path(project, *args) end def runner_path(runner, *args) - namespace_project_runner_path(@project.namespace, @project, runner, *args) + project_runner_path(@project, runner, *args) end def environment_path(environment, *args) - namespace_project_environment_path(environment.project.namespace, environment.project, environment, *args) + project_environment_path(environment.project, environment, *args) end def environment_metrics_path(environment, *args) - metrics_namespace_project_environment_path(environment.project.namespace, environment.project, environment, *args) + metrics_project_environment_path(environment.project, environment, *args) end def issue_path(entity, *args) - namespace_project_issue_path(entity.project.namespace, entity.project, entity, *args) + project_issue_path(entity.project, entity, *args) end def merge_request_path(entity, *args) - namespace_project_merge_request_path(entity.project.namespace, entity.project, entity, *args) + project_merge_request_path(entity.project, entity, *args) end def pipeline_path(pipeline, *args) - namespace_project_pipeline_path(pipeline.project.namespace, pipeline.project, pipeline.id, *args) + project_pipeline_path(pipeline.project, pipeline.id, *args) end def milestone_path(entity, *args) - namespace_project_milestone_path(entity.project.namespace, entity.project, entity, *args) + project_milestone_path(entity.project, entity, *args) end def issue_url(entity, *args) - namespace_project_issue_url(entity.project.namespace, entity.project, entity, *args) + project_issue_url(entity.project, entity, *args) end def merge_request_url(entity, *args) - namespace_project_merge_request_url(entity.project.namespace, entity.project, entity, *args) + project_merge_request_url(entity.project, entity, *args) end def pipeline_url(pipeline, *args) - namespace_project_pipeline_url(pipeline.project.namespace, pipeline.project, pipeline.id, *args) + project_pipeline_url(pipeline.project, pipeline.id, *args) end def pipeline_job_url(pipeline, build, *args) - namespace_project_job_url(pipeline.project.namespace, pipeline.project, build.id, *args) + project_job_url(pipeline.project, build.id, *args) end def commits_url(entity, *args) - namespace_project_commits_url(entity.project.namespace, entity.project, entity.ref, *args) + project_commits_url(entity.project, entity.ref, *args) end def commit_url(entity, *args) - namespace_project_commit_url(entity.project.namespace, entity.project, entity.sha, *args) - end - - def project_snippet_url(entity, *args) - namespace_project_snippet_url(entity.project.namespace, entity.project, entity, *args) + project_commit_url(entity.project, entity.sha, *args) end def preview_markdown_path(project, *args) if @snippet.is_a?(PersonalSnippet) preview_markdown_snippets_path else - preview_markdown_namespace_project_path(project.namespace, project, *args) + preview_markdown_project_path(project, *args) end end def toggle_subscription_path(entity, *args) if entity.is_a?(Issue) - toggle_subscription_namespace_project_issue_path(entity.project.namespace, entity.project, entity) + toggle_subscription_project_issue_path(entity.project, entity) else - toggle_subscription_namespace_project_merge_request_path(entity.project.namespace, entity.project, entity) + toggle_subscription_project_merge_request_path(entity.project, entity) end end @@ -152,32 +97,27 @@ module GitlabRoutingHelper ## Members def project_members_url(project, *args) - namespace_project_project_members_url(project.namespace, project) + project_project_members_url(project) end def project_member_path(project_member, *args) - namespace_project_project_member_path(project_member.source.namespace, project_member.source, project_member) + project_project_member_path(project_member.source, project_member) end def request_access_project_members_path(project, *args) - request_access_namespace_project_project_members_path(project.namespace, project) + request_access_project_project_members_path(project) end def leave_project_members_path(project, *args) - leave_namespace_project_project_members_path(project.namespace, project) + leave_project_project_members_path(project) end def approve_access_request_project_member_path(project_member, *args) - approve_access_request_namespace_project_project_member_path(project_member.source.namespace, project_member.source, project_member) + approve_access_request_project_project_member_path(project_member.source, project_member) end def resend_invite_project_member_path(project_member, *args) - resend_invite_namespace_project_project_member_path(project_member.source.namespace, project_member.source, project_member) - end - - # Snippets - def personal_snippet_url(snippet, *args) - snippet_url(snippet) + resend_invite_project_project_member_path(project_member.source, project_member) end # Groups @@ -211,50 +151,37 @@ module GitlabRoutingHelper def artifacts_action_path(path, project, build) action, path_params = path.split('/', 2) - args = [project.namespace, project, build, path_params] + args = [project, build, path_params] case action when 'download' - download_namespace_project_job_artifacts_path(*args) + download_project_job_artifacts_path(*args) when 'browse' - browse_namespace_project_job_artifacts_path(*args) + browse_project_job_artifacts_path(*args) when 'file' - file_namespace_project_job_artifacts_path(*args) + file_project_job_artifacts_path(*args) when 'raw' - raw_namespace_project_job_artifacts_path(*args) + raw_project_job_artifacts_path(*args) end end # Pipeline Schedules def pipeline_schedules_path(project, *args) - namespace_project_pipeline_schedules_path(project.namespace, project, *args) + project_pipeline_schedules_path(project, *args) end def pipeline_schedule_path(schedule, *args) project = schedule.project - namespace_project_pipeline_schedule_path(project.namespace, project, schedule, *args) + project_pipeline_schedule_path(project, schedule, *args) end def edit_pipeline_schedule_path(schedule) project = schedule.project - edit_namespace_project_pipeline_schedule_path(project.namespace, project, schedule) + edit_project_pipeline_schedule_path(project, schedule) end def take_ownership_pipeline_schedule_path(schedule, *args) project = schedule.project - take_ownership_namespace_project_pipeline_schedule_path(project.namespace, project, schedule, *args) - end - - # Settings - def project_settings_integrations_path(project, *args) - namespace_project_settings_integrations_path(project.namespace, project, *args) - end - - def project_settings_members_path(project, *args) - namespace_project_settings_members_path(project.namespace, project, *args) - end - - def project_settings_ci_cd_path(project, *args) - namespace_project_settings_ci_cd_path(project.namespace, project, *args) + take_ownership_project_pipeline_schedule_path(project, schedule, *args) end end diff --git a/app/helpers/groups_helper.rb b/app/helpers/groups_helper.rb index af0b3e9c5bc..8cd61f738e1 100644 --- a/app/helpers/groups_helper.rb +++ b/app/helpers/groups_helper.rb @@ -58,6 +58,11 @@ module GroupsHelper IssuesFinder.new(current_user, group_id: group.id).execute end + def remove_group_message(group) + _("You are going to remove %{group_name}.\nRemoved groups CANNOT be restored!\nAre you ABSOLUTELY sure?") % + { group_name: group.name } + end + private def group_title_link(group, hidable: false) diff --git a/app/helpers/issuables_helper.rb b/app/helpers/issuables_helper.rb index 05177e58c5a..b5366519ed9 100644 --- a/app/helpers/issuables_helper.rb +++ b/app/helpers/issuables_helper.rb @@ -26,9 +26,9 @@ module IssuablesHelper project = issuable.project if issuable.is_a?(MergeRequest) - namespace_project_merge_request_path(project.namespace, project, issuable.iid, :json) + project_merge_request_path(project, issuable.iid, :json) else - namespace_project_issue_path(project.namespace, project, issuable.iid, :json) + project_issue_path(project, issuable.iid, :json) end end @@ -197,7 +197,7 @@ module IssuablesHelper def issuable_initial_data(issuable) data = { - endpoint: namespace_project_issue_path(@project.namespace, @project, issuable), + endpoint: project_issue_path(@project, issuable), canUpdate: can?(current_user, :update_issue, issuable), canDestroy: can?(current_user, :destroy_issue, issuable), canMove: current_user ? issuable.can_move?(current_user) : false, @@ -295,7 +295,7 @@ module IssuablesHelper mark_icon: (is_collapsed ? icon('check-square', class: 'todo-undone') : nil), issuable_id: issuable.id, issuable_type: issuable.class.name.underscore, - url: namespace_project_todos_path(@project.namespace, @project), + url: project_todos_path(@project), delete_path: (dashboard_todo_path(todo) if todo), placement: (is_collapsed ? 'left' : nil), container: (is_collapsed ? 'body' : nil) diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb index 82288f1da35..42b6cfdf02f 100644 --- a/app/helpers/issues_helper.rb +++ b/app/helpers/issues_helper.rb @@ -150,7 +150,7 @@ module IssuesHelper Gitlab::UrlBuilder.build(single_discussion.first_note) else project = merge_request.project - namespace_project_merge_request_path(project.namespace, project, merge_request) + project_merge_request_path(project, merge_request) end link_to link_text, path diff --git a/app/helpers/labels_helper.rb b/app/helpers/labels_helper.rb index 6baf6f31d8f..4b99de1b6a5 100644 --- a/app/helpers/labels_helper.rb +++ b/app/helpers/labels_helper.rb @@ -57,14 +57,14 @@ module LabelsHelper def edit_label_path(label) case label when GroupLabel then edit_group_label_path(label.group, label) - when ProjectLabel then edit_namespace_project_label_path(label.project.namespace, label.project, label) + when ProjectLabel then edit_project_label_path(label.project, label) end end def destroy_label_path(label) case label when GroupLabel then group_label_path(label.group, label) - when ProjectLabel then namespace_project_label_path(label.project.namespace, label.project, label) + when ProjectLabel then project_label_path(label.project, label) end end @@ -127,7 +127,7 @@ module LabelsHelper project = @target_project || @project if project - namespace_project_labels_path(project.namespace, project, :json) + project_labels_path(project, :json) else dashboard_labels_path(:json) end @@ -149,8 +149,8 @@ module LabelsHelper case label_subscription_status(label, project) when 'group-level' then toggle_subscription_group_label_path(label.group, label) - when 'project-level' then toggle_subscription_namespace_project_label_path(project.namespace, project, label) - when 'unsubscribed' then toggle_subscription_namespace_project_label_path(project.namespace, project, label) + when 'project-level' then toggle_subscription_project_label_path(project, label) + when 'unsubscribed' then toggle_subscription_project_label_path(project, label) end end diff --git a/app/helpers/merge_requests_helper.rb b/app/helpers/merge_requests_helper.rb index 54d6f86fa11..78cf7b26a31 100644 --- a/app/helpers/merge_requests_helper.rb +++ b/app/helpers/merge_requests_helper.rb @@ -1,8 +1,7 @@ module MergeRequestsHelper def new_mr_path_from_push_event(event) target_project = event.project.default_merge_request_target - namespace_project_new_merge_request_path( - event.project.namespace, + project_new_merge_request_path( event.project, new_mr_from_push_event(event, target_project) ) @@ -48,8 +47,8 @@ module MergeRequestsHelper end def mr_change_branches_path(merge_request) - namespace_project_new_merge_request_path( - @project.namespace, @project, + project_new_merge_request_path( + @project, merge_request: { source_project_id: merge_request.source_project_id, target_project_id: merge_request.target_project_id, @@ -82,9 +81,7 @@ module MergeRequestsHelper end def merge_request_version_path(project, merge_request, merge_request_diff, start_sha = nil) - diffs_namespace_project_merge_request_path( - project.namespace, project, merge_request, - diff_id: merge_request_diff.id, start_sha: start_sha) + diffs_project_merge_request_path(project, merge_request, diff_id: merge_request_diff.id, start_sha: start_sha) end def version_index(merge_request_diff) diff --git a/app/helpers/milestones_helper.rb b/app/helpers/milestones_helper.rb index a230db22fa2..8c7851dcfc2 100644 --- a/app/helpers/milestones_helper.rb +++ b/app/helpers/milestones_helper.rb @@ -1,7 +1,7 @@ module MilestonesHelper def milestones_filter_path(opts = {}) if @project - namespace_project_milestones_path(@project.namespace, @project, opts) + project_milestones_path(@project, opts) elsif @group group_milestones_path(@group, opts) else @@ -11,7 +11,7 @@ module MilestonesHelper def milestones_label_path(opts = {}) if @project - namespace_project_issues_path(@project.namespace, @project, opts) + project_issues_path(@project, opts) elsif @group issues_group_path(@group, opts) else @@ -73,7 +73,9 @@ module MilestonesHelper def milestones_filter_dropdown_path project = @target_project || @project if project - namespace_project_milestones_path(project.namespace, project, :json) + project_milestones_path(project, :json) + elsif @group + group_milestones_path(@group, :json) else dashboard_milestones_path(:json) end @@ -118,7 +120,7 @@ module MilestonesHelper def milestone_merge_request_tab_path(milestone) if @project - merge_requests_namespace_project_milestone_path(@project.namespace, @project, milestone, format: :json) + merge_requests_project_milestone_path(@project, milestone, format: :json) elsif @group merge_requests_group_milestone_path(@group, milestone.safe_title, title: milestone.title, format: :json) else @@ -128,7 +130,7 @@ module MilestonesHelper def milestone_participants_tab_path(milestone) if @project - participants_namespace_project_milestone_path(@project.namespace, @project, milestone, format: :json) + participants_project_milestone_path(@project, milestone, format: :json) elsif @group participants_group_milestone_path(@group, milestone.safe_title, title: milestone.title, format: :json) else @@ -138,7 +140,7 @@ module MilestonesHelper def milestone_labels_tab_path(milestone) if @project - labels_namespace_project_milestone_path(@project.namespace, @project, milestone, format: :json) + labels_project_milestone_path(@project, milestone, format: :json) elsif @group labels_group_milestone_path(@group, milestone.safe_title, title: milestone.title, format: :json) else diff --git a/app/helpers/notes_helper.rb b/app/helpers/notes_helper.rb index ecc6cd6c6c5..0a0881d95cf 100644 --- a/app/helpers/notes_helper.rb +++ b/app/helpers/notes_helper.rb @@ -81,11 +81,11 @@ module NotesHelper path_params = version_params.merge(anchor: discussion.line_code) - diffs_namespace_project_merge_request_path(discussion.project.namespace, discussion.project, discussion.noteable, path_params) + diffs_project_merge_request_path(discussion.project, discussion.noteable, path_params) elsif discussion.for_commit? anchor = discussion.line_code if discussion.diff_discussion? - namespace_project_commit_path(discussion.project.namespace, discussion.project, discussion.noteable, anchor: anchor) + project_commit_path(discussion.project, discussion.noteable, anchor: anchor) end end @@ -93,12 +93,7 @@ module NotesHelper if @snippet.is_a?(PersonalSnippet) snippet_notes_path(@snippet) else - namespace_project_noteable_notes_path( - namespace_id: @project.namespace, - project_id: @project, - target_id: @noteable.id, - target_type: @noteable.class.name.underscore - ) + project_noteable_notes_path(@project, target_id: @noteable.id, target_type: @noteable.class.name.underscore) end end @@ -106,7 +101,7 @@ module NotesHelper if note.noteable.is_a?(PersonalSnippet) snippet_note_path(note.noteable, note) else - namespace_project_note_path(project.namespace, project, note) + project_note_path(project, note) end end diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index 53d95c2de94..5022b291f7f 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -347,8 +347,7 @@ module ProjectsHelper def add_special_file_path(project, file_name:, commit_message: nil, branch_name: nil, context: nil) commit_message ||= s_("CommitMessage|Add %{file_name}") % { file_name: file_name.downcase } - namespace_project_new_blob_path( - project.namespace, + project_new_blob_path( project, project.default_branch || 'master', file_name: file_name, @@ -359,8 +358,7 @@ module ProjectsHelper end def add_koding_stack_path(project) - namespace_project_new_blob_path( - project.namespace, + project_new_blob_path( project, project.default_branch || 'master', file_name: '.koding.yml', @@ -414,8 +412,7 @@ module ProjectsHelper def contribution_guide_path(project) if project && contribution_guide = project.repository.contribution_guide - namespace_project_blob_path( - project.namespace, + project_blob_path( project, tree_join(project.default_branch, contribution_guide.name) @@ -445,7 +442,7 @@ module ProjectsHelper def project_wiki_path_with_version(proj, page, version, is_newest) url_params = is_newest ? {} : { version_id: version } - namespace_project_wiki_path(proj.namespace, proj, page, url_params) + project_wiki_path(proj, page, url_params) end def project_status_css_class(status) @@ -470,8 +467,7 @@ module ProjectsHelper def filename_path(project, filename) if project && blob = project.repository.send(filename) - namespace_project_blob_path( - project.namespace, + project_blob_path( project, tree_join(project.default_branch, blob.name) ) diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb index 8f15904f068..8c44f4b0934 100644 --- a/app/helpers/search_helper.rb +++ b/app/helpers/search_helper.rb @@ -67,16 +67,16 @@ module SearchHelper ref = @ref || @project.repository.root_ref [ - { category: "Current Project", label: "Files", url: namespace_project_tree_path(@project.namespace, @project, ref) }, - { category: "Current Project", label: "Commits", url: namespace_project_commits_path(@project.namespace, @project, ref) }, - { category: "Current Project", label: "Network", url: namespace_project_network_path(@project.namespace, @project, ref) }, - { category: "Current Project", label: "Graph", url: namespace_project_graph_path(@project.namespace, @project, ref) }, - { category: "Current Project", label: "Issues", url: namespace_project_issues_path(@project.namespace, @project) }, - { category: "Current Project", label: "Merge Requests", url: namespace_project_merge_requests_path(@project.namespace, @project) }, - { category: "Current Project", label: "Milestones", url: namespace_project_milestones_path(@project.namespace, @project) }, - { category: "Current Project", label: "Snippets", url: namespace_project_snippets_path(@project.namespace, @project) }, - { category: "Current Project", label: "Members", url: namespace_project_settings_members_path(@project.namespace, @project) }, - { category: "Current Project", label: "Wiki", url: namespace_project_wikis_path(@project.namespace, @project) } + { category: "Current Project", label: "Files", url: project_tree_path(@project, ref) }, + { category: "Current Project", label: "Commits", url: project_commits_path(@project, ref) }, + { category: "Current Project", label: "Network", url: project_network_path(@project, ref) }, + { category: "Current Project", label: "Graph", url: project_graph_path(@project, ref) }, + { category: "Current Project", label: "Issues", url: project_issues_path(@project) }, + { category: "Current Project", label: "Merge Requests", url: project_merge_requests_path(@project) }, + { category: "Current Project", label: "Milestones", url: project_milestones_path(@project) }, + { category: "Current Project", label: "Snippets", url: project_snippets_path(@project) }, + { category: "Current Project", label: "Members", url: project_settings_members_path(@project) }, + { category: "Current Project", label: "Wiki", url: project_wikis_path(@project) } ] else [] @@ -104,7 +104,7 @@ module SearchHelper id: p.id, value: "#{search_result_sanitize(p.name)}", label: "#{search_result_sanitize(p.name_with_namespace)}", - url: namespace_project_path(p.namespace, p) + url: project_path(p) } end end @@ -126,6 +126,18 @@ module SearchHelper search_path(options) end + def search_filter_input_options(type) + { + id: "filtered-search-#{type}", + placeholder: 'Search or filter results...', + data: { + 'project-id' => @project.id, + 'username-params' => @users.to_json(only: [:id, :username]), + 'base-endpoint' => project_path(@project) + } + } + end + # Sanitize a HTML field for search display. Most tags are stripped out and the # maximum length is set to 200 characters. def search_md_sanitize(object, field) diff --git a/app/helpers/snippets_helper.rb b/app/helpers/snippets_helper.rb index 2fd64b3441e..b447d4952e7 100644 --- a/app/helpers/snippets_helper.rb +++ b/app/helpers/snippets_helper.rb @@ -1,8 +1,7 @@ module SnippetsHelper def reliable_snippet_path(snippet, opts = nil) if snippet.project_id? - namespace_project_snippet_path(snippet.project.namespace, - snippet.project, snippet, opts) + project_snippet_path(snippet.project, snippet, opts) else snippet_path(snippet, opts) end @@ -10,7 +9,7 @@ module SnippetsHelper def download_snippet_path(snippet) if snippet.project_id - raw_namespace_project_snippet_path(@project.namespace, @project, snippet, inline: false) + raw_project_snippet_path(@project, snippet, inline: false) else raw_snippet_path(snippet, inline: false) end @@ -21,7 +20,7 @@ module SnippetsHelper # @returns String, path to snippet index def subject_snippets_path(subject = nil, opts = nil) if subject.is_a?(Project) - namespace_project_snippets_path(subject.namespace, subject, opts) + project_snippets_path(subject, opts) else # assume subject === User dashboard_snippets_path(opts) end diff --git a/app/helpers/tab_helper.rb b/app/helpers/tab_helper.rb index 1a55ee05996..ee701076a14 100644 --- a/app/helpers/tab_helper.rb +++ b/app/helpers/tab_helper.rb @@ -107,8 +107,7 @@ module TabHelper def branches_tab_class if current_controller?(:protected_branches) || current_controller?(:branches) || - current_page?(namespace_project_repository_path(@project.namespace, - @project)) + current_page?(project_repository_path(@project)) 'active' end end diff --git a/app/helpers/tags_helper.rb b/app/helpers/tags_helper.rb index 31aaf9e5607..d000d6b1c0a 100644 --- a/app/helpers/tags_helper.rb +++ b/app/helpers/tags_helper.rb @@ -10,7 +10,7 @@ module TagsHelper } options = exist_opts.merge(options) - namespace_project_tags_path(@project.namespace, @project, @id, options) + project_tags_path(@project, @id, options) end def tag_list(project) diff --git a/app/helpers/todos_helper.rb b/app/helpers/todos_helper.rb index 3d1b3a4711a..2a7aa299e83 100644 --- a/app/helpers/todos_helper.rb +++ b/app/helpers/todos_helper.rb @@ -39,7 +39,7 @@ module TodosHelper anchor = dom_id(todo.note) if todo.note.present? if todo.for_commit? - namespace_project_commit_path(todo.project.namespace.becomes(Namespace), todo.project, + project_commit_path(todo.project, todo.target, anchor: anchor) else path = [todo.project.namespace.becomes(Namespace), todo.project, todo.target] diff --git a/app/mailers/emails/issues.rb b/app/mailers/emails/issues.rb index 0f847841295..64ca2d2eacf 100644 --- a/app/mailers/emails/issues.rb +++ b/app/mailers/emails/issues.rb @@ -31,7 +31,7 @@ module Emails setup_issue_mail(issue_id, recipient_id) @label_names = label_names - @labels_url = namespace_project_labels_url(@project.namespace, @project) + @labels_url = project_labels_url(@project) mail_answer_thread(@issue, issue_thread_options(updated_by_user_id, recipient_id)) end @@ -56,7 +56,7 @@ module Emails def setup_issue_mail(issue_id, recipient_id) @issue = Issue.find(issue_id) @project = @issue.project - @target_url = namespace_project_issue_url(@project.namespace, @project, @issue) + @target_url = project_issue_url(@project, @issue) @sent_notification = SentNotification.record(@issue, recipient_id, reply_key) end diff --git a/app/mailers/emails/merge_requests.rb b/app/mailers/emails/merge_requests.rb index ec27ac517db..3626f8ce416 100644 --- a/app/mailers/emails/merge_requests.rb +++ b/app/mailers/emails/merge_requests.rb @@ -22,7 +22,7 @@ module Emails setup_merge_request_mail(merge_request_id, recipient_id) @label_names = label_names - @labels_url = namespace_project_labels_url(@project.namespace, @project) + @labels_url = project_labels_url(@project) mail_answer_thread(@merge_request, merge_request_thread_options(updated_by_user_id, recipient_id)) end @@ -59,7 +59,7 @@ module Emails def setup_merge_request_mail(merge_request_id, recipient_id) @merge_request = MergeRequest.find(merge_request_id) @project = @merge_request.project - @target_url = namespace_project_merge_request_url(@project.namespace, @project, @merge_request) + @target_url = project_merge_request_url(@project, @merge_request) @sent_notification = SentNotification.record(@merge_request, recipient_id, reply_key) end diff --git a/app/mailers/emails/notes.rb b/app/mailers/emails/notes.rb index 00707a0023e..77a82b895ce 100644 --- a/app/mailers/emails/notes.rb +++ b/app/mailers/emails/notes.rb @@ -4,7 +4,7 @@ module Emails setup_note_mail(note_id, recipient_id) @commit = @note.noteable - @target_url = namespace_project_commit_url(*note_target_url_options) + @target_url = project_commit_url(*note_target_url_options) mail_answer_thread(@commit, note_thread_options(recipient_id)) end @@ -12,7 +12,7 @@ module Emails setup_note_mail(note_id, recipient_id) @issue = @note.noteable - @target_url = namespace_project_issue_url(*note_target_url_options) + @target_url = project_issue_url(*note_target_url_options) mail_answer_thread(@issue, note_thread_options(recipient_id)) end @@ -20,7 +20,7 @@ module Emails setup_note_mail(note_id, recipient_id) @merge_request = @note.noteable - @target_url = namespace_project_merge_request_url(*note_target_url_options) + @target_url = project_merge_request_url(*note_target_url_options) mail_answer_thread(@merge_request, note_thread_options(recipient_id)) end @@ -28,7 +28,7 @@ module Emails setup_note_mail(note_id, recipient_id) @snippet = @note.noteable - @target_url = namespace_project_snippet_url(*note_target_url_options) + @target_url = project_snippet_url(*note_target_url_options) mail_answer_thread(@snippet, note_thread_options(recipient_id)) end @@ -43,7 +43,7 @@ module Emails private def note_target_url_options - [@project.namespace, @project, @note.noteable, anchor: "note_#{@note.id}"] + [@project, @note.noteable, anchor: "note_#{@note.id}"] end def note_thread_options(recipient_id) diff --git a/app/mailers/emails/projects.rb b/app/mailers/emails/projects.rb index e0af7081411..761d873c01c 100644 --- a/app/mailers/emails/projects.rb +++ b/app/mailers/emails/projects.rb @@ -3,7 +3,7 @@ module Emails def project_was_moved_email(project_id, user_id, old_path_with_namespace) @current_user = @user = User.find user_id @project = Project.find project_id - @target_url = namespace_project_url(@project.namespace, @project) + @target_url = project_url(@project) @old_path_with_namespace = old_path_with_namespace mail(to: @user.notification_email, subject: subject("Project was moved")) diff --git a/app/mailers/notify.rb b/app/mailers/notify.rb index f315e38bcaa..eaac6fcb548 100644 --- a/app/mailers/notify.rb +++ b/app/mailers/notify.rb @@ -1,5 +1,6 @@ class Notify < BaseMailer include ActionDispatch::Routing::PolymorphicRoutes + include GitlabRoutingHelper include Emails::Issues include Emails::MergeRequests diff --git a/app/models/appearance.rb b/app/models/appearance.rb index c79326e8427..f9c48482be7 100644 --- a/app/models/appearance.rb +++ b/app/models/appearance.rb @@ -10,5 +10,5 @@ class Appearance < ActiveRecord::Base mount_uploader :logo, AttachmentUploader mount_uploader :header_logo, AttachmentUploader - has_many :uploads, as: :model, dependent: :destroy + has_many :uploads, as: :model, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent end diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb index 668caef0d2c..b0d7f7ef5f5 100644 --- a/app/models/application_setting.rb +++ b/app/models/application_setting.rb @@ -13,13 +13,13 @@ class ApplicationSetting < ActiveRecord::Base [\r\n] # any number of newline characters }x - serialize :restricted_visibility_levels # rubocop:disable Cop/ActiverecordSerialize - serialize :import_sources # rubocop:disable Cop/ActiverecordSerialize - serialize :disabled_oauth_sign_in_sources, Array # rubocop:disable Cop/ActiverecordSerialize - serialize :domain_whitelist, Array # rubocop:disable Cop/ActiverecordSerialize - serialize :domain_blacklist, Array # rubocop:disable Cop/ActiverecordSerialize - serialize :repository_storages # rubocop:disable Cop/ActiverecordSerialize - serialize :sidekiq_throttling_queues, Array # rubocop:disable Cop/ActiverecordSerialize + serialize :restricted_visibility_levels # rubocop:disable Cop/ActiveRecordSerialize + serialize :import_sources # rubocop:disable Cop/ActiveRecordSerialize + serialize :disabled_oauth_sign_in_sources, Array # rubocop:disable Cop/ActiveRecordSerialize + serialize :domain_whitelist, Array # rubocop:disable Cop/ActiveRecordSerialize + serialize :domain_blacklist, Array # rubocop:disable Cop/ActiveRecordSerialize + serialize :repository_storages # rubocop:disable Cop/ActiveRecordSerialize + serialize :sidekiq_throttling_queues, Array # rubocop:disable Cop/ActiveRecordSerialize cache_markdown_field :sign_in_text cache_markdown_field :help_page_text diff --git a/app/models/audit_event.rb b/app/models/audit_event.rb index 46d412fbd72..112a8778b4e 100644 --- a/app/models/audit_event.rb +++ b/app/models/audit_event.rb @@ -1,5 +1,5 @@ class AuditEvent < ActiveRecord::Base - serialize :details, Hash # rubocop:disable Cop/ActiverecordSerialize + serialize :details, Hash # rubocop:disable Cop/ActiveRecordSerialize belongs_to :user, foreign_key: :author_id diff --git a/app/models/board.rb b/app/models/board.rb index 18081a32157..97d0f550925 100644 --- a/app/models/board.rb +++ b/app/models/board.rb @@ -1,7 +1,7 @@ class Board < ActiveRecord::Base belongs_to :project - has_many :lists, -> { order(:list_type, :position) }, dependent: :delete_all + has_many :lists, -> { order(:list_type, :position) }, dependent: :delete_all # rubocop:disable Cop/ActiveRecordDependent validates :project, presence: true diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index a300536532b..48586ba8910 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -19,8 +19,8 @@ module Ci ) end - serialize :options # rubocop:disable Cop/ActiverecordSerialize - serialize :yaml_variables, Gitlab::Serializer::Ci::Variables # rubocop:disable Cop/ActiverecordSerialize + serialize :options # rubocop:disable Cop/ActiveRecordSerialize + serialize :yaml_variables, Gitlab::Serializer::Ci::Variables # rubocop:disable Cop/ActiveRecordSerialize delegate :name, to: :project, prefix: true @@ -176,13 +176,22 @@ module Ci # * Lowercased # * Anything not matching [a-z0-9-] is replaced with a - # * Maximum length is 63 bytes + # * First/Last Character is not a hyphen def ref_slug - slugified = ref.to_s.downcase - slugified.gsub(/[^a-z0-9]/, '-')[0..62] + ref.to_s + .downcase + .gsub(/[^a-z0-9]/, '-')[0..62] + .gsub(/(\A-+|-+\z)/, '') end # Variables whose value does not depend on environment def simple_variables + variables(environment: nil) + end + + # All variables, including those dependent on environment, which could + # contain unexpanded variables. + def variables(environment: persisted_environment) variables = predefined_variables variables += project.predefined_variables variables += pipeline.predefined_variables @@ -191,15 +200,11 @@ module Ci variables += project.deployment_variables if has_environment? variables += yaml_variables variables += user_variables - variables += project.secret_variables_for(ref).map(&:to_runner_variable) + variables += secret_variables(environment: environment) variables += trigger_request.user_variables if trigger_request - variables - end + variables += persisted_environment_variables if environment - # All variables, including those dependent on environment, which could - # contain unexpanded variables. - def variables - simple_variables.concat(persisted_environment_variables) + variables end def merge_request @@ -367,6 +372,11 @@ module Ci ] end + def secret_variables(environment: persisted_environment) + project.secret_variables_for(ref: ref, environment: environment) + .map(&:to_runner_variable) + end + def steps [Gitlab::Ci::Build::Step.from_commands(self), Gitlab::Ci::Build::Step.from_after_script(self)].compact diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index 364858964b0..b646b32fc64 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -14,7 +14,7 @@ module Ci has_many :stages has_many :statuses, class_name: 'CommitStatus', foreign_key: :commit_id has_many :builds, foreign_key: :commit_id - has_many :trigger_requests, dependent: :destroy, foreign_key: :commit_id + has_many :trigger_requests, dependent: :destroy, foreign_key: :commit_id # rubocop:disable Cop/ActiveRecordDependent # Merge requests for which the current pipeline is running against # the merge request's latest commit. @@ -326,10 +326,24 @@ module Ci end end + def ci_yaml_file_path + if project.ci_config_path.blank? + '.gitlab-ci.yml' + else + project.ci_config_path + end + end + def ci_yaml_file return @ci_yaml_file if defined?(@ci_yaml_file) - @ci_yaml_file = project.repository.gitlab_ci_yml_for(sha) rescue nil + @ci_yaml_file = begin + project.repository.gitlab_ci_yml_for(sha, ci_yaml_file_path) + rescue Rugged::ReferenceError, GRPC::NotFound, GRPC::Internal + self.yaml_errors = + "Failed to load CI/CD config file at #{ci_yaml_file_path}" + nil + end end def has_yaml_errors? @@ -377,7 +391,8 @@ module Ci def predefined_variables [ - { key: 'CI_PIPELINE_ID', value: id.to_s, public: true } + { key: 'CI_PIPELINE_ID', value: id.to_s, public: true }, + { key: 'CI_CONFIG_PATH', value: ci_yaml_file_path, public: true } ] end diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb index d12f96f3d0b..f5790f9744f 100644 --- a/app/models/ci/runner.rb +++ b/app/models/ci/runner.rb @@ -8,7 +8,7 @@ module Ci FORM_EDITABLE = %i[description tag_list active run_untagged locked].freeze has_many :builds - has_many :runner_projects, dependent: :destroy + has_many :runner_projects, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent has_many :projects, through: :runner_projects has_one :last_build, ->() { order('id DESC') }, class_name: 'Ci::Build' diff --git a/app/models/ci/trigger_request.rb b/app/models/ci/trigger_request.rb index 564334ad1ad..c58ce5c3717 100644 --- a/app/models/ci/trigger_request.rb +++ b/app/models/ci/trigger_request.rb @@ -6,7 +6,7 @@ module Ci belongs_to :pipeline, foreign_key: :commit_id has_many :builds - serialize :variables # rubocop:disable Cop/ActiverecordSerialize + serialize :variables # rubocop:disable Cop/ActiveRecordSerialize def user_variables return [] unless variables diff --git a/app/models/ci/variable.rb b/app/models/ci/variable.rb index 96d6e120998..0b8d0ff881a 100644 --- a/app/models/ci/variable.rb +++ b/app/models/ci/variable.rb @@ -5,7 +5,7 @@ module Ci belongs_to :project - validates :key, uniqueness: { scope: :project_id } + validates :key, uniqueness: { scope: [:project_id, :environment_scope] } scope :unprotected, -> { where(protected: false) } end diff --git a/app/models/concerns/awardable.rb b/app/models/concerns/awardable.rb index a7fd0a15f0f..f4f9b037957 100644 --- a/app/models/concerns/awardable.rb +++ b/app/models/concerns/awardable.rb @@ -2,7 +2,7 @@ module Awardable extend ActiveSupport::Concern included do - has_many :award_emoji, -> { includes(:user).order(:id) }, as: :awardable, dependent: :destroy + has_many :award_emoji, -> { includes(:user).order(:id) }, as: :awardable, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent if self < Participable # By default we always load award_emoji user association diff --git a/app/models/concerns/cache_markdown_field.rb b/app/models/concerns/cache_markdown_field.rb index eb32bf3d32a..95152dcd68c 100644 --- a/app/models/concerns/cache_markdown_field.rb +++ b/app/models/concerns/cache_markdown_field.rb @@ -78,7 +78,7 @@ module CacheMarkdownField def cached_html_up_to_date?(markdown_field) html_field = cached_markdown_fields.html_field(markdown_field) - cached = !cached_html_for(markdown_field).nil? && !__send__(markdown_field).nil? + cached = cached_html_for(markdown_field).present? && __send__(markdown_field).present? return false unless cached markdown_changed = attribute_changed?(markdown_field) || false diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb index d178ee4422b..23cb85600da 100644 --- a/app/models/concerns/issuable.rb +++ b/app/models/concerns/issuable.rb @@ -30,7 +30,7 @@ module Issuable belongs_to :updated_by, class_name: "User" belongs_to :last_edited_by, class_name: 'User' belongs_to :milestone - has_many :notes, as: :noteable, inverse_of: :noteable, dependent: :destroy do + has_many :notes, as: :noteable, inverse_of: :noteable, dependent: :destroy do # rubocop:disable Cop/ActiveRecordDependent def authors_loaded? # We check first if we're loaded to not load unnecessarily. loaded? && to_a.all? { |note| note.association(:author).loaded? } @@ -42,9 +42,9 @@ module Issuable end end - has_many :label_links, as: :target, dependent: :destroy + has_many :label_links, as: :target, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent has_many :labels, through: :label_links - has_many :todos, as: :target, dependent: :destroy + has_many :todos, as: :target, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent has_one :metrics @@ -102,6 +102,14 @@ module Issuable def locking_enabled? title_changed? || description_changed? end + + def allows_multiple_assignees? + false + end + + def has_multiple_assignees? + assignees.count > 1 + end end module ClassMethods diff --git a/app/models/concerns/protected_ref.rb b/app/models/concerns/protected_ref.rb index 47e71c58557..fc6b840f7a8 100644 --- a/app/models/concerns/protected_ref.rb +++ b/app/models/concerns/protected_ref.rb @@ -17,7 +17,7 @@ module ProtectedRef class_methods do def protected_ref_access_levels(*types) types.each do |type| - has_many :"#{type}_access_levels", dependent: :destroy + has_many :"#{type}_access_levels", dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent validates :"#{type}_access_levels", length: { is: 1, message: "are restricted to a single instance per #{self.model_name.human}." } diff --git a/app/models/concerns/routable.rb b/app/models/concerns/routable.rb index ec7796a9dbb..f5048d17d80 100644 --- a/app/models/concerns/routable.rb +++ b/app/models/concerns/routable.rb @@ -4,8 +4,8 @@ module Routable extend ActiveSupport::Concern included do - has_one :route, as: :source, autosave: true, dependent: :destroy - has_many :redirect_routes, as: :source, autosave: true, dependent: :destroy + has_one :route, as: :source, autosave: true, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent + has_many :redirect_routes, as: :source, autosave: true, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent validates_associated :route validates :route, presence: true @@ -103,8 +103,12 @@ module Routable def full_path return uncached_full_path unless RequestStore.active? - key = "routable/full_path/#{self.class.name}/#{self.id}" - RequestStore[key] ||= uncached_full_path + RequestStore[full_path_key] ||= uncached_full_path + end + + def expires_full_path_cache + RequestStore.delete(full_path_key) if RequestStore.active? + @full_path = nil end def build_full_path @@ -135,6 +139,10 @@ module Routable path_changed? || parent_changed? end + def full_path_key + @full_path_key ||= "routable/full_path/#{self.class.name}/#{self.id}" + end + def build_full_name if parent && name parent.human_name + ' / ' + name diff --git a/app/models/concerns/sortable.rb b/app/models/concerns/sortable.rb index a155a064032..fdacfa5a194 100644 --- a/app/models/concerns/sortable.rb +++ b/app/models/concerns/sortable.rb @@ -5,6 +5,25 @@ module Sortable extend ActiveSupport::Concern + module DropDefaultScopeOnFinders + # Override these methods to drop the `ORDER BY id DESC` default scope. + # See http://dba.stackexchange.com/a/110919 for why we do this. + %i[find find_by find_by!].each do |meth| + define_method meth do |*args, &block| + return super(*args, &block) if block + + unordered_relation = unscope(:order) + + # We cannot simply call `meth` on `unscope(:order)`, since that is also + # an instance of the same relation class this module is included into, + # which means we'd get infinite recursion. + # We explicitly use the original implementation to prevent this. + original_impl = method(__method__).super_method.unbind + original_impl.bind(unordered_relation).call(*args) + end + end + end + included do # By default all models should be ordered # by created_at field starting from newest @@ -18,6 +37,10 @@ module Sortable scope :order_updated_asc, -> { reorder(updated_at: :asc) } scope :order_name_asc, -> { reorder(name: :asc) } scope :order_name_desc, -> { reorder(name: :desc) } + + # All queries (relations) on this model are instances of this `relation_klass`. + relation_klass = relation_delegate_class(ActiveRecord::Relation) + relation_klass.prepend DropDefaultScopeOnFinders end module ClassMethods diff --git a/app/models/concerns/spammable.rb b/app/models/concerns/spammable.rb index 647a6cad3d7..bd75f25a210 100644 --- a/app/models/concerns/spammable.rb +++ b/app/models/concerns/spammable.rb @@ -8,7 +8,7 @@ module Spammable end included do - has_one :user_agent_detail, as: :subject, dependent: :destroy + has_one :user_agent_detail, as: :subject, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent attr_accessor :spam attr_accessor :spam_log diff --git a/app/models/concerns/subscribable.rb b/app/models/concerns/subscribable.rb index f60a0f8f438..274b38a7708 100644 --- a/app/models/concerns/subscribable.rb +++ b/app/models/concerns/subscribable.rb @@ -9,7 +9,7 @@ module Subscribable extend ActiveSupport::Concern included do - has_many :subscriptions, dependent: :destroy, as: :subscribable + has_many :subscriptions, dependent: :destroy, as: :subscribable # rubocop:disable Cop/ActiveRecordDependent end def subscribed?(user, project = nil) diff --git a/app/models/concerns/time_trackable.rb b/app/models/concerns/time_trackable.rb index 9cf83440784..b517ddaebd7 100644 --- a/app/models/concerns/time_trackable.rb +++ b/app/models/concerns/time_trackable.rb @@ -18,7 +18,7 @@ module TimeTrackable validates :time_estimate, numericality: { message: 'has an invalid format' }, allow_nil: false validate :check_negative_time_spent - has_many :timelogs, dependent: :destroy + has_many :timelogs, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent end def spend_time(options) diff --git a/app/models/deploy_key.rb b/app/models/deploy_key.rb index 053f2a11aa0..51768dd96bc 100644 --- a/app/models/deploy_key.rb +++ b/app/models/deploy_key.rb @@ -1,5 +1,5 @@ class DeployKey < Key - has_many :deploy_keys_projects, dependent: :destroy + has_many :deploy_keys_projects, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent has_many :projects, through: :deploy_keys_projects scope :in_projects, ->(projects) { joins(:deploy_keys_projects).where('deploy_keys_projects.project_id in (?)', projects) } diff --git a/app/models/diff_note.rb b/app/models/diff_note.rb index 20ef1378500..e9a60e6ce09 100644 --- a/app/models/diff_note.rb +++ b/app/models/diff_note.rb @@ -6,9 +6,9 @@ class DiffNote < Note NOTEABLE_TYPES = %w(MergeRequest Commit).freeze - serialize :original_position, Gitlab::Diff::Position # rubocop:disable Cop/ActiverecordSerialize - serialize :position, Gitlab::Diff::Position # rubocop:disable Cop/ActiverecordSerialize - serialize :change_position, Gitlab::Diff::Position # rubocop:disable Cop/ActiverecordSerialize + serialize :original_position, Gitlab::Diff::Position # rubocop:disable Cop/ActiveRecordSerialize + serialize :position, Gitlab::Diff::Position # rubocop:disable Cop/ActiveRecordSerialize + serialize :change_position, Gitlab::Diff::Position # rubocop:disable Cop/ActiveRecordSerialize validates :original_position, presence: true validates :position, presence: true diff --git a/app/models/environment.rb b/app/models/environment.rb index 66c96d0f586..e9ebf0637f3 100644 --- a/app/models/environment.rb +++ b/app/models/environment.rb @@ -6,7 +6,7 @@ class Environment < ActiveRecord::Base belongs_to :project, required: true, validate: true - has_many :deployments, dependent: :destroy + has_many :deployments, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent has_one :last_deployment, -> { order('deployments.id DESC') }, class_name: 'Deployment' before_validation :nullify_external_url @@ -218,8 +218,7 @@ class Environment < ActiveRecord::Base end def etag_cache_key - Gitlab::Routing.url_helpers.namespace_project_environments_path( - project.namespace, + Gitlab::Routing.url_helpers.project_environments_path( project, format: :json) end diff --git a/app/models/event.rb b/app/models/event.rb index 29bc141c5cd..8d93a228494 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -50,7 +50,7 @@ class Event < ActiveRecord::Base belongs_to :target, polymorphic: true # rubocop:disable Cop/PolymorphicAssociations # For Hash only - serialize :data # rubocop:disable Cop/ActiverecordSerialize + serialize :data # rubocop:disable Cop/ActiveRecordSerialize # Callbacks after_create :reset_project_activity diff --git a/app/models/forked_project_link.rb b/app/models/forked_project_link.rb index 36cf7ad6a28..8d35864eff6 100644 --- a/app/models/forked_project_link.rb +++ b/app/models/forked_project_link.rb @@ -1,4 +1,4 @@ class ForkedProjectLink < ActiveRecord::Base - belongs_to :forked_to_project, class_name: 'Project' - belongs_to :forked_from_project, class_name: 'Project' + belongs_to :forked_to_project, -> { where.not(pending_delete: true) }, class_name: 'Project' + belongs_to :forked_from_project, -> { where.not(pending_delete: true) }, class_name: 'Project' end diff --git a/app/models/group.rb b/app/models/group.rb index a6fdb30f84c..b93fce6100d 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -8,7 +8,7 @@ class Group < Namespace include Referable include SelectForProjectAuthorization - has_many :group_members, -> { where(requested_at: nil) }, dependent: :destroy, as: :source + has_many :group_members, -> { where(requested_at: nil) }, dependent: :destroy, as: :source # rubocop:disable Cop/ActiveRecordDependent alias_method :members, :group_members has_many :users, through: :group_members has_many :owners, @@ -16,11 +16,11 @@ class Group < Namespace through: :group_members, source: :user - has_many :requesters, -> { where.not(requested_at: nil) }, dependent: :destroy, as: :source, class_name: 'GroupMember' + has_many :requesters, -> { where.not(requested_at: nil) }, dependent: :destroy, as: :source, class_name: 'GroupMember' # rubocop:disable Cop/ActiveRecordDependent - has_many :project_group_links, dependent: :destroy + has_many :project_group_links, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent has_many :shared_projects, through: :project_group_links, source: :project - has_many :notification_settings, dependent: :destroy, as: :source + has_many :notification_settings, dependent: :destroy, as: :source # rubocop:disable Cop/ActiveRecordDependent has_many :labels, class_name: 'GroupLabel' validate :avatar_type, if: ->(user) { user.avatar.present? && user.avatar_changed? } @@ -31,7 +31,7 @@ class Group < Namespace validates :two_factor_grace_period, presence: true, numericality: { greater_than_or_equal_to: 0 } mount_uploader :avatar, AvatarUploader - has_many :uploads, as: :model, dependent: :destroy + has_many :uploads, as: :model, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent after_create :post_create_hook after_destroy :post_destroy_hook diff --git a/app/models/hooks/web_hook.rb b/app/models/hooks/web_hook.rb index 7503f3739c3..7a9f8997959 100644 --- a/app/models/hooks/web_hook.rb +++ b/app/models/hooks/web_hook.rb @@ -12,7 +12,7 @@ class WebHook < ActiveRecord::Base default_value_for :repository_update_events, false default_value_for :enable_ssl_verification, true - has_many :web_hook_logs, dependent: :destroy + has_many :web_hook_logs, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent scope :push_hooks, -> { where(push_events: true) } scope :tag_push_hooks, -> { where(tag_push_events: true) } diff --git a/app/models/hooks/web_hook_log.rb b/app/models/hooks/web_hook_log.rb index d73cfcf630d..e72c125fb69 100644 --- a/app/models/hooks/web_hook_log.rb +++ b/app/models/hooks/web_hook_log.rb @@ -1,9 +1,9 @@ class WebHookLog < ActiveRecord::Base belongs_to :web_hook - serialize :request_headers, Hash # rubocop:disable Cop/ActiverecordSerialize - serialize :request_data, Hash # rubocop:disable Cop/ActiverecordSerialize - serialize :response_headers, Hash # rubocop:disable Cop/ActiverecordSerialize + serialize :request_headers, Hash # rubocop:disable Cop/ActiveRecordSerialize + serialize :request_data, Hash # rubocop:disable Cop/ActiveRecordSerialize + serialize :response_headers, Hash # rubocop:disable Cop/ActiveRecordSerialize validates :web_hook, presence: true diff --git a/app/models/issue.rb b/app/models/issue.rb index 3a9a6dba601..01f985823e1 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -23,9 +23,14 @@ class Issue < ActiveRecord::Base belongs_to :project belongs_to :moved_to, class_name: 'Issue' - has_many :events, as: :target, dependent: :destroy + has_many :events, as: :target, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent - has_many :merge_requests_closing_issues, class_name: 'MergeRequestsClosingIssues', dependent: :delete_all + has_many :merge_requests_closing_issues, + class_name: 'MergeRequestsClosingIssues', + dependent: :delete_all # rubocop:disable Cop/ActiveRecordDependent + + 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 @@ -295,11 +300,7 @@ class Issue < ActiveRecord::Base end def expire_etag_cache - key = Gitlab::Routing.url_helpers.realtime_changes_namespace_project_issue_path( - project.namespace, - project, - self - ) + key = Gitlab::Routing.url_helpers.realtime_changes_project_issue_path(project, self) Gitlab::EtagCaching::Store.new.touch(key) end end diff --git a/app/models/label.rb b/app/models/label.rb index ed6a8411da9..674bb3f2720 100644 --- a/app/models/label.rb +++ b/app/models/label.rb @@ -15,9 +15,9 @@ class Label < ActiveRecord::Base default_value_for :color, DEFAULT_COLOR - has_many :lists, dependent: :destroy + has_many :lists, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent has_many :priorities, class_name: 'LabelPriority' - has_many :label_links, dependent: :destroy + has_many :label_links, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent has_many :issues, through: :label_links, source: :target, source_type: 'Issue' has_many :merge_requests, through: :label_links, source: :target, source_type: 'MergeRequest' diff --git a/app/models/legacy_diff_note.rb b/app/models/legacy_diff_note.rb index 2d5909ab25e..c36be956ff0 100644 --- a/app/models/legacy_diff_note.rb +++ b/app/models/legacy_diff_note.rb @@ -7,7 +7,7 @@ class LegacyDiffNote < Note include NoteOnDiff - serialize :st_diff # rubocop:disable Cop/ActiverecordSerialize + serialize :st_diff # rubocop:disable Cop/ActiveRecordSerialize validates :line_code, presence: true, line_code: true diff --git a/app/models/lfs_object.rb b/app/models/lfs_object.rb index 7712d5783e0..b7cf96abe83 100644 --- a/app/models/lfs_object.rb +++ b/app/models/lfs_object.rb @@ -1,5 +1,5 @@ class LfsObject < ActiveRecord::Base - has_many :lfs_objects_projects, dependent: :destroy + has_many :lfs_objects_projects, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent has_many :projects, through: :lfs_objects_projects validates :oid, presence: true, uniqueness: true diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index c099d731082..2752181ed79 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -12,19 +12,21 @@ class MergeRequest < ActiveRecord::Base belongs_to :source_project, class_name: "Project" belongs_to :merge_user, class_name: "User" - has_many :merge_request_diffs, dependent: :destroy + has_many :merge_request_diffs has_one :merge_request_diff, -> { order('merge_request_diffs.id DESC') } belongs_to :head_pipeline, foreign_key: "head_pipeline_id", class_name: "Ci::Pipeline" - has_many :events, as: :target, dependent: :destroy + has_many :events, as: :target, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent - has_many :merge_requests_closing_issues, class_name: 'MergeRequestsClosingIssues', dependent: :delete_all + has_many :merge_requests_closing_issues, + class_name: 'MergeRequestsClosingIssues', + dependent: :delete_all # rubocop:disable Cop/ActiveRecordDependent belongs_to :assignee, class_name: "User" - serialize :merge_params, Hash # rubocop:disable Cop/ActiverecordSerialize + serialize :merge_params, Hash # rubocop:disable Cop/ActiveRecordSerialize after_create :ensure_merge_request_diff, unless: :importing? after_update :reload_diff_if_branch_changed @@ -197,11 +199,19 @@ class MergeRequest < ActiveRecord::Base } end - # This method is needed for compatibility with issues to not mess view and other code + # These method are needed for compatibility with issues to not mess view and other code def assignees Array(assignee) end + def assignee_ids + Array(assignee_id) + end + + def assignee_ids=(ids) + write_attribute(:assignee_id, ids.last) + end + def assignee_or_author?(user) author_id == user.id || assignee_id == user.id end diff --git a/app/models/merge_request_diff.rb b/app/models/merge_request_diff.rb index f1ee4d3f7a9..0cbf58a2325 100644 --- a/app/models/merge_request_diff.rb +++ b/app/models/merge_request_diff.rb @@ -12,8 +12,8 @@ class MergeRequestDiff < ActiveRecord::Base belongs_to :merge_request has_many :merge_request_diff_files, -> { order(:merge_request_diff_id, :relative_order) } - serialize :st_commits # rubocop:disable Cop/ActiverecordSerialize - serialize :st_diffs # rubocop:disable Cop/ActiverecordSerialize + serialize :st_commits # rubocop:disable Cop/ActiveRecordSerialize + serialize :st_diffs # rubocop:disable Cop/ActiveRecordSerialize state_machine :state, initial: :empty do state :collected diff --git a/app/models/milestone.rb b/app/models/milestone.rb index d2e2749f70d..c0ccbf8e27e 100644 --- a/app/models/milestone.rb +++ b/app/models/milestone.rb @@ -21,7 +21,7 @@ class Milestone < ActiveRecord::Base has_many :issues has_many :labels, -> { distinct.reorder('labels.title') }, through: :issues has_many :merge_requests - has_many :events, as: :target, dependent: :destroy + has_many :events, as: :target, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent scope :active, -> { with_state(:active) } scope :closed, -> { with_state(:closed) } diff --git a/app/models/namespace.rb b/app/models/namespace.rb index 672eab94c07..15713fc5f6d 100644 --- a/app/models/namespace.rb +++ b/app/models/namespace.rb @@ -15,13 +15,13 @@ class Namespace < ActiveRecord::Base cache_markdown_field :description, pipeline: :description - has_many :projects, dependent: :destroy + has_many :projects, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent has_many :project_statistics belongs_to :owner, class_name: "User" belongs_to :parent, class_name: "Namespace" has_many :children, class_name: "Namespace", foreign_key: :parent_id - has_one :chat_team, dependent: :destroy + has_one :chat_team, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent validates :owner, presence: true, unless: ->(n) { n.type == "Group" } validates :name, diff --git a/app/models/note.rb b/app/models/note.rb index ca6999427c0..3d39047d32f 100644 --- a/app/models/note.rb +++ b/app/models/note.rb @@ -46,8 +46,8 @@ class Note < ActiveRecord::Base belongs_to :updated_by, class_name: "User" belongs_to :last_edited_by, class_name: 'User' - has_many :todos, dependent: :destroy - has_many :events, as: :target, dependent: :destroy + has_many :todos, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent + has_many :events, as: :target, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent has_one :system_note_metadata delegate :gfm_reference, :local_reference, to: :noteable @@ -330,8 +330,7 @@ class Note < ActiveRecord::Base def expire_etag_cache return unless for_issue? - key = Gitlab::Routing.url_helpers.namespace_project_noteable_notes_path( - noteable.project.namespace, + key = Gitlab::Routing.url_helpers.project_noteable_notes_path( noteable.project, target_type: noteable_type.underscore, target_id: noteable.id diff --git a/app/models/personal_access_token.rb b/app/models/personal_access_token.rb index 6e13f9b2089..654be927ed8 100644 --- a/app/models/personal_access_token.rb +++ b/app/models/personal_access_token.rb @@ -3,7 +3,7 @@ class PersonalAccessToken < ActiveRecord::Base include TokenAuthenticatable add_authentication_token_field :token - serialize :scopes, Array # rubocop:disable Cop/ActiverecordSerialize + serialize :scopes, Array # rubocop:disable Cop/ActiveRecordSerialize belongs_to :user diff --git a/app/models/project.rb b/app/models/project.rb index 8140ed3763f..74c15d2508b 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -59,6 +59,7 @@ class Project < ActiveRecord::Base update_column(:last_repository_updated_at, self.created_at) end + before_destroy :remove_private_deploy_keys after_destroy :remove_pages # update visibility_level of forks @@ -80,96 +81,108 @@ class Project < ActiveRecord::Base belongs_to :namespace has_one :last_event, -> {order 'events.created_at DESC'}, class_name: 'Event' - has_many :boards, before_add: :validate_board_limit, dependent: :destroy + has_many :boards, before_add: :validate_board_limit # Project services - has_one :campfire_service, dependent: :destroy - has_one :drone_ci_service, dependent: :destroy - has_one :emails_on_push_service, dependent: :destroy - has_one :pipelines_email_service, dependent: :destroy - has_one :irker_service, dependent: :destroy - has_one :pivotaltracker_service, dependent: :destroy - has_one :hipchat_service, dependent: :destroy - has_one :flowdock_service, dependent: :destroy - has_one :assembla_service, dependent: :destroy - has_one :asana_service, dependent: :destroy - has_one :gemnasium_service, dependent: :destroy - has_one :mattermost_slash_commands_service, dependent: :destroy - has_one :mattermost_service, dependent: :destroy - has_one :slack_slash_commands_service, dependent: :destroy - has_one :slack_service, dependent: :destroy - has_one :buildkite_service, dependent: :destroy - has_one :bamboo_service, dependent: :destroy - has_one :teamcity_service, dependent: :destroy - has_one :pushover_service, dependent: :destroy - has_one :jira_service, dependent: :destroy - has_one :redmine_service, dependent: :destroy - has_one :custom_issue_tracker_service, dependent: :destroy - has_one :bugzilla_service, dependent: :destroy - has_one :gitlab_issue_tracker_service, dependent: :destroy, inverse_of: :project - has_one :external_wiki_service, dependent: :destroy - has_one :kubernetes_service, dependent: :destroy, inverse_of: :project - has_one :prometheus_service, dependent: :destroy, inverse_of: :project - has_one :mock_ci_service, dependent: :destroy - has_one :mock_deployment_service, dependent: :destroy - has_one :mock_monitoring_service, dependent: :destroy - has_one :microsoft_teams_service, dependent: :destroy - - has_one :forked_project_link, dependent: :destroy, foreign_key: "forked_to_project_id" + has_one :campfire_service + has_one :drone_ci_service + has_one :emails_on_push_service + has_one :pipelines_email_service + has_one :irker_service + has_one :pivotaltracker_service + has_one :hipchat_service + has_one :flowdock_service + has_one :assembla_service + has_one :asana_service + has_one :gemnasium_service + has_one :mattermost_slash_commands_service + has_one :mattermost_service + has_one :slack_slash_commands_service + has_one :slack_service + has_one :buildkite_service + has_one :bamboo_service + has_one :teamcity_service + has_one :pushover_service + has_one :jira_service + has_one :redmine_service + has_one :custom_issue_tracker_service + has_one :bugzilla_service + has_one :gitlab_issue_tracker_service, inverse_of: :project + has_one :external_wiki_service + has_one :kubernetes_service, inverse_of: :project + has_one :prometheus_service, inverse_of: :project + has_one :mock_ci_service + has_one :mock_deployment_service + has_one :mock_monitoring_service + has_one :microsoft_teams_service + + has_one :forked_project_link, foreign_key: "forked_to_project_id" has_one :forked_from_project, through: :forked_project_link has_many :forked_project_links, foreign_key: "forked_from_project_id" has_many :forks, through: :forked_project_links, source: :forked_to_project # Merge Requests for target project should be removed with it - has_many :merge_requests, dependent: :destroy, foreign_key: 'target_project_id' - has_many :issues, dependent: :destroy - has_many :labels, dependent: :destroy, class_name: 'ProjectLabel' - has_many :services, dependent: :destroy - has_many :events, dependent: :destroy - has_many :milestones, dependent: :destroy - has_many :notes, dependent: :destroy - has_many :snippets, dependent: :destroy, class_name: 'ProjectSnippet' - has_many :hooks, dependent: :destroy, class_name: 'ProjectHook' - has_many :protected_branches, dependent: :destroy - has_many :protected_tags, dependent: :destroy + has_many :merge_requests, foreign_key: 'target_project_id' + has_many :issues + has_many :labels, class_name: 'ProjectLabel' + has_many :services + has_many :events + has_many :milestones + has_many :notes + has_many :snippets, class_name: 'ProjectSnippet' + has_many :hooks, class_name: 'ProjectHook' + has_many :protected_branches + has_many :protected_tags has_many :project_authorizations has_many :authorized_users, through: :project_authorizations, source: :user, class_name: 'User' - has_many :project_members, -> { where(requested_at: nil) }, dependent: :destroy, as: :source + has_many :project_members, -> { where(requested_at: nil) }, + as: :source, dependent: :delete_all # rubocop:disable Cop/ActiveRecordDependent + alias_method :members, :project_members has_many :users, through: :project_members - has_many :requesters, -> { where.not(requested_at: nil) }, dependent: :destroy, as: :source, class_name: 'ProjectMember' + has_many :requesters, -> { where.not(requested_at: nil) }, + as: :source, class_name: 'ProjectMember', dependent: :delete_all # rubocop:disable Cop/ActiveRecordDependent - has_many :deploy_keys_projects, dependent: :destroy + has_many :deploy_keys_projects has_many :deploy_keys, through: :deploy_keys_projects - has_many :users_star_projects, dependent: :destroy + has_many :users_star_projects has_many :starrers, through: :users_star_projects, source: :user - has_many :releases, dependent: :destroy - has_many :lfs_objects_projects, dependent: :destroy + has_many :releases + has_many :lfs_objects_projects, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent has_many :lfs_objects, through: :lfs_objects_projects - has_many :project_group_links, dependent: :destroy + has_many :project_group_links has_many :invited_groups, through: :project_group_links, source: :group - has_many :pages_domains, dependent: :destroy - has_many :todos, dependent: :destroy - has_many :notification_settings, dependent: :destroy, as: :source - - has_one :import_data, dependent: :delete, class_name: 'ProjectImportData' - has_one :project_feature, dependent: :destroy - has_one :statistics, class_name: 'ProjectStatistics', dependent: :delete - has_many :container_repositories, dependent: :destroy - - has_many :commit_statuses, dependent: :destroy - has_many :pipelines, dependent: :destroy, class_name: 'Ci::Pipeline' - has_many :builds, class_name: 'Ci::Build' # the builds are created from the commit_statuses - has_many :runner_projects, dependent: :destroy, class_name: 'Ci::RunnerProject' + has_many :pages_domains + has_many :todos + has_many :notification_settings, as: :source, dependent: :delete_all # rubocop:disable Cop/ActiveRecordDependent + + has_one :import_data, class_name: 'ProjectImportData' + has_one :project_feature + has_one :statistics, class_name: 'ProjectStatistics' + + # Container repositories need to remove data from the container registry, + # which is not managed by the DB. Hence we're still using dependent: :destroy + # here. + has_many :container_repositories, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent + + has_many :commit_statuses + has_many :pipelines, class_name: 'Ci::Pipeline' + + # Ci::Build objects store data on the file system such as artifact files and + # build traces. Currently there's no efficient way of removing this data in + # bulk that doesn't involve loading the rows into memory. As a result we're + # still using `dependent: :destroy` here. + has_many :builds, class_name: 'Ci::Build', dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent + has_many :runner_projects, class_name: 'Ci::RunnerProject' has_many :runners, through: :runner_projects, source: :runner, class_name: 'Ci::Runner' has_many :variables, class_name: 'Ci::Variable' - has_many :triggers, dependent: :destroy, class_name: 'Ci::Trigger' - has_many :environments, dependent: :destroy - has_many :deployments, dependent: :destroy - has_many :pipeline_schedules, dependent: :destroy, class_name: 'Ci::PipelineSchedule' + has_many :triggers, class_name: 'Ci::Trigger' + has_many :environments + has_many :deployments + has_many :pipeline_schedules, class_name: 'Ci::PipelineSchedule' has_many :active_runners, -> { active }, through: :runner_projects, source: :runner, class_name: 'Ci::Runner' @@ -186,6 +199,11 @@ class Project < ActiveRecord::Base # Validations validates :creator, presence: true, on: :create validates :description, length: { maximum: 2000 }, allow_blank: true + validates :ci_config_path, + format: { without: /\.{2}/, + message: 'cannot include directory traversal.' }, + length: { maximum: 255 }, + allow_blank: true validates :name, presence: true, length: { maximum: 255 }, @@ -219,7 +237,7 @@ class Project < ActiveRecord::Base before_save :ensure_runners_token mount_uploader :avatar, AvatarUploader - has_many :uploads, as: :model, dependent: :destroy + has_many :uploads, as: :model, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent # Scopes scope :pending_delete, -> { where(pending_delete: true) } @@ -521,6 +539,11 @@ class Project < ActiveRecord::Base import_data&.destroy end + def ci_config_path=(value) + # Strip all leading slashes so that //foo -> foo + super(value&.sub(%r{\A/+}, '')&.delete("\0")) + end + def import_url=(value) return super(value) unless Gitlab::UrlSanitizer.valid?(value) @@ -675,7 +698,7 @@ class Project < ActiveRecord::Base end def web_url - Gitlab::Routing.url_helpers.namespace_project_url(self.namespace, self) + Gitlab::Routing.url_helpers.project_url(self) end def new_issue_address(author) @@ -815,7 +838,7 @@ class Project < ActiveRecord::Base end def ci_service - @ci_service ||= ci_services.reorder(nil).find_by(active: true) + @ci_service ||= ci_services.find_by(active: true) end def deployment_services @@ -823,7 +846,7 @@ class Project < ActiveRecord::Base end def deployment_service - @deployment_service ||= deployment_services.reorder(nil).find_by(active: true) + @deployment_service ||= deployment_services.find_by(active: true) end def monitoring_services @@ -831,7 +854,7 @@ class Project < ActiveRecord::Base end def monitoring_service - @monitoring_service ||= monitoring_services.reorder(nil).find_by(active: true) + @monitoring_service ||= monitoring_services.find_by(active: true) end def jira_tracker? @@ -851,7 +874,7 @@ class Project < ActiveRecord::Base def avatar_url(**args) # We use avatar_path instead of overriding avatar_url because of carrierwave. # See https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/11001/diffs#note_28659864 - avatar_path(args) || (Gitlab::Routing.url_helpers.namespace_project_avatar_url(namespace, self) if avatar_in_git) + avatar_path(args) || (Gitlab::Routing.url_helpers.project_avatar_url(self) if avatar_in_git) end # For compatibility with old code @@ -963,6 +986,7 @@ class Project < ActiveRecord::Base begin gitlab_shell.mv_repository(repository_storage_path, "#{old_path_with_namespace}.wiki", "#{new_path_with_namespace}.wiki") send_move_instructions(old_path_with_namespace) + expires_full_path_cache @old_path_with_namespace = old_path_with_namespace @@ -1014,7 +1038,8 @@ class Project < ActiveRecord::Base namespace: namespace.name, visibility_level: visibility_level, path_with_namespace: path_with_namespace, - default_branch: default_branch + default_branch: default_branch, + ci_config_path: ci_config_path } # Backward compatibility @@ -1073,21 +1098,21 @@ class Project < ActiveRecord::Base merge_requests.where(source_project_id: self.id) end - def create_repository + def create_repository(force: false) # Forked import is handled asynchronously - unless forked? - if gitlab_shell.add_repository(repository_storage_path, path_with_namespace) - repository.after_create - true - else - errors.add(:base, 'Failed to create repository via gitlab-shell') - false - end + return if forked? && !force + + if gitlab_shell.add_repository(repository_storage_path, path_with_namespace) + repository.after_create + true + else + errors.add(:base, 'Failed to create repository via gitlab-shell') + false end end def ensure_repository - create_repository unless repository_exists? + create_repository(force: true) unless repository_exists? end def repository_exists? @@ -1228,7 +1253,13 @@ class Project < ActiveRecord::Base File.join(pages_path, 'public') end + def remove_private_deploy_keys + deploy_keys.where(public: false).delete_all + end + def remove_pages + ::Projects::UpdatePagesConfigurationService.new(self).execute + # 1. We rename pages to temporary directory # 2. We wait 5 minutes, due to NFS caching # 3. We asynchronously remove pages with force @@ -1314,7 +1345,8 @@ class Project < ActiveRecord::Base variables end - def secret_variables_for(ref) + def secret_variables_for(ref:, environment: nil) + # EE would use the environment if protected_for?(ref) variables else diff --git a/app/models/project_import_data.rb b/app/models/project_import_data.rb index e3cafd4d1c6..37730474324 100644 --- a/app/models/project_import_data.rb +++ b/app/models/project_import_data.rb @@ -10,7 +10,7 @@ class ProjectImportData < ActiveRecord::Base insecure_mode: true, algorithm: 'aes-256-cbc' - serialize :data, JSON # rubocop:disable Cop/ActiverecordSerialize + serialize :data, JSON # rubocop:disable Cop/ActiveRecordSerialize validates :project, presence: true diff --git a/app/models/project_services/gitlab_issue_tracker_service.rb b/app/models/project_services/gitlab_issue_tracker_service.rb index ad4eb9536e1..5e31f393bbe 100644 --- a/app/models/project_services/gitlab_issue_tracker_service.rb +++ b/app/models/project_services/gitlab_issue_tracker_service.rb @@ -12,26 +12,26 @@ class GitlabIssueTrackerService < IssueTrackerService end def project_url - namespace_project_issues_url(project.namespace, project) + project_issues_url(project) end def new_issue_url - new_namespace_project_issue_url(namespace_id: project.namespace, project_id: project) + new_project_issue_url(project) end def issue_url(iid) - namespace_project_issue_url(namespace_id: project.namespace, project_id: project, id: iid) + project_issue_url(project, id: iid) end def project_path - namespace_project_issues_path(project.namespace, project) + project_issues_path(project) end def new_issue_path - new_namespace_project_issue_path(namespace_id: project.namespace, project_id: project) + new_project_issue_path(project) end def issue_path(iid) - namespace_project_issue_path(namespace_id: project.namespace, project_id: project, id: iid) + project_issue_path(project, id: iid) end end diff --git a/app/models/project_services/issue_tracker_service.rb b/app/models/project_services/issue_tracker_service.rb index fcc7c4bec06..1fa4cd4db30 100644 --- a/app/models/project_services/issue_tracker_service.rb +++ b/app/models/project_services/issue_tracker_service.rb @@ -21,7 +21,7 @@ class IssueTrackerService < Service end def project_path - project_url + read_attribute(:project_url) end def new_issue_path diff --git a/app/models/project_services/jira_service.rb b/app/models/project_services/jira_service.rb index 00328892b4a..8af642b44aa 100644 --- a/app/models/project_services/jira_service.rb +++ b/app/models/project_services/jira_service.rb @@ -152,8 +152,8 @@ class JiraService < IssueTrackerService url: resource_url(user_path(author)) }, project: { - name: self.project.path_with_namespace, - url: resource_url(namespace_project_path(project.namespace, self.project)) + name: project.path_with_namespace, + url: resource_url(namespace_project_path(project.namespace, project)) # rubocop:disable Cop/ProjectPathHelper }, entity: { name: noteable_type.humanize.downcase, diff --git a/app/models/project_services/kubernetes_service.rb b/app/models/project_services/kubernetes_service.rb index 48e7802c557..62f7c057c5b 100644 --- a/app/models/project_services/kubernetes_service.rb +++ b/app/models/project_services/kubernetes_service.rb @@ -96,10 +96,13 @@ class KubernetesService < DeploymentService end def predefined_variables + config = YAML.dump(kubeconfig) + variables = [ { key: 'KUBE_URL', value: api_url, public: true }, { key: 'KUBE_TOKEN', value: token, public: false }, - { key: 'KUBE_NAMESPACE', value: actual_namespace, public: true } + { key: 'KUBE_NAMESPACE', value: actual_namespace, public: true }, + { key: 'KUBECONFIG', value: config, public: false, file: true } ] if ca_pem.present? @@ -135,6 +138,14 @@ class KubernetesService < DeploymentService private + def kubeconfig + to_kubeconfig( + url: api_url, + namespace: actual_namespace, + token: token, + ca_pem: ca_pem) + end + def namespace_placeholder default_namespace || TEMPLATE_PLACEHOLDER end diff --git a/app/models/project_services/slash_commands_service.rb b/app/models/project_services/slash_commands_service.rb index 4592cb747a0..eb4da68bb7e 100644 --- a/app/models/project_services/slash_commands_service.rb +++ b/app/models/project_services/slash_commands_service.rb @@ -5,7 +5,7 @@ class SlashCommandsService < Service prop_accessor :token - has_many :chat_names, foreign_key: :service_id, dependent: :destroy + has_many :chat_names, foreign_key: :service_id, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent def valid_token?(token) self.respond_to?(:token) && diff --git a/app/models/project_wiki.rb b/app/models/project_wiki.rb index f26ee57510c..beaadbbd1ab 100644 --- a/app/models/project_wiki.rb +++ b/app/models/project_wiki.rb @@ -31,7 +31,7 @@ class ProjectWiki end def web_url - Gitlab::Routing.url_helpers.namespace_project_wiki_url(@project.namespace, @project, :home) + Gitlab::Routing.url_helpers.project_wiki_url(@project, :home) end def url_to_repo diff --git a/app/models/repository.rb b/app/models/repository.rb index 8c24e722a8b..10b429c707e 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -931,7 +931,7 @@ class Repository def is_ancestor?(ancestor_id, descendant_id) return false if ancestor_id.nil? || descendant_id.nil? - + Gitlab::GitalyClient.migrate(:is_ancestor) do |is_enabled| if is_enabled raw_repository.is_ancestor?(ancestor_id, descendant_id) @@ -1078,8 +1078,8 @@ class Repository blob_data_at(sha, '.gitlab/route-map.yml') end - def gitlab_ci_yml_for(sha) - blob_data_at(sha, '.gitlab-ci.yml') + def gitlab_ci_yml_for(sha, path = '.gitlab-ci.yml') + blob_data_at(sha, path) end private diff --git a/app/models/sent_notification.rb b/app/models/sent_notification.rb index edde7bedbab..298569cb7a6 100644 --- a/app/models/sent_notification.rb +++ b/app/models/sent_notification.rb @@ -1,5 +1,5 @@ class SentNotification < ActiveRecord::Base - serialize :position, Gitlab::Diff::Position # rubocop:disable Cop/ActiverecordSerialize + serialize :position, Gitlab::Diff::Position # rubocop:disable Cop/ActiveRecordSerialize belongs_to :project belongs_to :noteable, polymorphic: true # rubocop:disable Cop/PolymorphicAssociations diff --git a/app/models/service.rb b/app/models/service.rb index 6a0b0a5c522..6b64079215f 100644 --- a/app/models/service.rb +++ b/app/models/service.rb @@ -2,7 +2,7 @@ # and implement a set of methods class Service < ActiveRecord::Base include Sortable - serialize :properties, JSON # rubocop:disable Cop/ActiverecordSerialize + serialize :properties, JSON # rubocop:disable Cop/ActiveRecordSerialize default_value_for :active, false default_value_for :push_events, true @@ -51,6 +51,14 @@ class Service < ActiveRecord::Base active end + def show_active_box? + true + end + + def editable? + true + end + def template? template end diff --git a/app/models/snippet.rb b/app/models/snippet.rb index 54014df43b0..09d5ff46618 100644 --- a/app/models/snippet.rb +++ b/app/models/snippet.rb @@ -30,16 +30,14 @@ class Snippet < ActiveRecord::Base belongs_to :author, class_name: 'User' belongs_to :project - has_many :notes, as: :noteable, dependent: :destroy + has_many :notes, as: :noteable, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent delegate :name, :email, to: :author, prefix: true, allow_nil: true validates :author, presence: true validates :title, presence: true, length: { maximum: 255 } validates :file_name, - length: { maximum: 255 }, - format: { with: Gitlab::Regex.file_name_regex, - message: Gitlab::Regex.file_name_regex_message } + length: { maximum: 255 } validates :content, presence: true validates :visibility_level, inclusion: { in: Gitlab::VisibilityLevel.values } diff --git a/app/models/user.rb b/app/models/user.rb index 0febae84873..4411a06d429 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -41,7 +41,7 @@ class User < ActiveRecord::Base otp_secret_encryption_key: Gitlab::Application.secrets.otp_key_base devise :two_factor_backupable, otp_number_of_backup_codes: 10 - serialize :otp_backup_codes, JSON # rubocop:disable Cop/ActiverecordSerialize + serialize :otp_backup_codes, JSON # rubocop:disable Cop/ActiveRecordSerialize devise :lockable, :recoverable, :rememberable, :trackable, :validatable, :omniauthable, :confirmable, :registerable @@ -67,24 +67,24 @@ class User < ActiveRecord::Base # # Namespace for personal projects - has_one :namespace, -> { where type: nil }, dependent: :destroy, foreign_key: :owner_id, autosave: true + has_one :namespace, -> { where type: nil }, dependent: :destroy, foreign_key: :owner_id, autosave: true # rubocop:disable Cop/ActiveRecordDependent # Profile has_many :keys, -> do type = Key.arel_table[:type] where(type.not_eq('DeployKey').or(type.eq(nil))) - end, dependent: :destroy - has_many :deploy_keys, -> { where(type: 'DeployKey') }, dependent: :destroy + end, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent + has_many :deploy_keys, -> { where(type: 'DeployKey') }, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent - has_many :emails, dependent: :destroy - has_many :personal_access_tokens, dependent: :destroy - has_many :identities, dependent: :destroy, autosave: true - has_many :u2f_registrations, dependent: :destroy - has_many :chat_names, dependent: :destroy + has_many :emails, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent + has_many :personal_access_tokens, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent + has_many :identities, dependent: :destroy, autosave: true # rubocop:disable Cop/ActiveRecordDependent + has_many :u2f_registrations, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent + has_many :chat_names, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent # Groups - has_many :members, dependent: :destroy - has_many :group_members, -> { where(requested_at: nil) }, dependent: :destroy, source: 'GroupMember' + has_many :members, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent + has_many :group_members, -> { where(requested_at: nil) }, dependent: :destroy, source: 'GroupMember' # rubocop:disable Cop/ActiveRecordDependent has_many :groups, through: :group_members has_many :owned_groups, -> { where members: { access_level: Gitlab::Access::OWNER } }, through: :group_members, source: :group has_many :masters_groups, -> { where members: { access_level: Gitlab::Access::MASTER } }, through: :group_members, source: :group @@ -92,35 +92,35 @@ class User < ActiveRecord::Base # Projects has_many :groups_projects, through: :groups, source: :projects has_many :personal_projects, through: :namespace, source: :projects - has_many :project_members, -> { where(requested_at: nil) }, dependent: :destroy + has_many :project_members, -> { where(requested_at: nil) }, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent has_many :projects, through: :project_members has_many :created_projects, foreign_key: :creator_id, class_name: 'Project' - has_many :users_star_projects, dependent: :destroy + has_many :users_star_projects, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent has_many :starred_projects, through: :users_star_projects, source: :project has_many :project_authorizations has_many :authorized_projects, through: :project_authorizations, source: :project - has_many :snippets, dependent: :destroy, foreign_key: :author_id - has_many :notes, dependent: :destroy, foreign_key: :author_id - has_many :issues, dependent: :destroy, foreign_key: :author_id - has_many :merge_requests, dependent: :destroy, foreign_key: :author_id - has_many :events, dependent: :destroy, foreign_key: :author_id - has_many :subscriptions, dependent: :destroy + has_many :snippets, dependent: :destroy, foreign_key: :author_id # rubocop:disable Cop/ActiveRecordDependent + has_many :notes, dependent: :destroy, foreign_key: :author_id # rubocop:disable Cop/ActiveRecordDependent + has_many :issues, dependent: :destroy, foreign_key: :author_id # rubocop:disable Cop/ActiveRecordDependent + has_many :merge_requests, dependent: :destroy, foreign_key: :author_id # rubocop:disable Cop/ActiveRecordDependent + has_many :events, dependent: :destroy, foreign_key: :author_id # rubocop:disable Cop/ActiveRecordDependent + has_many :subscriptions, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent has_many :recent_events, -> { order "id DESC" }, foreign_key: :author_id, class_name: "Event" - has_many :oauth_applications, class_name: 'Doorkeeper::Application', as: :owner, dependent: :destroy - has_one :abuse_report, dependent: :destroy, foreign_key: :user_id - has_many :reported_abuse_reports, dependent: :destroy, foreign_key: :reporter_id, class_name: "AbuseReport" - has_many :spam_logs, dependent: :destroy - has_many :builds, dependent: :nullify, class_name: 'Ci::Build' - has_many :pipelines, dependent: :nullify, class_name: 'Ci::Pipeline' - has_many :todos, dependent: :destroy - has_many :notification_settings, dependent: :destroy - has_many :award_emoji, dependent: :destroy - has_many :triggers, dependent: :destroy, class_name: 'Ci::Trigger', foreign_key: :owner_id + has_many :oauth_applications, class_name: 'Doorkeeper::Application', as: :owner, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent + has_one :abuse_report, dependent: :destroy, foreign_key: :user_id # rubocop:disable Cop/ActiveRecordDependent + has_many :reported_abuse_reports, dependent: :destroy, foreign_key: :reporter_id, class_name: "AbuseReport" # rubocop:disable Cop/ActiveRecordDependent + has_many :spam_logs, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent + has_many :builds, dependent: :nullify, class_name: 'Ci::Build' # rubocop:disable Cop/ActiveRecordDependent + has_many :pipelines, dependent: :nullify, class_name: 'Ci::Pipeline' # rubocop:disable Cop/ActiveRecordDependent + has_many :todos, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent + has_many :notification_settings, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent + has_many :award_emoji, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent + has_many :triggers, dependent: :destroy, class_name: 'Ci::Trigger', foreign_key: :owner_id # rubocop:disable Cop/ActiveRecordDependent has_many :issue_assignees has_many :assigned_issues, class_name: "Issue", through: :issue_assignees, source: :issue - has_many :assigned_merge_requests, dependent: :nullify, foreign_key: :assignee_id, class_name: "MergeRequest" + has_many :assigned_merge_requests, dependent: :nullify, foreign_key: :assignee_id, class_name: "MergeRequest" # rubocop:disable Cop/ActiveRecordDependent # # Validations @@ -211,7 +211,7 @@ class User < ActiveRecord::Base end mount_uploader :avatar, AvatarUploader - has_many :uploads, as: :model, dependent: :destroy + has_many :uploads, as: :model, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent # Scopes scope :admins, -> { where(admin: true) } diff --git a/app/policies/base_policy.rb b/app/policies/base_policy.rb index 191c2e78a08..a605a3457c8 100644 --- a/app/policies/base_policy.rb +++ b/app/policies/base_policy.rb @@ -1,6 +1,8 @@ require_dependency 'declarative_policy' class BasePolicy < DeclarativePolicy::Base + include Gitlab::CurrentSettings + desc "User is an instance admin" with_options scope: :user, score: 0 condition(:admin) { @user&.admin? } @@ -10,4 +12,9 @@ class BasePolicy < DeclarativePolicy::Base with_options scope: :user, score: 0 condition(:can_create_group) { @user&.can_create_group } + + desc "The application is restricted from public visibility" + condition(:restricted_public_level, scope: :global) do + current_application_settings.restricted_visibility_levels.include?(Gitlab::VisibilityLevel::PUBLIC) + end end diff --git a/app/policies/global_policy.rb b/app/policies/global_policy.rb index 535faa922dd..55eefa76d3f 100644 --- a/app/policies/global_policy.rb +++ b/app/policies/global_policy.rb @@ -11,10 +11,16 @@ class GlobalPolicy < BasePolicy with_options scope: :user, score: 0 condition(:access_locked) { @user.access_locked? } - rule { anonymous }.prevent_all + rule { anonymous }.policy do + prevent :log_in + prevent :access_api + prevent :access_git + prevent :receive_notifications + prevent :use_quick_actions + prevent :create_group + end rule { default }.policy do - enable :read_users_list enable :log_in enable :access_api enable :access_git @@ -37,4 +43,8 @@ class GlobalPolicy < BasePolicy rule { access_locked }.policy do prevent :log_in end + + rule { ~restricted_public_level }.policy do + enable :read_users_list + end end diff --git a/app/policies/user_policy.rb b/app/policies/user_policy.rb index 0181ddf85e0..0905ddd9b38 100644 --- a/app/policies/user_policy.rb +++ b/app/policies/user_policy.rb @@ -1,11 +1,4 @@ class UserPolicy < BasePolicy - include Gitlab::CurrentSettings - - desc "The application is restricted from public visibility" - condition(:restricted_public_level, scope: :global) do - current_application_settings.restricted_visibility_levels.include?(Gitlab::VisibilityLevel::PUBLIC) - end - desc "The current user is the user in question" condition(:user_is_self, score: 0) { @subject == @user } diff --git a/app/presenters/merge_request_presenter.rb b/app/presenters/merge_request_presenter.rb index 8bf35953d29..6ba1d3165e9 100644 --- a/app/presenters/merge_request_presenter.rb +++ b/app/presenters/merge_request_presenter.rb @@ -20,30 +20,25 @@ class MergeRequestPresenter < Gitlab::View::Presenter::Delegated def cancel_merge_when_pipeline_succeeds_path if can_cancel_merge_when_pipeline_succeeds?(current_user) - cancel_merge_when_pipeline_succeeds_namespace_project_merge_request_path( - project.namespace, - project, - merge_request) + cancel_merge_when_pipeline_succeeds_project_merge_request_path(project, merge_request) end end def create_issue_to_resolve_discussions_path if can?(current_user, :create_issue, project) && project.issues_enabled? - new_namespace_project_issue_path(project.namespace, - project, - merge_request_to_resolve_discussions_of: iid) + new_project_issue_path(project, merge_request_to_resolve_discussions_of: iid) end end def remove_wip_path if can?(current_user, :update_merge_request, merge_request.project) - remove_wip_namespace_project_merge_request_path(project.namespace, project, merge_request) + remove_wip_project_merge_request_path(project, merge_request) end end def merge_path if can_be_merged_by?(current_user) - merge_namespace_project_merge_request_path(project.namespace, project, merge_request) + merge_project_merge_request_path(project, merge_request) end end @@ -55,7 +50,7 @@ class MergeRequestPresenter < Gitlab::View::Presenter::Delegated notice_now: edit_in_new_fork_notice_now } - namespace_project_forks_path(merge_request.project.namespace, merge_request.project, + project_forks_path(merge_request.project, namespace_key: current_user.namespace.id, continue: continue_params) end @@ -69,7 +64,7 @@ class MergeRequestPresenter < Gitlab::View::Presenter::Delegated notice_now: edit_in_new_fork_notice_now } - namespace_project_forks_path(project.namespace, project, + project_forks_path(project, namespace_key: current_user.namespace.id, continue: continue_params) end @@ -77,19 +72,19 @@ class MergeRequestPresenter < Gitlab::View::Presenter::Delegated def conflict_resolution_path if conflicts.can_be_resolved_in_ui? && conflicts.can_be_resolved_by?(current_user) - conflicts_namespace_project_merge_request_path(project.namespace, project, merge_request) + conflicts_project_merge_request_path(project, merge_request) end end def target_branch_commits_path if target_branch_exists? - namespace_project_commits_path(project.namespace, project, target_branch) + project_commits_path(project, target_branch) end end def source_branch_path if source_branch_exists? - namespace_project_branch_path(source_project.namespace, source_project, source_branch) + project_branch_path(source_project, source_branch) end end @@ -99,7 +94,7 @@ class MergeRequestPresenter < Gitlab::View::Presenter::Delegated if source_branch_exists? namespace = link_to(namespace, project_path(source_project)) - branch = link_to(branch, namespace_project_commits_path(source_project.namespace, source_project, source_branch)) + branch = link_to(branch, project_commits_path(source_project, source_branch)) end if for_fork? @@ -136,7 +131,7 @@ class MergeRequestPresenter < Gitlab::View::Presenter::Delegated merge_request: merge_request, closes_issues: closing_issues ).assignable_issues - path = assign_related_issues_namespace_project_merge_request_path(project.namespace, project, merge_request) + path = assign_related_issues_project_merge_request_path(project, merge_request) if issues.present? pluralize_this_issue = issues.count > 1 ? "these issues" : "this issue" link_to "Assign yourself to #{pluralize_this_issue}", path, method: :post diff --git a/app/serializers/build_action_entity.rb b/app/serializers/build_action_entity.rb index 301b718d060..f2d76a8ad81 100644 --- a/app/serializers/build_action_entity.rb +++ b/app/serializers/build_action_entity.rb @@ -6,10 +6,7 @@ class BuildActionEntity < Grape::Entity end expose :path do |build| - play_namespace_project_job_path( - build.project.namespace, - build.project, - build) + play_project_job_path(build.project, build) end expose :playable?, as: :playable diff --git a/app/serializers/build_artifact_entity.rb b/app/serializers/build_artifact_entity.rb index cb55c98f7c6..6e0e33bc09b 100644 --- a/app/serializers/build_artifact_entity.rb +++ b/app/serializers/build_artifact_entity.rb @@ -9,24 +9,15 @@ class BuildArtifactEntity < Grape::Entity expose :artifacts_expire_at, as: :expire_at expose :path do |job| - download_namespace_project_job_artifacts_path( - project.namespace, - project, - job) + download_project_job_artifacts_path(project, job) end expose :keep_path, if: -> (*) { job.has_expiring_artifacts? } do |job| - keep_namespace_project_job_artifacts_path( - project.namespace, - project, - job) + keep_project_job_artifacts_path(project, job) end expose :browse_path do |job| - browse_namespace_project_job_artifacts_path( - project.namespace, - project, - job) + browse_project_job_artifacts_path(project, job) end private diff --git a/app/serializers/build_details_entity.rb b/app/serializers/build_details_entity.rb index eeb5399aa8b..20f9938f038 100644 --- a/app/serializers/build_details_entity.rb +++ b/app/serializers/build_details_entity.rb @@ -7,7 +7,7 @@ class BuildDetailsEntity < JobEntity expose :erased_by, if: -> (*) { build.erased? }, using: UserEntity expose :erase_path, if: -> (*) { build.erasable? && can?(current_user, :update_build, project) } do |build| - erase_namespace_project_job_path(project.namespace, project, build) + erase_project_job_path(project, build) end expose :merge_request, if: -> (*) { can?(current_user, :read_merge_request, build.merge_request) } do @@ -16,23 +16,23 @@ class BuildDetailsEntity < JobEntity end expose :path do |build| - namespace_project_merge_request_path(project.namespace, project, build.merge_request) + project_merge_request_path(project, build.merge_request) end end expose :new_issue_path, if: -> (*) { can?(request.current_user, :create_issue, project) && build.failed? } do |build| - new_namespace_project_issue_path(project.namespace, project, issue: build_failed_issue_options) + new_project_issue_path(project, issue: build_failed_issue_options) end expose :raw_path do |build| - raw_namespace_project_job_path(project.namespace, project, build) + raw_project_job_path(project, build) end private def build_failed_issue_options { title: "Build Failed ##{build.id}", - description: namespace_project_job_path(project.namespace, project, build) } + description: project_job_path(project, build) } end def current_user diff --git a/app/serializers/commit_entity.rb b/app/serializers/commit_entity.rb index 31763955f97..e4e9d8ef90a 100644 --- a/app/serializers/commit_entity.rb +++ b/app/serializers/commit_entity.rb @@ -8,16 +8,10 @@ class CommitEntity < API::Entities::RepoCommit end expose :commit_url do |commit| - namespace_project_commit_url( - request.project.namespace, - request.project, - commit) + project_commit_url(request.project, commit) end expose :commit_path do |commit| - namespace_project_commit_path( - request.project.namespace, - request.project, - commit) + project_commit_path(request.project, commit) end end diff --git a/app/serializers/deployment_entity.rb b/app/serializers/deployment_entity.rb index e493c9162fd..241c689bccd 100644 --- a/app/serializers/deployment_entity.rb +++ b/app/serializers/deployment_entity.rb @@ -11,10 +11,7 @@ class DeploymentEntity < Grape::Entity end expose :ref_path do |deployment| - namespace_project_tree_path( - deployment.project.namespace, - deployment.project, - id: deployment.ref) + project_tree_path(deployment.project, id: deployment.ref) end end diff --git a/app/serializers/environment_entity.rb b/app/serializers/environment_entity.rb index 4e8a3c67b21..dcaccc3007d 100644 --- a/app/serializers/environment_entity.rb +++ b/app/serializers/environment_entity.rb @@ -10,32 +10,20 @@ class EnvironmentEntity < Grape::Entity expose :stop_action? expose :metrics_path, if: -> (environment, _) { environment.has_metrics? } do |environment| - metrics_namespace_project_environment_path( - environment.project.namespace, - environment.project, - environment) + metrics_project_environment_path(environment.project, environment) end expose :environment_path do |environment| - namespace_project_environment_path( - environment.project.namespace, - environment.project, - environment) + project_environment_path(environment.project, environment) end expose :stop_path do |environment| - stop_namespace_project_environment_path( - environment.project.namespace, - environment.project, - environment) + stop_project_environment_path(environment.project, environment) end expose :terminal_path, if: ->(environment, _) { environment.has_terminals? } do |environment| can?(request.current_user, :admin_environment, environment.project) && - terminal_namespace_project_environment_path( - environment.project.namespace, - environment.project, - environment) + terminal_project_environment_path(environment.project, environment) end expose :created_at, :updated_at diff --git a/app/serializers/issue_entity.rb b/app/serializers/issue_entity.rb index 35df95549b7..c189a4992da 100644 --- a/app/serializers/issue_entity.rb +++ b/app/serializers/issue_entity.rb @@ -11,6 +11,6 @@ class IssueEntity < IssuableEntity expose :labels, using: LabelEntity expose :web_url do |issue| - namespace_project_issue_path(issue.project.namespace, issue.project, issue) + project_issue_path(issue.project, issue) end end diff --git a/app/serializers/merge_request_entity.rb b/app/serializers/merge_request_entity.rb index 7bb981041cc..7ec2dbd0efe 100644 --- a/app/serializers/merge_request_entity.rb +++ b/app/serializers/merge_request_entity.rb @@ -99,9 +99,7 @@ class MergeRequestEntity < IssuableEntity expose :new_blob_path do |merge_request| if can?(current_user, :push_code, merge_request.project) - namespace_project_new_blob_path(merge_request.project.namespace, - merge_request.project, - merge_request.source_branch) + project_new_blob_path(merge_request.project, merge_request.source_branch) end end @@ -134,30 +132,19 @@ class MergeRequestEntity < IssuableEntity end expose :email_patches_path do |merge_request| - namespace_project_merge_request_path(merge_request.project.namespace, - merge_request.project, - merge_request, - format: :patch) + project_merge_request_path(merge_request.project, merge_request, format: :patch) end expose :plain_diff_path do |merge_request| - namespace_project_merge_request_path(merge_request.project.namespace, - merge_request.project, - merge_request, - format: :diff) + project_merge_request_path(merge_request.project, merge_request, format: :diff) end expose :status_path do |merge_request| - namespace_project_merge_request_path(merge_request.target_project.namespace, - merge_request.target_project, - merge_request, - format: :json) + project_merge_request_path(merge_request.target_project, merge_request, format: :json) end expose :ci_environments_status_path do |merge_request| - ci_environments_status_namespace_project_merge_request_path(merge_request.project.namespace, - merge_request.project, - merge_request) + ci_environments_status_project_merge_request_path(merge_request.project, merge_request) end expose :merge_commit_message_with_description do |merge_request| @@ -173,9 +160,7 @@ class MergeRequestEntity < IssuableEntity end expose :commit_change_content_path do |merge_request| - commit_change_content_namespace_project_merge_request_path(merge_request.project.namespace, - merge_request.project, - merge_request) + commit_change_content_project_merge_request_path(merge_request.project, merge_request) end private diff --git a/app/serializers/pipeline_entity.rb b/app/serializers/pipeline_entity.rb index 6d1fd9d459f..c4f000b0ca3 100644 --- a/app/serializers/pipeline_entity.rb +++ b/app/serializers/pipeline_entity.rb @@ -10,10 +10,7 @@ class PipelineEntity < Grape::Entity expose :created_at, :updated_at expose :path do |pipeline| - namespace_project_pipeline_path( - pipeline.project.namespace, - pipeline.project, - pipeline) + project_pipeline_path(pipeline.project, pipeline) end expose :flags do @@ -48,15 +45,11 @@ class PipelineEntity < Grape::Entity expose :commit, using: CommitEntity expose :retry_path, if: -> (*) { can_retry? } do |pipeline| - retry_namespace_project_pipeline_path(pipeline.project.namespace, - pipeline.project, - pipeline.id) + retry_project_pipeline_path(pipeline.project, pipeline) end expose :cancel_path, if: -> (*) { can_cancel? } do |pipeline| - cancel_namespace_project_pipeline_path(pipeline.project.namespace, - pipeline.project, - pipeline.id) + cancel_project_pipeline_path(pipeline.project, pipeline) end expose :yaml_errors, if: -> (pipeline, _) { pipeline.has_yaml_errors? } diff --git a/app/serializers/project_entity.rb b/app/serializers/project_entity.rb index a471a7e6a88..dc283ba3e7a 100644 --- a/app/serializers/project_entity.rb +++ b/app/serializers/project_entity.rb @@ -5,7 +5,7 @@ class ProjectEntity < Grape::Entity expose :name expose :full_path do |project| - namespace_project_path(project.namespace, project) + project_path(project) end expose :full_name do |project| diff --git a/app/serializers/runner_entity.rb b/app/serializers/runner_entity.rb index ed7dacc2dbd..e9999a36d8a 100644 --- a/app/serializers/runner_entity.rb +++ b/app/serializers/runner_entity.rb @@ -5,7 +5,7 @@ class RunnerEntity < Grape::Entity expose :edit_path, if: -> (*) { can?(request.current_user, :admin_build, project) && runner.specific? } do |runner| - edit_namespace_project_runner_path(project.namespace, project, runner) + edit_project_runner_path(project, runner) end private diff --git a/app/serializers/stage_entity.rb b/app/serializers/stage_entity.rb index cee0089056f..4523b15152e 100644 --- a/app/serializers/stage_entity.rb +++ b/app/serializers/stage_entity.rb @@ -14,16 +14,14 @@ class StageEntity < Grape::Entity expose :detailed_status, as: :status, with: StatusEntity expose :path do |stage| - namespace_project_pipeline_path( - stage.pipeline.project.namespace, + project_pipeline_path( stage.pipeline.project, stage.pipeline, anchor: stage.name) end expose :dropdown_path do |stage| - stage_namespace_project_pipeline_path( - stage.pipeline.project.namespace, + stage_project_pipeline_path( stage.pipeline.project, stage.pipeline, stage: stage.name, diff --git a/app/services/access_token_validation_service.rb b/app/services/access_token_validation_service.rb index b2a543daa00..9c00ea789ec 100644 --- a/app/services/access_token_validation_service.rb +++ b/app/services/access_token_validation_service.rb @@ -5,10 +5,11 @@ class AccessTokenValidationService REVOKED = :revoked INSUFFICIENT_SCOPE = :insufficient_scope - attr_reader :token + attr_reader :token, :request - def initialize(token) + def initialize(token, request: nil) @token = token + @request = request end def validate(scopes: []) @@ -27,12 +28,23 @@ class AccessTokenValidationService end # True if the token's scope contains any of the passed scopes. - def include_any_scope?(scopes) - if scopes.blank? + def include_any_scope?(required_scopes) + if required_scopes.blank? true else - # Check whether the token is allowed access to any of the required scopes. - Set.new(scopes).intersection(Set.new(token.scopes)).present? + # We're comparing each required_scope against all token scopes, which would + # take quadratic time. This consideration is irrelevant here because of the + # small number of records involved. + # https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/12300/#note_33689006 + token_scopes = token.scopes.map(&:to_sym) + + required_scopes.any? do |scope| + if scope.respond_to?(:sufficient?) + scope.sufficient?(token_scopes, request) + else + API::Scope.new(scope).sufficient?(token_scopes, request) + end + end end end end diff --git a/app/services/ci/create_pipeline_service.rb b/app/services/ci/create_pipeline_service.rb index 942145c4a8c..4f35255fb53 100644 --- a/app/services/ci/create_pipeline_service.rb +++ b/app/services/ci/create_pipeline_service.rb @@ -33,7 +33,7 @@ module Ci unless pipeline.config_processor unless pipeline.ci_yaml_file - return error('Missing .gitlab-ci.yml file') + return error("Missing #{pipeline.ci_yaml_file_path} file") end return error(pipeline.yaml_errors, save: save_on_errors) end diff --git a/app/services/delete_merged_branches_service.rb b/app/services/delete_merged_branches_service.rb index 3b611588466..5c9e2a16c71 100644 --- a/app/services/delete_merged_branches_service.rb +++ b/app/services/delete_merged_branches_service.rb @@ -10,6 +10,8 @@ class DeleteMergedBranchesService < BaseService branches = branches.select { |branch| project.repository.merged_to_root_ref?(branch) } # Prevent deletion of branches relevant to open merge requests branches -= merge_request_branch_names + # Prevent deletion of protected branches + branches -= project.protected_branches.pluck(:name) branches.each do |branch| DeleteBranchService.new(project, current_user).execute(branch) diff --git a/app/services/merge_requests/get_urls_service.rb b/app/services/merge_requests/get_urls_service.rb index 5dd40e07c0d..668a1741736 100644 --- a/app/services/merge_requests/get_urls_service.rb +++ b/app/services/merge_requests/get_urls_service.rb @@ -49,13 +49,13 @@ module MergeRequests def url_for_new_merge_request(branch_name) merge_request_params = { source_branch: branch_name } - url = Gitlab::Routing.url_helpers.namespace_project_new_merge_request_url(project.namespace, project, merge_request: merge_request_params) + url = Gitlab::Routing.url_helpers.project_new_merge_request_url(project, merge_request: merge_request_params) { branch_name: branch_name, url: url, new_merge_request: true } end def url_for_existing_merge_request(merge_request) target_project = merge_request.target_project - url = Gitlab::Routing.url_helpers.namespace_project_merge_request_url(target_project.namespace, target_project, merge_request) + url = Gitlab::Routing.url_helpers.project_merge_request_url(target_project, merge_request) { branch_name: merge_request.source_branch, url: url, new_merge_request: false } end end diff --git a/app/services/merge_requests/merge_service.rb b/app/services/merge_requests/merge_service.rb index b247cb89e5e..bc846e07f24 100644 --- a/app/services/merge_requests/merge_service.rb +++ b/app/services/merge_requests/merge_service.rb @@ -61,8 +61,12 @@ module MergeRequests MergeRequests::PostMergeService.new(project, current_user).execute(merge_request) if params[:should_remove_source_branch].present? || @merge_request.force_remove_source_branch? - DeleteBranchService.new(@merge_request.source_project, branch_deletion_user) - .execute(merge_request.source_branch) + # Verify again that the source branch can be removed, since branch may be protected, + # or the source branch may have been updated. + if @merge_request.can_remove_source_branch?(branch_deletion_user) + DeleteBranchService.new(@merge_request.source_project, branch_deletion_user) + .execute(merge_request.source_branch) + end end end diff --git a/app/services/projects/transfer_service.rb b/app/services/projects/transfer_service.rb index fd701e33524..4bb98e5cb4e 100644 --- a/app/services/projects/transfer_service.rb +++ b/app/services/projects/transfer_service.rb @@ -78,6 +78,7 @@ module Projects Gitlab::PagesTransfer.new.move_project(project.path, @old_namespace.full_path, @new_namespace.full_path) project.old_path_with_namespace = @old_path + project.expires_full_path_cache execute_system_hooks end diff --git a/app/services/quick_actions/interpret_service.rb b/app/services/quick_actions/interpret_service.rb index 6816b137361..e4dfe87e614 100644 --- a/app/services/quick_actions/interpret_service.rb +++ b/app/services/quick_actions/interpret_service.rb @@ -92,9 +92,12 @@ module QuickActions desc 'Assign' explanation do |users| - "Assigns #{users.first.to_reference}." if users.any? + users = issuable.allows_multiple_assignees? ? users : users.take(1) + "Assigns #{users.map(&:to_reference).to_sentence}." + end + params do + issuable.allows_multiple_assignees? ? '@user1 @user2' : '@user' end - params '@user' condition do current_user.can?(:"admin_#{issuable.to_ability_name}", project) end @@ -104,28 +107,69 @@ module QuickActions command :assign do |users| next if users.empty? - if issuable.is_a?(Issue) - @updates[:assignee_ids] = [users.last.id] + @updates[:assignee_ids] = + if issuable.allows_multiple_assignees? + issuable.assignees.pluck(:id) + users.map(&:id) + else + [users.last.id] + end + end + + desc do + if issuable.allows_multiple_assignees? + 'Remove all or specific assignee(s)' else - @updates[:assignee_id] = users.last.id + 'Remove assignee' end end - - desc 'Remove assignee' explanation do - "Removes assignee #{issuable.assignees.first.to_reference}." + "Removes #{'assignee'.pluralize(issuable.assignees.size)} #{issuable.assignees.map(&:to_reference).to_sentence}." + end + params do + issuable.allows_multiple_assignees? ? '@user1 @user2' : '' end condition do issuable.persisted? && issuable.assignees.any? && current_user.can?(:"admin_#{issuable.to_ability_name}", project) end - command :unassign do - if issuable.is_a?(Issue) - @updates[:assignee_ids] = [] - else - @updates[:assignee_id] = nil - end + parse_params do |unassign_param| + # When multiple users are assigned, all will be unassigned if multiple assignees are no longer allowed + extract_users(unassign_param) if issuable.allows_multiple_assignees? + end + command :unassign do |users = nil| + @updates[:assignee_ids] = + if users&.any? + issuable.assignees.pluck(:id) - users.map(&:id) + else + [] + end + end + + desc do + "Change assignee#{'(s)' if issuable.allows_multiple_assignees?}" + end + explanation do |users| + users = issuable.allows_multiple_assignees? ? users : users.take(1) + "Change #{'assignee'.pluralize(users.size)} to #{users.map(&:to_reference).to_sentence}." + end + params do + issuable.allows_multiple_assignees? ? '@user1 @user2' : '@user' + end + condition do + issuable.persisted? && + current_user.can?(:"admin_#{issuable.to_ability_name}", project) + end + parse_params do |assignee_param| + extract_users(assignee_param) + end + command :reassign do |users| + @updates[:assignee_ids] = + if issuable.allows_multiple_assignees? + users.map(&:id) + else + [users.last.id] + end end desc 'Set milestone' diff --git a/app/services/system_note_service.rb b/app/services/system_note_service.rb index 0837c07e6aa..da0f21d449a 100644 --- a/app/services/system_note_service.rb +++ b/app/services/system_note_service.rb @@ -282,7 +282,7 @@ module SystemNoteService body = "changed this line in" if version_params = merge_request.version_params_for(diff_refs) line_code = change_position.line_code(project.repository) - url = url_helpers.diffs_namespace_project_merge_request_url(project.namespace, project, merge_request, version_params.merge(anchor: line_code)) + url = url_helpers.diffs_project_merge_request_url(project, merge_request, version_params.merge(anchor: line_code)) body << " [version #{version_index} of the diff](#{url})" else @@ -413,7 +413,7 @@ module SystemNoteService # # "created branch `201-issue-branch-button`" def new_issue_branch(issue, project, author, branch) - link = url_helpers.namespace_project_compare_url(project.namespace, project, from: project.default_branch, to: branch) + link = url_helpers.project_compare_url(project, from: project.default_branch, to: branch) body = "created branch [`#{branch}`](#{link})" @@ -630,10 +630,9 @@ module SystemNoteService def diff_comparison_url(merge_request, project, oldrev) diff_id = merge_request.merge_request_diff.id - url_helpers.diffs_namespace_project_merge_request_url( - project.namespace, + url_helpers.diffs_project_merge_request_url( project, - merge_request.iid, + merge_request, diff_id: diff_id, start_sha: oldrev ) diff --git a/app/views/admin/application_settings/_form.html.haml b/app/views/admin/application_settings/_form.html.haml index b21d5665970..5f5eeb8b9a9 100644 --- a/app/views/admin/application_settings/_form.html.haml +++ b/app/views/admin/application_settings/_form.html.haml @@ -22,7 +22,9 @@ .form-group = f.label :restricted_visibility_levels, class: 'control-label col-sm-2' .col-sm-10 - - restricted_level_checkboxes('restricted-visibility-help').each do |level| + - checkbox_name = 'application_setting[restricted_visibility_levels][]' + = hidden_field_tag(checkbox_name) + - restricted_level_checkboxes('restricted-visibility-help', checkbox_name).each do |level| .checkbox = level %span.help-block#restricted-visibility-help diff --git a/app/views/admin/dashboard/index.html.haml b/app/views/admin/dashboard/index.html.haml index 3c9f932a225..128b5dc01ab 100644 --- a/app/views/admin/dashboard/index.html.haml +++ b/app/views/admin/dashboard/index.html.haml @@ -5,182 +5,182 @@ .admin-dashboard.prepend-top-default .row .col-md-4 - %h4 Statistics - %hr - %p - Forks - %span.light.pull-right - = number_with_delimiter(ForkedProjectLink.count) - %p - Issues - %span.light.pull-right - = number_with_delimiter(Issue.count) - %p - Merge Requests - %span.light.pull-right - = number_with_delimiter(MergeRequest.count) - %p - Notes - %span.light.pull-right - = number_with_delimiter(Note.count) - %p - Snippets - %span.light.pull-right - = number_with_delimiter(Snippet.count) - %p - SSH Keys - %span.light.pull-right - = number_with_delimiter(Key.count) - %p - Milestones - %span.light.pull-right - = number_with_delimiter(Milestone.count) - %p - Active Users - %span.light.pull-right - = number_with_delimiter(User.active.count) + .info-well + .well-segment.admin-well + %h4 Statistics + %p + Forks + %span.light.pull-right + = number_with_delimiter(ForkedProjectLink.count) + %p + Issues + %span.light.pull-right + = number_with_delimiter(Issue.count) + %p + Merge Requests + %span.light.pull-right + = number_with_delimiter(MergeRequest.count) + %p + Notes + %span.light.pull-right + = number_with_delimiter(Note.count) + %p + Snippets + %span.light.pull-right + = number_with_delimiter(Snippet.count) + %p + SSH Keys + %span.light.pull-right + = number_with_delimiter(Key.count) + %p + Milestones + %span.light.pull-right + = number_with_delimiter(Milestone.count) + %p + Active Users + %span.light.pull-right + = number_with_delimiter(User.active.count) .col-md-4 - %h4 - Features - %hr - - sign_up = "Sign up" - %p{ "aria-label" => "#{sign_up}: status " + (signup_enabled? ? "on" : "off") } - = sign_up - %span.light.pull-right - = boolean_to_icon signup_enabled? - - ldap = "LDAP" - %p{ "aria-label" => "#{ldap}: status " + (Gitlab.config.ldap.enabled ? "on" : "off") } - = ldap - %span.light.pull-right - = boolean_to_icon Gitlab.config.ldap.enabled - - gravatar = "Gravatar" - %p{ "aria-label" => "#{gravatar}: status " + (gravatar_enabled? ? "on" : "off") } - = gravatar - %span.light.pull-right - = boolean_to_icon gravatar_enabled? - - omniauth = "OmniAuth" - %p{ "aria-label" => "#{omniauth}: status " + (Gitlab.config.omniauth.enabled ? "on" : "off") } - = omniauth - %span.light.pull-right - = boolean_to_icon Gitlab.config.omniauth.enabled - - reply_email = "Reply by email" - %p{ "aria-label" => "#{reply_email}: status " + (Gitlab::IncomingEmail.enabled? ? "on" : "off") } - = reply_email - %span.light.pull-right - = boolean_to_icon Gitlab::IncomingEmail.enabled? - - container_reg = "Container Registry" - %p{ "aria-label" => "#{container_reg}: status " + (Gitlab.config.registry.enabled ? "on" : "off") } - = container_reg - %span.light.pull-right - = boolean_to_icon Gitlab.config.registry.enabled - - gitlab_pages = 'GitLab Pages' - - gitlab_pages_enabled = Gitlab.config.pages.enabled - %p{ "aria-label" => "#{gitlab_pages}: status " + (gitlab_pages_enabled ? "on" : "off") } - = gitlab_pages - %span.light.pull-right - = boolean_to_icon gitlab_pages_enabled - - gitlab_shared_runners = 'Shared Runners' - - gitlab_shared_runners_enabled = Gitlab.config.gitlab_ci.shared_runners_enabled - %p{ "aria-label" => "#{gitlab_shared_runners}: status " + (gitlab_shared_runners_enabled ? "on" : "off") } - = gitlab_shared_runners - %span.light.pull-right - = boolean_to_icon gitlab_shared_runners_enabled - + .info-well + .well-segment.admin-well + %h4 Features + - sign_up = "Sign up" + %p{ "aria-label" => "#{sign_up}: status " + (signup_enabled? ? "on" : "off") } + = sign_up + %span.light.pull-right + = boolean_to_icon signup_enabled? + - ldap = "LDAP" + %p{ "aria-label" => "#{ldap}: status " + (Gitlab.config.ldap.enabled ? "on" : "off") } + = ldap + %span.light.pull-right + = boolean_to_icon Gitlab.config.ldap.enabled + - gravatar = "Gravatar" + %p{ "aria-label" => "#{gravatar}: status " + (gravatar_enabled? ? "on" : "off") } + = gravatar + %span.light.pull-right + = boolean_to_icon gravatar_enabled? + - omniauth = "OmniAuth" + %p{ "aria-label" => "#{omniauth}: status " + (Gitlab.config.omniauth.enabled ? "on" : "off") } + = omniauth + %span.light.pull-right + = boolean_to_icon Gitlab.config.omniauth.enabled + - reply_email = "Reply by email" + %p{ "aria-label" => "#{reply_email}: status " + (Gitlab::IncomingEmail.enabled? ? "on" : "off") } + = reply_email + %span.light.pull-right + = boolean_to_icon Gitlab::IncomingEmail.enabled? + - container_reg = "Container Registry" + %p{ "aria-label" => "#{container_reg}: status " + (Gitlab.config.registry.enabled ? "on" : "off") } + = container_reg + %span.light.pull-right + = boolean_to_icon Gitlab.config.registry.enabled + - gitlab_pages = 'GitLab Pages' + - gitlab_pages_enabled = Gitlab.config.pages.enabled + %p{ "aria-label" => "#{gitlab_pages}: status " + (gitlab_pages_enabled ? "on" : "off") } + = gitlab_pages + %span.light.pull-right + = boolean_to_icon gitlab_pages_enabled + - gitlab_shared_runners = 'Shared Runners' + - gitlab_shared_runners_enabled = Gitlab.config.gitlab_ci.shared_runners_enabled + %p{ "aria-label" => "#{gitlab_shared_runners}: status " + (gitlab_shared_runners_enabled ? "on" : "off") } + = gitlab_shared_runners + %span.light.pull-right + = boolean_to_icon gitlab_shared_runners_enabled .col-md-4 - %h4 - Components - - if current_application_settings.version_check_enabled - .pull-right - = version_status_badge - - %hr - %p - GitLab - %span.pull-right - = Gitlab::VERSION - %p - GitLab Shell - %span.pull-right - = Gitlab::Shell.new.version - %p - GitLab Workhorse - %span.pull-right - = gitlab_workhorse_version - %p - GitLab API - %span.pull-right - = API::API::version - %p - Git - %span.pull-right - = Gitlab::Git.version - %p - Ruby - %span.pull-right - #{RUBY_VERSION}p#{RUBY_PATCHLEVEL} - - %p - Rails - %span.pull-right - #{Rails::VERSION::STRING} - - %p - = Gitlab::Database.adapter_name - %span.pull-right - = Gitlab::Database.version - %hr + .info-well + .well-segment.admin-well + %h4 + Components + - if current_application_settings.version_check_enabled + .pull-right + = version_status_badge + %p + GitLab + %span.pull-right + = Gitlab::VERSION + %p + GitLab Shell + %span.pull-right + = Gitlab::Shell.new.version + %p + GitLab Workhorse + %span.pull-right + = gitlab_workhorse_version + %p + GitLab API + %span.pull-right + = API::API::version + %p + Git + %span.pull-right + = Gitlab::Git.version + %p + Ruby + %span.pull-right + #{RUBY_VERSION}p#{RUBY_PATCHLEVEL} + %p + Rails + %span.pull-right + #{Rails::VERSION::STRING} + %p + = Gitlab::Database.adapter_name + %span.pull-right + = Gitlab::Database.version .row .col-sm-4 - .light-well.well-centered - %h4 Projects - .data + .info-well.dark-well + .well-segment.well-centered = link_to admin_projects_path do - %h1= number_with_delimiter(Project.cached_count) + %h3.text-center + Projects: + = number_with_delimiter(Project.cached_count) %hr = link_to('New project', new_project_path, class: "btn btn-new") .col-sm-4 - .light-well.well-centered - %h4 Users - .data + .info-well.dark-well + .well-segment.well-centered = link_to admin_users_path do - %h1= number_with_delimiter(User.count) + %h3.text-center + Users: + = number_with_delimiter(User.count) %hr = link_to 'New user', new_admin_user_path, class: "btn btn-new" .col-sm-4 - .light-well.well-centered - %h4 Groups - .data + .info-well.dark-well + .well-segment.well-centered = link_to admin_groups_path do - %h1= number_with_delimiter(Group.count) + %h3.text-center + Groups + = number_with_delimiter(Group.count) %hr = link_to 'New group', new_admin_group_path, class: "btn btn-new" - - .row.prepend-top-10 + .row .col-md-4 - %h4 Latest projects - %hr - - @projects.each do |project| - %p - = link_to project.name_with_namespace, [:admin, project.namespace.becomes(Namespace), project], class: 'str-truncated-60' - %span.light.pull-right - #{time_ago_with_tooltip(project.created_at)} - + .info-well + .well-segment.admin-well + %h4 Latest projects + - @projects.each do |project| + %p + = link_to project.name_with_namespace, [:admin, project.namespace.becomes(Namespace), project], class: 'str-truncated-60' + %span.light.pull-right + #{time_ago_with_tooltip(project.created_at)} .col-md-4 - %h4 Latest users - %hr - - @users.each do |user| - %p - = link_to [:admin, user], class: 'str-truncated-60' do - = user.name - %span.light.pull-right - #{time_ago_with_tooltip(user.created_at)} - + .info-well + .well-segment.admin-well + %h4 Latest users + - @users.each do |user| + %p + = link_to [:admin, user], class: 'str-truncated-60' do + = user.name + %span.light.pull-right + #{time_ago_with_tooltip(user.created_at)} .col-md-4 - %h4 Latest groups - %hr - - @groups.each do |group| - %p - = link_to [:admin, group], class: 'str-truncated-60' do - = group.full_name - %span.light.pull-right - #{time_ago_with_tooltip(group.created_at)} + .info-well + .well-segment.admin-well + %h4 Latest groups + - @groups.each do |group| + %p + = link_to [:admin, group], class: 'str-truncated-60' do + = group.full_name + %span.light.pull-right + #{time_ago_with_tooltip(group.created_at)} diff --git a/app/views/admin/projects/_projects.html.haml b/app/views/admin/projects/_projects.html.haml index 596f367a00d..c69c2761189 100644 --- a/app/views/admin/projects/_projects.html.haml +++ b/app/views/admin/projects/_projects.html.haml @@ -4,7 +4,7 @@ - @projects.each_with_index do |project| %li.project-row{ class: ('no-description' if project.description.blank?) } .controls - = link_to 'Edit', edit_namespace_project_path(project.namespace, project), id: "edit_#{dom_id(project)}", class: "btn" + = link_to 'Edit', edit_project_path(project), id: "edit_#{dom_id(project)}", class: "btn" = link_to 'Delete', [project.namespace.becomes(Namespace), project], data: { confirm: remove_project_message(project) }, method: :delete, class: "btn btn-remove" .stats %span.badge diff --git a/app/views/admin/projects/show.html.haml b/app/views/admin/projects/show.html.haml index 08a8f627113..fb9057b2db5 100644 --- a/app/views/admin/projects/show.html.haml +++ b/app/views/admin/projects/show.html.haml @@ -108,7 +108,7 @@ .panel-heading Transfer project .panel-body - = form_for @project, url: transfer_admin_namespace_project_path(@project.namespace, @project), method: :put, html: { class: 'form-horizontal' } do |f| + = form_for @project, url: transfer_admin_project_path(@project), method: :put, html: { class: 'form-horizontal' } do |f| .form-group = f.label :new_namespace_id, "Namespace", class: 'control-label' .col-sm-10 @@ -128,7 +128,7 @@ .panel-heading Repository check .panel-body - = form_for @project, url: repository_check_admin_namespace_project_path(@project.namespace, @project), method: :post do |f| + = form_for @project, url: repository_check_admin_project_path(@project), method: :post do |f| .form-group - if @project.last_repository_check_at.nil? This repository has never been checked. diff --git a/app/views/admin/runners/_runner.html.haml b/app/views/admin/runners/_runner.html.haml index d4d166ab7b6..140688b52d3 100644 --- a/app/views/admin/runners/_runner.html.haml +++ b/app/views/admin/runners/_runner.html.haml @@ -32,13 +32,16 @@ #{time_ago_in_words(runner.contacted_at)} ago - else Never - %td - .pull-right - = link_to 'Edit', admin_runner_path(runner), class: 'btn btn-sm' + %td.admin-runner-btn-group-cell + .pull-right.btn-group + = link_to admin_runner_path(runner), class: 'btn btn-sm btn-default has-tooltip', title: 'Edit', ref: 'tooltip', aria: { label: 'Edit' }, data: { placement: 'top', container: 'body'} do + = icon('pencil') - if runner.active? - = link_to 'Pause', [:pause, :admin, runner], data: { confirm: "Are you sure?" }, method: :get, class: 'btn btn-danger btn-sm' + = link_to [:pause, :admin, runner], method: :get, class: 'btn btn-sm btn-default has-tooltip', title: 'Pause', ref: 'tooltip', aria: { label: 'Pause' }, data: { placement: 'top', container: 'body', confirm: "Are you sure?" } do + = icon('pause') - else - = link_to 'Resume', [:resume, :admin, runner], method: :get, class: 'btn btn-success btn-sm' - = link_to 'Remove', [:admin, runner], data: { confirm: "Are you sure?" }, method: :delete, class: 'btn btn-danger btn-sm' - + = link_to [:resume, :admin, runner], method: :get, class: 'btn btn-default btn-sm has-tooltip', title: 'Resume', ref: 'tooltip', aria: { label: 'Resume' }, data: { placement: 'top', container: 'body'} do + = icon('play') + = link_to [:admin, runner], method: :delete, class: 'btn btn-danger btn-sm has-tooltip', title: 'Remove', ref: 'tooltip', aria: { label: 'Remove' }, data: { placement: 'top', container: 'body', confirm: "Are you sure?" } do + = icon('remove') diff --git a/app/views/admin/runners/show.html.haml b/app/views/admin/runners/show.html.haml index 801430e525e..df2bf27be9d 100644 --- a/app/views/admin/runners/show.html.haml +++ b/app/views/admin/runners/show.html.haml @@ -85,7 +85,7 @@ %tr.build %td.id - if project - = link_to namespace_project_job_path(project.namespace, project, build) do + = link_to project_job_path(project, build) do %strong ##{build.id} - else %strong ##{build.id} diff --git a/app/views/admin/users/projects.html.haml b/app/views/admin/users/projects.html.haml index 15eaf1c0e67..4a440f3f6d4 100644 --- a/app/views/admin/users/projects.html.haml +++ b/app/views/admin/users/projects.html.haml @@ -33,7 +33,7 @@ - member = project.team.find_member(@user.id) %li.project_member .list-item-name - = link_to admin_namespace_project_path(project.namespace, project), class: dom_class(project) do + = link_to admin_project_path(project), class: dom_class(project) do = project.name_with_namespace - if member @@ -44,5 +44,5 @@ %span.light.vertical-align-middle= member.human_access - if member.respond_to? :project - = link_to namespace_project_project_member_path(project.namespace, project, member), data: { confirm: remove_member_message(member) }, remote: true, method: :delete, class: "btn-xs btn btn-remove prepend-left-10", title: 'Remove user from project' do + = link_to project_project_member_path(project, member), data: { confirm: remove_member_message(member) }, remote: true, method: :delete, class: "btn-xs btn btn-remove prepend-left-10", title: 'Remove user from project' do %i.fa.fa-times diff --git a/app/views/devise/shared/_omniauth_box.html.haml b/app/views/devise/shared/_omniauth_box.html.haml index f92f89e73ff..e80d10dc8f1 100644 --- a/app/views/devise/shared/_omniauth_box.html.haml +++ b/app/views/devise/shared/_omniauth_box.html.haml @@ -6,4 +6,7 @@ - providers.each do |provider| %span.light - has_icon = provider_has_icon?(provider) - = link_to provider_image_tag(provider), omniauth_authorize_path(:user, provider), method: :post, class: (has_icon ? 'oauth-image-link' : 'btn') + = link_to provider_image_tag(provider), omniauth_authorize_path(:user, provider), method: :post, class: 'oauth-login' + (has_icon ? ' oauth-image-link' : ' btn'), id: "oauth-login-#{provider}" + %fieldset + = check_box_tag :remember_me + = label_tag :remember_me, 'Remember Me' diff --git a/app/views/devise/shared/_signup_box.html.haml b/app/views/devise/shared/_signup_box.html.haml index d696577278d..298604dee8c 100644 --- a/app/views/devise/shared/_signup_box.html.haml +++ b/app/views/devise/shared/_signup_box.html.haml @@ -25,7 +25,7 @@ %div - if Gitlab::Recaptcha.enabled? = recaptcha_tags - %div + .submit-container = f.submit "Register", class: "btn-register btn" .clearfix.submit-container %p diff --git a/app/views/discussions/_new_issue_for_all_discussions.html.haml b/app/views/discussions/_new_issue_for_all_discussions.html.haml index ca9e0e8728a..cab346fb514 100644 --- a/app/views/discussions/_new_issue_for_all_discussions.html.haml +++ b/app/views/discussions/_new_issue_for_all_discussions.html.haml @@ -3,4 +3,4 @@ .btn.btn-default.discussion-create-issue-btn.has-tooltip{ title: "Resolve all discussions in new issue", "aria-label" => "Resolve all discussions in a new issue", "data-container" => "body" } - = link_to custom_icon('icon_mr_issue'), new_namespace_project_issue_path(@project.namespace, @project, merge_request_to_resolve_discussions_of: merge_request.iid), title: "Resolve all discussions in new issue", class: 'new-issue-for-discussion' + = link_to custom_icon('icon_mr_issue'), new_project_issue_path(@project, merge_request_to_resolve_discussions_of: merge_request.iid), title: "Resolve all discussions in new issue", class: 'new-issue-for-discussion' diff --git a/app/views/discussions/_new_issue_for_discussion.html.haml b/app/views/discussions/_new_issue_for_discussion.html.haml index df5546a1e32..a9bc317b8f8 100644 --- a/app/views/discussions/_new_issue_for_discussion.html.haml +++ b/app/views/discussions/_new_issue_for_discussion.html.haml @@ -5,4 +5,4 @@ .btn.btn-default.discussion-create-issue-btn.has-tooltip{ title: "Resolve this discussion in a new issue", "aria-label" => "Resolve this discussion in a new issue", "data-container" => "body" } - = link_to custom_icon('icon_mr_issue'), new_namespace_project_issue_path(@project.namespace, @project, merge_request_to_resolve_discussions_of: merge_request.iid, discussion_to_resolve: discussion.id), title: "Resolve this discussion in a new issue", class: 'new-issue-for-discussion' + = link_to custom_icon('icon_mr_issue'), new_project_issue_path(@project, merge_request_to_resolve_discussions_of: merge_request.iid, discussion_to_resolve: discussion.id), title: "Resolve this discussion in a new issue", class: 'new-issue-for-discussion' diff --git a/app/views/events/_commit.html.haml b/app/views/events/_commit.html.haml index 3c64f1be5ff..ad434a64556 100644 --- a/app/views/events/_commit.html.haml +++ b/app/views/events/_commit.html.haml @@ -1,5 +1,5 @@ %li.commit .commit-row-title - = link_to truncate_sha(commit[:id]), namespace_project_commit_path(project.namespace, project, commit[:id]), class: "commit-sha", alt: '', title: truncate_sha(commit[:id]) + = link_to truncate_sha(commit[:id]), project_commit_path(project, commit[:id]), class: "commit-sha", alt: '', title: truncate_sha(commit[:id]) · = markdown event_commit_title(commit[:message]), project: project, pipeline: :single_line, author: event.author diff --git a/app/views/events/_event_push.atom.haml b/app/views/events/_event_push.atom.haml index f8f0bcb7608..9fcacfbbf36 100644 --- a/app/views/events/_event_push.atom.haml +++ b/app/views/events/_event_push.atom.haml @@ -2,7 +2,7 @@ - event.commits.first(15).each do |commit| %p %strong= commit[:author][:name] - = link_to "(##{truncate_sha(commit[:id])})", namespace_project_commit_path(event.project.namespace, event.project, id: commit[:id]) + = link_to "(##{truncate_sha(commit[:id])})", project_commit_path(event.project, id: commit[:id]) %i at = commit[:timestamp].to_time.to_s(:short) diff --git a/app/views/events/event/_push.html.haml b/app/views/events/event/_push.html.haml index 769ac655d0a..54b414cc62a 100644 --- a/app/views/events/event/_push.html.haml +++ b/app/views/events/event/_push.html.haml @@ -6,7 +6,7 @@ %span.author_name= link_to_author event %span.pushed #{event.action_name} #{event.ref_type} %strong - - commits_link = namespace_project_commits_path(project.namespace, project, event.ref_name) + - commits_link = project_commits_path(project, event.ref_name) = link_to_if project.repository.branch_exists?(event.ref_name), event.ref_name, commits_link, class: 'ref-name' = render "events/event_scope", event: event @@ -31,7 +31,7 @@ - from = project.default_branch - from_label = from - = link_to namespace_project_compare_path(project.namespace, project, from: from, to: event.commit_to) do + = link_to project_compare_path(project, from: from, to: event.commit_to) do Compare #{from_label}...#{truncate_sha(event.commit_to)} - if create_mr diff --git a/app/views/groups/edit.html.haml b/app/views/groups/edit.html.haml index 2d32d5299b7..5cb4d05960d 100644 --- a/app/views/groups/edit.html.haml +++ b/app/views/groups/edit.html.haml @@ -46,10 +46,13 @@ .panel.panel-danger .panel-heading Remove group .panel-body - %p - Removing group will cause all child projects and resources to be removed. - %br - %strong Removed group can not be restored! + = form_tag(@group, method: :delete) do + %p + Removing group will cause all child projects and resources to be removed. + %br + %strong Removed group can not be restored! - .form-actions - = link_to 'Remove group', @group, data: {confirm: 'Removed group can not be restored! Are you sure?'}, method: :delete, class: "btn btn-remove" + .form-actions + = button_to 'Remove group', '#', class: "btn btn-remove js-confirm-danger", data: { "confirm-danger-message" => remove_group_message(@group) } + += render 'shared/confirm_modal', phrase: @group.path diff --git a/app/views/groups/projects.html.haml b/app/views/groups/projects.html.haml index 62ad47972b9..7a2e688a114 100644 --- a/app/views/groups/projects.html.haml +++ b/app/views/groups/projects.html.haml @@ -20,8 +20,8 @@ %span.label.label-warning archived %span.badge = storage_counter(project.statistics.storage_size) - = link_to 'Members', namespace_project_project_members_path(project.namespace, project), id: "edit_#{dom_id(project)}", class: "btn btn-sm" - = link_to 'Edit', edit_namespace_project_path(project.namespace, project), id: "edit_#{dom_id(project)}", class: "btn btn-sm" + = link_to 'Members', project_project_members_path(project), id: "edit_#{dom_id(project)}", class: "btn btn-sm" + = link_to 'Edit', edit_project_path(project), id: "edit_#{dom_id(project)}", class: "btn btn-sm" = link_to 'Remove', project, data: { confirm: remove_project_message(project)}, method: :delete, class: "btn btn-sm btn-remove" - if @projects.blank? .nothing-here-block This group has no projects yet diff --git a/app/views/import/base/create.js.haml b/app/views/import/base/create.js.haml index 57e8c3ca1e1..fde671e25a9 100644 --- a/app/views/import/base/create.js.haml +++ b/app/views/import/base/create.js.haml @@ -4,7 +4,7 @@ job.attr("id", "project_#{@project.id}") target_field = job.find(".import-target") target_field.empty() - target_field.append('#{link_to @project.path_with_namespace, namespace_project_path(@project.namespace, @project)}') + target_field.append('#{link_to @project.path_with_namespace, project_path(@project)}') $("table.import-jobs tbody").prepend(job) job.addClass("active").find(".import-actions").html("<i class='fa fa-spinner fa-spin'></i> started") - else diff --git a/app/views/invites/show.html.haml b/app/views/invites/show.html.haml index 882fdf1317d..ad6213b4efd 100644 --- a/app/views/invites/show.html.haml +++ b/app/views/invites/show.html.haml @@ -12,7 +12,7 @@ - project = @member.source project %strong - = link_to project.name_with_namespace, namespace_project_url(project.namespace, project) + = link_to project.name_with_namespace, project_url(project) - when Group - group = @member.source group diff --git a/app/views/issues/_issue.atom.builder b/app/views/issues/_issue.atom.builder index 2ed78bb3b65..0c113c08526 100644 --- a/app/views/issues/_issue.atom.builder +++ b/app/views/issues/_issue.atom.builder @@ -1,6 +1,6 @@ xml.entry do - xml.id namespace_project_issue_url(issue.project.namespace, issue.project, issue) - xml.link href: namespace_project_issue_url(issue.project.namespace, issue.project, issue) + xml.id project_issue_url(issue.project, issue) + xml.link href: project_issue_url(issue.project, issue) xml.title truncate(issue.title, length: 80) xml.updated issue.updated_at.xmlschema xml.media :thumbnail, width: "40", height: "40", url: image_url(avatar_icon(issue.author_email)) diff --git a/app/views/layouts/_init_auto_complete.html.haml b/app/views/layouts/_init_auto_complete.html.haml index 6caaba240bb..4bb0dfc73fd 100644 --- a/app/views/layouts/_init_auto_complete.html.haml +++ b/app/views/layouts/_init_auto_complete.html.haml @@ -5,10 +5,10 @@ :javascript gl.GfmAutoComplete = gl.GfmAutoComplete || {}; gl.GfmAutoComplete.dataSources = { - members: "#{members_namespace_project_autocomplete_sources_path(project.namespace, project, type: noteable_type, type_id: params[:id])}", - issues: "#{issues_namespace_project_autocomplete_sources_path(project.namespace, project)}", - mergeRequests: "#{merge_requests_namespace_project_autocomplete_sources_path(project.namespace, project)}", - labels: "#{labels_namespace_project_autocomplete_sources_path(project.namespace, project)}", - milestones: "#{milestones_namespace_project_autocomplete_sources_path(project.namespace, project)}", - commands: "#{commands_namespace_project_autocomplete_sources_path(project.namespace, project, type: noteable_type, type_id: params[:id])}" + members: "#{members_project_autocomplete_sources_path(project, type: noteable_type, type_id: params[:id])}", + issues: "#{issues_project_autocomplete_sources_path(project)}", + mergeRequests: "#{merge_requests_project_autocomplete_sources_path(project)}", + labels: "#{labels_project_autocomplete_sources_path(project)}", + milestones: "#{milestones_project_autocomplete_sources_path(project)}", + commands: "#{commands_project_autocomplete_sources_path(project, type: noteable_type, type_id: params[:id])}" }; diff --git a/app/views/layouts/_search.html.haml b/app/views/layouts/_search.html.haml index b689991bb6d..59f16b47bf7 100644 --- a/app/views/layouts/_search.html.haml +++ b/app/views/layouts/_search.html.haml @@ -5,7 +5,7 @@ - if @group && @group.persisted? && @group.path - group_data_attrs = { group_path: j(@group.path), name: @group.name, issues_path: issues_group_path(j(@group.path)), mr_path: merge_requests_group_path(j(@group.path)) } - if @project && @project.persisted? - - project_data_attrs = { project_path: j(@project.path), name: j(@project.name), issues_path: namespace_project_issues_path(@project.namespace, @project), mr_path: namespace_project_merge_requests_path(@project.namespace, @project) } + - project_data_attrs = { project_path: j(@project.path), name: j(@project.name), issues_path: project_issues_path(@project), mr_path: project_merge_requests_path(@project) } .search.search-form{ class: "#{'has-location-badge' if label.present?}" } = form_tag search_path, method: :get, class: 'navbar-form' do |f| .search-input-container diff --git a/app/views/layouts/header/_default.html.haml b/app/views/layouts/header/_default.html.haml index 8cbc3f6105f..ed44263741e 100644 --- a/app/views/layouts/header/_default.html.haml +++ b/app/views/layouts/header/_default.html.haml @@ -74,9 +74,8 @@ = link_to "Profile", current_user, class: 'profile-link', data: { user: current_user.username } %li = link_to "Settings", profile_path - - if can_toggle_new_nav? - %li - = link_to "Turn on new nav", profile_preferences_path(anchor: "new-navigation") + %li + = link_to "Turn on new nav", profile_preferences_path(anchor: "new-navigation") %li.divider %li = link_to "Sign out", destroy_user_session_path, method: :delete, class: "sign-out-link" @@ -96,4 +95,4 @@ - if @project && !@project.empty_repo? - if ref = @ref || @project.repository.root_ref :javascript - var findFileURL = "#{namespace_project_find_file_path(@project.namespace, @project, ref)}"; + var findFileURL = "#{project_find_file_path(@project, ref)}"; diff --git a/app/views/layouts/header/_new.html.haml b/app/views/layouts/header/_new.html.haml index 5859f689dd1..bee7291da45 100644 --- a/app/views/layouts/header/_new.html.haml +++ b/app/views/layouts/header/_new.html.haml @@ -88,4 +88,4 @@ - if @project && !@project.empty_repo? - if ref = @ref || @project.repository.root_ref :javascript - var findFileURL = "#{namespace_project_find_file_path(@project.namespace, @project, ref)}"; + var findFileURL = "#{project_find_file_path(@project, ref)}"; diff --git a/app/views/layouts/header/_new_dropdown.haml b/app/views/layouts/header/_new_dropdown.haml index 4d41579168c..9da739b0974 100644 --- a/app/views/layouts/header/_new_dropdown.haml +++ b/app/views/layouts/header/_new_dropdown.haml @@ -30,13 +30,13 @@ %li.dropdown-bold-header This project - if create_project_issue %li - = link_to 'New issue', new_namespace_project_issue_path(@project.namespace, @project) + = link_to 'New issue', new_project_issue_path(@project) - if merge_project %li - = link_to 'New merge request', namespace_project_new_merge_request_path(merge_project.namespace, merge_project) + = link_to 'New merge request', project_new_merge_request_path(merge_project) - if create_project_snippet %li.header-new-project-snippet - = link_to 'New snippet', new_namespace_project_snippet_path(@project.namespace, @project) + = link_to 'New snippet', new_project_snippet_path(@project) %li.divider %li.dropdown-bold-header GitLab - if current_user.can_create_project? diff --git a/app/views/layouts/nav/_new_project_sidebar.html.haml b/app/views/layouts/nav/_new_project_sidebar.html.haml index eae9da5da14..6e483353a2d 100644 --- a/app/views/layouts/nav/_new_project_sidebar.html.haml +++ b/app/views/layouts/nav/_new_project_sidebar.html.haml @@ -27,52 +27,52 @@ - if project_nav_tab? :files = nav_link(controller: %w(tree blob blame edit_tree new_tree find_file commit commits compare projects/repositories tags branches releases graphs network)) do - = link_to project_files_path(@project), title: 'Repository', class: 'shortcuts-tree' do + = link_to project_tree_path(@project), title: 'Repository', class: 'shortcuts-tree' do %span Repository %ul.sidebar-sub-level-items = nav_link(controller: %w(tree blob blame edit_tree new_tree find_file)) do - = link_to project_files_path(@project) do + = link_to project_tree_path(@project) do #{ _('Files') } = nav_link(controller: [:commit, :commits]) do - = link_to namespace_project_commits_path(@project.namespace, @project, current_ref) do + = link_to project_commits_path(@project, current_ref) do #{ _('Commits') } = nav_link(html_options: {class: branches_tab_class}) do - = link_to namespace_project_branches_path(@project.namespace, @project) do + = link_to project_branches_path(@project) do #{ _('Branches') } = nav_link(controller: [:tags, :releases]) do - = link_to namespace_project_tags_path(@project.namespace, @project) do + = link_to project_tags_path(@project) do #{ _('Tags') } = nav_link(path: 'graphs#show') do - = link_to namespace_project_graph_path(@project.namespace, @project, current_ref) do + = link_to project_graph_path(@project, current_ref) do #{ _('Contributors') } = nav_link(controller: %w(network)) do - = link_to namespace_project_network_path(@project.namespace, @project, current_ref) do + = link_to project_network_path(@project, current_ref) do #{ s_('ProjectNetworkGraph|Graph') } = nav_link(controller: :compare) do - = link_to namespace_project_compare_index_path(@project.namespace, @project, from: @repository.root_ref, to: current_ref) do + = link_to project_compare_index_path(@project, from: @repository.root_ref, to: current_ref) do #{ _('Compare') } = nav_link(path: 'graphs#charts') do - = link_to charts_namespace_project_graph_path(@project.namespace, @project, current_ref) do + = link_to charts_project_graph_path(@project, current_ref) do #{ _('Charts') } - if project_nav_tab? :container_registry = nav_link(controller: %w[projects/registry/repositories]) do - = link_to project_container_registry_path(@project), title: 'Container Registry', class: 'shortcuts-container-registry' do + = link_to project_container_registry_index_path(@project), title: 'Container Registry', class: 'shortcuts-container-registry' do %span Registry - if project_nav_tab? :issues = nav_link(controller: @project.default_issues_tracker? ? [:issues, :labels, :milestones, :boards] : :issues) do - = link_to namespace_project_issues_path(@project.namespace, @project), title: 'Issues', class: 'shortcuts-issues' do + = link_to project_issues_path(@project), title: 'Issues', class: 'shortcuts-issues' do %span Issues - if @project.default_issues_tracker? @@ -81,36 +81,36 @@ %ul.sidebar-sub-level-items - if project_nav_tab?(:issues) && !current_controller?(:merge_requests) = nav_link(controller: :issues) do - = link_to namespace_project_issues_path(@project.namespace, @project), title: 'Issues' do + = link_to project_issues_path(@project), title: 'Issues' do %span List = nav_link(controller: :boards) do - = link_to namespace_project_boards_path(@project.namespace, @project), title: 'Board' do + = link_to project_boards_path(@project), title: 'Board' do %span Board - if project_nav_tab?(:merge_requests) && current_controller?(:merge_requests) = nav_link(controller: :merge_requests) do - = link_to namespace_project_merge_requests_path(@project.namespace, @project), title: 'Merge Requests' do + = link_to project_merge_requests_path(@project), title: 'Merge Requests' do %span Merge Requests - if project_nav_tab? :labels = nav_link(controller: :labels) do - = link_to namespace_project_labels_path(@project.namespace, @project), title: 'Labels' do + = link_to project_labels_path(@project), title: 'Labels' do %span Labels - if project_nav_tab? :milestones = nav_link(controller: :milestones) do - = link_to namespace_project_milestones_path(@project.namespace, @project), title: 'Milestones' do + = link_to project_milestones_path(@project), title: 'Milestones' do %span Milestones - if project_nav_tab? :merge_requests = nav_link(controller: @project.default_issues_tracker? ? :merge_requests : [:merge_requests, :labels, :milestones]) do - = link_to namespace_project_merge_requests_path(@project.namespace, @project), title: 'Merge Requests', class: 'shortcuts-merge_requests' do + = link_to project_merge_requests_path(@project), title: 'Merge Requests', class: 'shortcuts-merge_requests' do %span Merge Requests %span.badge.count.merge_counter.js-merge-counter= number_with_delimiter(MergeRequestsFinder.new(current_user, project_id: @project.id).execute.opened.count) @@ -148,7 +148,7 @@ - if @project.feature_available?(:builds, current_user) && !@project.empty_repo? = nav_link(path: 'pipelines#charts') do - = link_to charts_namespace_project_pipelines_path(@project.namespace, @project), title: 'Charts', class: 'shortcuts-pipelines-charts' do + = link_to charts_project_pipelines_path(@project), title: 'Charts', class: 'shortcuts-pipelines-charts' do %span Charts @@ -160,7 +160,7 @@ - if project_nav_tab? :snippets = nav_link(controller: :snippets) do - = link_to namespace_project_snippets_path(@project.namespace, @project), title: 'Snippets', class: 'shortcuts-snippets' do + = link_to project_snippets_path(@project), title: 'Snippets', class: 'shortcuts-snippets' do %span Snippets @@ -187,23 +187,23 @@ %span Integrations = nav_link(controller: :repository) do - = link_to namespace_project_settings_repository_path(@project.namespace, @project), title: 'Repository' do + = link_to project_settings_repository_path(@project), title: 'Repository' do %span Repository - if @project.feature_available?(:builds, current_user) = nav_link(controller: :ci_cd) do - = link_to namespace_project_settings_ci_cd_path(@project.namespace, @project), title: 'Pipelines' do + = link_to project_settings_ci_cd_path(@project), title: 'Pipelines' do %span Pipelines - if Gitlab.config.pages.enabled = nav_link(controller: :pages) do - = link_to namespace_project_pages_path(@project.namespace, @project), title: 'Pages' do + = link_to project_pages_path(@project), title: 'Pages' do %span Pages - else = nav_link(path: %w[members#show]) do - = link_to namespace_project_settings_members_path(@project.namespace, @project), title: 'Settings', class: 'shortcuts-tree' do + = link_to project_settings_members_path(@project), title: 'Settings', class: 'shortcuts-tree' do %span Settings @@ -216,18 +216,18 @@ -# Shortcut to Repository > Graph (formerly, Network) - if project_nav_tab? :network %li.hidden - = link_to namespace_project_network_path(@project.namespace, @project, current_ref), title: 'Network', class: 'shortcuts-network' do + = link_to project_network_path(@project, current_ref), title: 'Network', class: 'shortcuts-network' do Graph -# Shortcut to Repository > Charts (formerly, top-nav item "Graphs") - unless @project.empty_repo? %li.hidden - = link_to charts_namespace_project_graph_path(@project.namespace, @project, current_ref), title: 'Charts', class: 'shortcuts-repository-charts' do + = link_to charts_project_graph_path(@project, current_ref), title: 'Charts', class: 'shortcuts-repository-charts' do Charts -# Shortcut to Issues > New Issue %li.hidden - = link_to new_namespace_project_issue_path(@project.namespace, @project), class: 'shortcuts-new-issue' do + = link_to new_project_issue_path(@project), class: 'shortcuts-new-issue' do Create a new issue -# Shortcut to Pipelines > Jobs @@ -244,4 +244,4 @@ -# Shortcut to issue boards %li.hidden - = link_to 'Issue Boards', namespace_project_boards_path(@project.namespace, @project), title: 'Issue Boards', class: 'shortcuts-issue-boards' + = link_to 'Issue Boards', project_boards_path(@project), title: 'Issue Boards', class: 'shortcuts-issue-boards' diff --git a/app/views/layouts/nav/_project.html.haml b/app/views/layouts/nav/_project.html.haml index b095adcfe7e..14deb46eee3 100644 --- a/app/views/layouts/nav/_project.html.haml +++ b/app/views/layouts/nav/_project.html.haml @@ -12,19 +12,19 @@ - if project_nav_tab? :files = nav_link(controller: %w(tree blob blame edit_tree new_tree find_file commit commits compare projects/repositories tags branches releases graphs network)) do - = link_to project_files_path(@project), title: 'Repository', class: 'shortcuts-tree' do + = link_to project_tree_path(@project), title: 'Repository', class: 'shortcuts-tree' do %span Repository - if project_nav_tab? :container_registry = nav_link(controller: %w[projects/registry/repositories]) do - = link_to project_container_registry_path(@project), title: 'Container Registry', class: 'shortcuts-container-registry' do + = link_to project_container_registry_index_path(@project), title: 'Container Registry', class: 'shortcuts-container-registry' do %span Registry - if project_nav_tab? :issues = nav_link(controller: @project.default_issues_tracker? ? [:issues, :labels, :milestones, :boards] : :issues) do - = link_to namespace_project_issues_path(@project.namespace, @project), title: 'Issues', class: 'shortcuts-issues' do + = link_to project_issues_path(@project), title: 'Issues', class: 'shortcuts-issues' do %span Issues - if @project.default_issues_tracker? @@ -34,7 +34,7 @@ - controllers = [:merge_requests, 'projects/merge_requests/conflicts'] - controllers.push(:merge_requests, :labels, :milestones) unless @project.default_issues_tracker? = nav_link(controller: controllers) do - = link_to namespace_project_merge_requests_path(@project.namespace, @project), title: 'Merge Requests', class: 'shortcuts-merge_requests' do + = link_to project_merge_requests_path(@project), title: 'Merge Requests', class: 'shortcuts-merge_requests' do %span Merge Requests %span.badge.count.merge_counter.js-merge-counter= number_with_delimiter(issuables_count_for_state(:merge_requests, :opened, finder: MergeRequestsFinder.new(current_user, project_id: @project.id))) @@ -53,7 +53,7 @@ - if project_nav_tab? :snippets = nav_link(controller: :snippets) do - = link_to namespace_project_snippets_path(@project.namespace, @project), title: 'Snippets', class: 'shortcuts-snippets' do + = link_to project_snippets_path(@project), title: 'Snippets', class: 'shortcuts-snippets' do %span Snippets @@ -64,7 +64,7 @@ Settings - else = nav_link(path: %w[members#show]) do - = link_to namespace_project_settings_members_path(@project.namespace, @project), title: 'Settings', class: 'shortcuts-tree' do + = link_to project_settings_members_path(@project), title: 'Settings', class: 'shortcuts-tree' do %span Settings @@ -77,18 +77,18 @@ -# Shortcut to Repository > Graph (formerly, Network) - if project_nav_tab? :network %li.hidden - = link_to namespace_project_network_path(@project.namespace, @project, current_ref), title: 'Network', class: 'shortcuts-network' do + = link_to project_network_path(@project, current_ref), title: 'Network', class: 'shortcuts-network' do Graph -# Shortcut to Repository > Charts (formerly, top-nav item "Graphs") - unless @project.empty_repo? %li.hidden - = link_to charts_namespace_project_graph_path(@project.namespace, @project, current_ref), title: 'Charts', class: 'shortcuts-repository-charts' do + = link_to charts_project_graph_path(@project, current_ref), title: 'Charts', class: 'shortcuts-repository-charts' do Charts -# Shortcut to Issues > New Issue %li.hidden - = link_to new_namespace_project_issue_path(@project.namespace, @project), class: 'shortcuts-new-issue' do + = link_to new_project_issue_path(@project), class: 'shortcuts-new-issue' do Create a new issue -# Shortcut to Pipelines > Jobs @@ -105,4 +105,4 @@ -# Shortcut to issue boards %li.hidden - = link_to 'Issue Boards', namespace_project_boards_path(@project.namespace, @project), title: 'Issue Boards', class: 'shortcuts-issue-boards' + = link_to 'Issue Boards', project_boards_path(@project), title: 'Issue Boards', class: 'shortcuts-issue-boards' diff --git a/app/views/layouts/project.html.haml b/app/views/layouts/project.html.haml index 4458c3c2c23..99adb83cd1f 100644 --- a/app/views/layouts/project.html.haml +++ b/app/views/layouts/project.html.haml @@ -11,7 +11,7 @@ - project = @target_project || @project - if current_user :javascript - window.uploads_path = "#{namespace_project_uploads_path project.namespace,project}"; + window.uploads_path = "#{project_uploads_path(project)}"; - content_for :header_content do .js-dropdown-menu-projects diff --git a/app/views/notify/closed_issue_email.text.haml b/app/views/notify/closed_issue_email.text.haml index bc12e38675f..b35d4b7502d 100644 --- a/app/views/notify/closed_issue_email.text.haml +++ b/app/views/notify/closed_issue_email.text.haml @@ -1,3 +1,3 @@ Issue was closed by #{@updated_by.name} -Issue ##{@issue.iid}: #{namespace_project_issue_url(@issue.project.namespace, @issue.project, @issue)} +Issue ##{@issue.iid}: #{project_issue_url(@issue.project, @issue)} diff --git a/app/views/notify/closed_merge_request_email.text.haml b/app/views/notify/closed_merge_request_email.text.haml index d0c96b83976..c4e06cb3cb1 100644 --- a/app/views/notify/closed_merge_request_email.text.haml +++ b/app/views/notify/closed_merge_request_email.text.haml @@ -1,6 +1,6 @@ Merge Request #{@merge_request.to_reference} was closed by #{@updated_by.name} -Merge Request url: #{namespace_project_merge_request_url(@merge_request.target_project.namespace, @merge_request.target_project, @merge_request)} +Merge Request url: #{project_merge_request_url(@merge_request.target_project, @merge_request)} = merge_path_description(@merge_request, 'to') diff --git a/app/views/notify/issue_moved_email.html.haml b/app/views/notify/issue_moved_email.html.haml index 40f7d61fe19..472c31e9a5e 100644 --- a/app/views/notify/issue_moved_email.html.haml +++ b/app/views/notify/issue_moved_email.html.haml @@ -2,5 +2,5 @@ Issue was moved to another project. %p New issue: - = link_to namespace_project_issue_url(@new_project.namespace, @new_project, @new_issue) do + = link_to project_issue_url(@new_project, @new_issue) do = @new_issue.title diff --git a/app/views/notify/issue_moved_email.text.erb b/app/views/notify/issue_moved_email.text.erb index b3bd43c2055..66ede43635b 100644 --- a/app/views/notify/issue_moved_email.text.erb +++ b/app/views/notify/issue_moved_email.text.erb @@ -1,4 +1,4 @@ Issue was moved to another project. New issue location: -<%= namespace_project_issue_url(@new_project.namespace, @new_project, @new_issue) %> +<%= project_issue_url(@new_project, @new_issue) %> diff --git a/app/views/notify/issue_status_changed_email.text.erb b/app/views/notify/issue_status_changed_email.text.erb index e6ab3fcde77..4200881f7e8 100644 --- a/app/views/notify/issue_status_changed_email.text.erb +++ b/app/views/notify/issue_status_changed_email.text.erb @@ -1,4 +1,4 @@ Issue was <%= @issue_status %> by <%= @updated_by.name %> -Issue <%= @issue.iid %>: <%= url_for(namespace_project_issue_url(@issue.project.namespace, @issue.project, @issue)) %> +Issue <%= @issue.iid %>: <%= url_for(project_issue_url(@issue.project, @issue)) %> diff --git a/app/views/notify/merge_request_status_email.text.haml b/app/views/notify/merge_request_status_email.text.haml index 4c9719ba732..ae2a2933865 100644 --- a/app/views/notify/merge_request_status_email.text.haml +++ b/app/views/notify/merge_request_status_email.text.haml @@ -1,6 +1,6 @@ Merge Request #{@merge_request.to_reference} was #{@mr_status} by #{@updated_by.name} -Merge Request url: #{namespace_project_merge_request_url(@merge_request.target_project.namespace, @merge_request.target_project, @merge_request)} +Merge Request url: #{project_merge_request_url(@merge_request.target_project, @merge_request)} = merge_path_description(@merge_request, 'to') diff --git a/app/views/notify/merged_merge_request_email.text.haml b/app/views/notify/merged_merge_request_email.text.haml index 46c1c9dee0b..661c23bcbe2 100644 --- a/app/views/notify/merged_merge_request_email.text.haml +++ b/app/views/notify/merged_merge_request_email.text.haml @@ -1,6 +1,6 @@ Merge Request #{@merge_request.to_reference} was merged -Merge Request url: #{namespace_project_merge_request_url(@merge_request.target_project.namespace, @merge_request.target_project, @merge_request)} +Merge Request url: #{project_merge_request_url(@merge_request.target_project, @merge_request)} = merge_path_description(@merge_request, 'to') diff --git a/app/views/notify/new_issue_email.text.erb b/app/views/notify/new_issue_email.text.erb index 13f1ac08e94..3c716f77296 100644 --- a/app/views/notify/new_issue_email.text.erb +++ b/app/views/notify/new_issue_email.text.erb @@ -1,6 +1,6 @@ New Issue was created. -Issue <%= @issue.iid %>: <%= url_for(namespace_project_issue_url(@issue.project.namespace, @issue.project, @issue)) %> +Issue <%= @issue.iid %>: <%= url_for(project_issue_url(@issue.project, @issue)) %> Author: <%= @issue.author_name %> Assignee: <%= @issue.assignee_list %> diff --git a/app/views/notify/new_mention_in_issue_email.text.erb b/app/views/notify/new_mention_in_issue_email.text.erb index f19ac3adfc7..23213106c5b 100644 --- a/app/views/notify/new_mention_in_issue_email.text.erb +++ b/app/views/notify/new_mention_in_issue_email.text.erb @@ -1,6 +1,6 @@ You have been mentioned in an issue. -Issue <%= @issue.iid %>: <%= url_for(namespace_project_issue_url(@issue.project.namespace, @issue.project, @issue)) %> +Issue <%= @issue.iid %>: <%= url_for(project_issue_url(@issue.project, @issue)) %> Author: <%= @issue.author_name %> Assignee: <%= @issue.assignee_list %> diff --git a/app/views/notify/new_mention_in_merge_request_email.text.erb b/app/views/notify/new_mention_in_merge_request_email.text.erb index 5bf0282e097..6fcebb22fc4 100644 --- a/app/views/notify/new_mention_in_merge_request_email.text.erb +++ b/app/views/notify/new_mention_in_merge_request_email.text.erb @@ -1,6 +1,6 @@ You have been mentioned in Merge Request <%= @merge_request.to_reference %> -<%= url_for(namespace_project_merge_request_url(@merge_request.target_project.namespace, @merge_request.target_project, @merge_request)) %> +<%= url_for(project_merge_request_url(@merge_request.target_project, @merge_request)) %> <%= merge_path_description(@merge_request, 'to') %> Author: <%= @merge_request.author_name %> diff --git a/app/views/notify/new_merge_request_email.text.erb b/app/views/notify/new_merge_request_email.text.erb index 3c8f178ac77..7d98400e6fe 100644 --- a/app/views/notify/new_merge_request_email.text.erb +++ b/app/views/notify/new_merge_request_email.text.erb @@ -1,6 +1,6 @@ New Merge Request <%= @merge_request.to_reference %> -<%= url_for(namespace_project_merge_request_url(@merge_request.target_project.namespace, @merge_request.target_project, @merge_request)) %> +<%= url_for(project_merge_request_url(@merge_request.target_project, @merge_request)) %> <%= merge_path_description(@merge_request, 'to') %> Author: <%= @merge_request.author_name %> diff --git a/app/views/notify/project_was_exported_email.html.haml b/app/views/notify/project_was_exported_email.html.haml index 3def26342a1..f0ba7827cef 100644 --- a/app/views/notify/project_was_exported_email.html.haml +++ b/app/views/notify/project_was_exported_email.html.haml @@ -2,7 +2,7 @@ Project #{@project.name} was exported successfully. %p The project export can be downloaded from: - = link_to download_export_namespace_project_url(@project.namespace, @project), rel: 'nofollow', download: '' do + = link_to download_export_project_url(@project), rel: 'nofollow', download: '' do = @project.name_with_namespace + " export" %p The download link will expire in 24 hours. diff --git a/app/views/notify/project_was_exported_email.text.erb b/app/views/notify/project_was_exported_email.text.erb index 42c4d176876..cd3a1f7934f 100644 --- a/app/views/notify/project_was_exported_email.text.erb +++ b/app/views/notify/project_was_exported_email.text.erb @@ -1,6 +1,6 @@ Project <%= @project.name %> was exported successfully. The project export can be downloaded from: -<%= download_export_namespace_project_url(@project.namespace, @project) %> +<%= download_export_project_url(@project) %> The download link will expire in 24 hours. diff --git a/app/views/notify/project_was_moved_email.html.haml b/app/views/notify/project_was_moved_email.html.haml index 87b3ff7f0b3..c476a39b661 100644 --- a/app/views/notify/project_was_moved_email.html.haml +++ b/app/views/notify/project_was_moved_email.html.haml @@ -2,7 +2,7 @@ Project #{@old_path_with_namespace} was moved to another location %p The project is now located under - = link_to namespace_project_url(@project.namespace, @project) do + = link_to project_url(@project) do = @project.name_with_namespace %p To update the remote url in your local repository run (for ssh): diff --git a/app/views/notify/project_was_moved_email.text.erb b/app/views/notify/project_was_moved_email.text.erb index b2c5f71e465..7c45163e0e8 100644 --- a/app/views/notify/project_was_moved_email.text.erb +++ b/app/views/notify/project_was_moved_email.text.erb @@ -1,7 +1,7 @@ Project <%= @old_path_with_namespace %> was moved to another location The project is now located under -<%= namespace_project_url(@project.namespace, @project) %> +<%= project_url(@project) %> To update the remote url in your local repository run (for ssh): diff --git a/app/views/notify/repository_push_email.html.haml b/app/views/notify/repository_push_email.html.haml index 546376aeed8..5c5520f4cb8 100644 --- a/app/views/notify/repository_push_email.html.haml +++ b/app/views/notify/repository_push_email.html.haml @@ -3,7 +3,7 @@ %h3 #{@message.author_name} #{@message.action_name} #{@message.ref_type} #{@message.ref_name} - at #{link_to(@message.project_name_with_namespace, namespace_project_url(@message.project_namespace, @message.project))} + at #{link_to(@message.project_name_with_namespace, project_url(@message.project))} - if @message.compare - if @message.reverse_compare? @@ -17,7 +17,7 @@ %ul - @message.commits.each do |commit| %li - %strong= link_to(commit.short_id, namespace_project_commit_url(@message.project_namespace, @message.project, commit)) + %strong= link_to(commit.short_id, project_commit_url(@message.project, commit)) %div %span by #{commit.author_name} %i at #{commit.committed_date.to_s(:iso8601)} diff --git a/app/views/notify/resolved_all_discussions_email.text.erb b/app/views/notify/resolved_all_discussions_email.text.erb index b0d380af8fc..2881f3e699e 100644 --- a/app/views/notify/resolved_all_discussions_email.text.erb +++ b/app/views/notify/resolved_all_discussions_email.text.erb @@ -1,3 +1,3 @@ All discussions on Merge Request <%= @merge_request.to_reference %> were resolved by <%= @resolved_by.name %> -<%= url_for(namespace_project_merge_request_url(@merge_request.target_project.namespace, @merge_request.target_project, @merge_request)) %> +<%= url_for(project_merge_request_url(@merge_request.target_project, @merge_request)) %> diff --git a/app/views/profiles/chat_names/_chat_name.html.haml b/app/views/profiles/chat_names/_chat_name.html.haml index 1ec1e7c70e4..fe1cf802971 100644 --- a/app/views/profiles/chat_names/_chat_name.html.haml +++ b/app/views/profiles/chat_names/_chat_name.html.haml @@ -10,7 +10,7 @@ %td %strong - if can?(current_user, :admin_project, project) - = link_to service.title, edit_namespace_project_service_path(project.namespace, project, service) + = link_to service.title, edit_project_service_path(project, service) - else = service.title %td diff --git a/app/views/profiles/preferences/show.html.haml b/app/views/profiles/preferences/show.html.haml index a089aeb2447..bd602071384 100644 --- a/app/views/profiles/preferences/show.html.haml +++ b/app/views/profiles/preferences/show.html.haml @@ -16,25 +16,22 @@ .preview= image_tag "#{scheme.css_class}-scheme-preview.png" = f.radio_button :color_scheme_id, scheme.id = scheme.name - - if can_toggle_new_nav? - .col-sm-12 - %hr - .col-lg-3.profile-settings-sidebar#new-navigation - %h4.prepend-top-0 - New Navigation - %p - This setting allows you to turn on or off the new upcoming navigation concept. - = succeed '.' do - = link_to 'Learn more', '', target: '_blank' - .col-lg-9.syntax-theme - = label_tag do - .preview= image_tag "old_nav.png" - %input.js-experiment-feature-toggle{ type: "radio", value: "false", name: "new_nav", checked: !show_new_nav? } - Old - = label_tag do - .preview= image_tag "new_nav.png" - %input.js-experiment-feature-toggle{ type: "radio", value: "true", name: "new_nav", checked: show_new_nav? } - New + .col-sm-12 + %hr + .col-lg-4.profile-settings-sidebar#new-navigation + %h4.prepend-top-0 + New Navigation + %p + This setting allows you to turn on or off the new upcoming navigation concept. + .col-lg-8.syntax-theme + = label_tag do + .preview= image_tag "old_nav.png" + %input.js-experiment-feature-toggle{ type: "radio", value: "false", name: "new_nav", checked: !show_new_nav? } + Old + = label_tag do + .preview= image_tag "new_nav.png" + %input.js-experiment-feature-toggle{ type: "radio", value: "true", name: "new_nav", checked: show_new_nav? } + New .col-sm-12 %hr .col-lg-4.profile-settings-sidebar diff --git a/app/views/projects/_activity.html.haml b/app/views/projects/_activity.html.haml index 10f581d751b..ecc966ed453 100644 --- a/app/views/projects/_activity.html.haml +++ b/app/views/projects/_activity.html.haml @@ -1,7 +1,7 @@ %div{ class: container_class } .nav-block.activity-filter-block.activities .controls - = link_to namespace_project_path(@project.namespace, @project, rss_url_options), title: "Subscribe", class: 'btn rss-btn has-tooltip' do + = link_to project_path(@project, rss_url_options), title: "Subscribe", class: 'btn rss-btn has-tooltip' do = icon('rss') = render 'shared/event_filter' diff --git a/app/views/projects/_find_file_link.html.haml b/app/views/projects/_find_file_link.html.haml index cb4d2bbacf5..da1b2d7f9b6 100644 --- a/app/views/projects/_find_file_link.html.haml +++ b/app/views/projects/_find_file_link.html.haml @@ -1,3 +1,3 @@ -= link_to namespace_project_find_file_path(@project.namespace, @project, @ref), class: 'btn shortcuts-find-file', rel: 'nofollow' do += link_to project_find_file_path(@project, @ref), class: 'btn shortcuts-find-file', rel: 'nofollow' do = icon('search') %span= _('Find file') diff --git a/app/views/projects/_last_push.html.haml b/app/views/projects/_last_push.html.haml index f1ef50d2de2..1a71bfca2e2 100644 --- a/app/views/projects/_last_push.html.haml +++ b/app/views/projects/_last_push.html.haml @@ -5,7 +5,7 @@ .event-last-push-text %span You pushed to %strong - = link_to event.ref_name, namespace_project_commits_path(event.project.namespace, event.project, event.ref_name), class: 'ref-name' + = link_to event.ref_name, project_commits_path(event.project, event.ref_name), class: 'ref-name' - if event.project != @project %span at diff --git a/app/views/projects/_wiki.html.haml b/app/views/projects/_wiki.html.haml index 2bab22e125d..a56c3503c77 100644 --- a/app/views/projects/_wiki.html.haml +++ b/app/views/projects/_wiki.html.haml @@ -14,5 +14,5 @@ Add a homepage to your wiki that contains information about your project %p We recommend you - = link_to "add a homepage", namespace_project_wiki_path(@project.namespace, @project, :home) + = link_to "add a homepage", project_wiki_path(@project, :home) to your project's wiki and GitLab will show it here instead of this message. diff --git a/app/views/projects/artifacts/_tree_directory.html.haml b/app/views/projects/artifacts/_tree_directory.html.haml index e2966ec33c2..03be6f15313 100644 --- a/app/views/projects/artifacts/_tree_directory.html.haml +++ b/app/views/projects/artifacts/_tree_directory.html.haml @@ -1,4 +1,4 @@ -- path_to_directory = browse_namespace_project_job_artifacts_path(@project.namespace, @project, @build, path: directory.path) +- path_to_directory = browse_project_job_artifacts_path(@project, @build, path: directory.path) %tr.tree-item{ 'data-link' => path_to_directory } %td.tree-item-file-name diff --git a/app/views/projects/artifacts/_tree_file.html.haml b/app/views/projects/artifacts/_tree_file.html.haml index ea0b43b85cf..8edb9be049a 100644 --- a/app/views/projects/artifacts/_tree_file.html.haml +++ b/app/views/projects/artifacts/_tree_file.html.haml @@ -1,4 +1,4 @@ -- path_to_file = file_namespace_project_job_artifacts_path(@project.namespace, @project, @build, path: file.path) +- path_to_file = file_project_job_artifacts_path(@project, @build, path: file.path) %tr.tree-item{ 'data-link' => path_to_file } - blob = file.blob diff --git a/app/views/projects/artifacts/browse.html.haml b/app/views/projects/artifacts/browse.html.haml index 961c805dc7c..576e5b385af 100644 --- a/app/views/projects/artifacts/browse.html.haml +++ b/app/views/projects/artifacts/browse.html.haml @@ -6,17 +6,17 @@ .tree-holder .nav-block .tree-controls - = link_to download_namespace_project_job_artifacts_path(@project.namespace, @project, @build), + = link_to download_project_job_artifacts_path(@project, @build), rel: 'nofollow', download: '', class: 'btn btn-default download' do = icon('download') Download artifacts archive %ul.breadcrumb.repo-breadcrumb %li - = link_to 'Artifacts', browse_namespace_project_job_artifacts_path(@project.namespace, @project, @build) + = link_to 'Artifacts', browse_project_job_artifacts_path(@project, @build) - path_breadcrumbs do |title, path| %li - = link_to truncate(title, length: 40), browse_namespace_project_job_artifacts_path(@project.namespace, @project, @build, path) + = link_to truncate(title, length: 40), browse_project_job_artifacts_path(@project, @build, path) .tree-content-holder %table.table.tree-table diff --git a/app/views/projects/artifacts/file.html.haml b/app/views/projects/artifacts/file.html.haml index b25c7c95196..18e86ac5a92 100644 --- a/app/views/projects/artifacts/file.html.haml +++ b/app/views/projects/artifacts/file.html.haml @@ -7,15 +7,15 @@ .nav-block %ul.breadcrumb.repo-breadcrumb %li - = link_to 'Artifacts', browse_namespace_project_job_artifacts_path(@project.namespace, @project, @build) + = link_to 'Artifacts', browse_project_job_artifacts_path(@project, @build) - path_breadcrumbs do |title, path| - title = truncate(title, length: 40) %li - if path == @path - = link_to file_namespace_project_job_artifacts_path(@project.namespace, @project, @build, path) do + = link_to file_project_job_artifacts_path(@project, @build, path) do %strong= title - else - = link_to title, browse_namespace_project_job_artifacts_path(@project.namespace, @project, @build, path) + = link_to title, browse_project_job_artifacts_path(@project, @build, path) %article.file-holder diff --git a/app/views/projects/blame/show.html.haml b/app/views/projects/blame/show.html.haml index 3627f72f5e1..f11afe8fc22 100644 --- a/app/views/projects/blame/show.html.haml +++ b/app/views/projects/blame/show.html.haml @@ -22,9 +22,9 @@ = author_avatar(commit, size: 36) .commit-row-title %strong - = link_to_gfm truncate(commit.title, length: 35), namespace_project_commit_path(@project.namespace, @project, commit.id), class: "cdark" + = link_to_gfm truncate(commit.title, length: 35), project_commit_path(@project, commit.id), class: "cdark" .pull-right - = link_to commit.short_id, namespace_project_commit_path(@project.namespace, @project, commit), class: "commit-sha" + = link_to commit.short_id, project_commit_path(@project, commit), class: "commit-sha" .light = commit_author_link(commit, avatar: false) diff --git a/app/views/projects/blob/_breadcrumb.html.haml b/app/views/projects/blob/_breadcrumb.html.haml index 2c944b516a4..1c148de9678 100644 --- a/app/views/projects/blob/_breadcrumb.html.haml +++ b/app/views/projects/blob/_breadcrumb.html.haml @@ -6,16 +6,16 @@ %ul.breadcrumb.repo-breadcrumb %li - = link_to namespace_project_tree_path(@project.namespace, @project, @ref) do + = link_to project_tree_path(@project, @ref) do = @project.path - path_breadcrumbs do |title, path| - title = truncate(title, length: 40) %li - if path == @path - = link_to namespace_project_blob_path(@project.namespace, @project, tree_join(@ref, path)) do + = link_to project_blob_path(@project, tree_join(@ref, path)) do %strong= title - else - = link_to title, namespace_project_tree_path(@project.namespace, @project, tree_join(@ref, path)) + = link_to title, project_tree_path(@project, tree_join(@ref, path)) .tree-controls = render 'projects/find_file_link' @@ -24,14 +24,14 @@ -# only show normal/blame view links for text files - if blob.readable_text? - if blame - = link_to 'Normal view', namespace_project_blob_path(@project.namespace, @project, @id), + = link_to 'Normal view', project_blob_path(@project, @id), class: 'btn' - else - = link_to 'Blame', namespace_project_blame_path(@project.namespace, @project, @id), + = link_to 'Blame', project_blame_path(@project, @id), class: 'btn js-blob-blame-link' unless blob.empty? - = link_to 'History', namespace_project_commits_path(@project.namespace, @project, @id), + = link_to 'History', project_commits_path(@project, @id), class: 'btn' - = link_to 'Permalink', namespace_project_blob_path(@project.namespace, @project, + = link_to 'Permalink', project_blob_path(@project, tree_join(@commit.sha, @path)), class: 'btn js-data-file-blob-permalink-url' diff --git a/app/views/projects/blob/_new_dir.html.haml b/app/views/projects/blob/_new_dir.html.haml index 40978583e8b..b2959ef6d31 100644 --- a/app/views/projects/blob/_new_dir.html.haml +++ b/app/views/projects/blob/_new_dir.html.haml @@ -5,7 +5,7 @@ %a.close{ href: "#", "data-dismiss" => "modal" } × %h3.page-title= _('Create New Directory') .modal-body - = form_tag namespace_project_create_dir_path(@project.namespace, @project, @id), method: :post, remote: false, class: 'form-horizontal js-create-dir-form js-quick-submit js-requires-input' do + = form_tag project_create_dir_path(@project, @id), method: :post, remote: false, class: 'form-horizontal js-create-dir-form js-quick-submit js-requires-input' do .form-group = label_tag :dir_name, _('Directory name'), class: 'control-label' .col-sm-10 diff --git a/app/views/projects/blob/_remove.html.haml b/app/views/projects/blob/_remove.html.haml index c8ca0406213..6a4a657fa8c 100644 --- a/app/views/projects/blob/_remove.html.haml +++ b/app/views/projects/blob/_remove.html.haml @@ -6,7 +6,7 @@ %h3.page-title Delete #{@blob.name} .modal-body - = form_tag namespace_project_blob_path(@project.namespace, @project, @id), method: :delete, class: 'form-horizontal js-delete-blob-form js-quick-submit js-requires-input' do + = form_tag project_blob_path(@project, @id), method: :delete, class: 'form-horizontal js-delete-blob-form js-quick-submit js-requires-input' do = render 'shared/new_commit_form', placeholder: "Delete #{@blob.name}" .form-group diff --git a/app/views/projects/blob/edit.html.haml b/app/views/projects/blob/edit.html.haml index 4af62461151..f8cb612a2b4 100644 --- a/app/views/projects/blob/edit.html.haml +++ b/app/views/projects/blob/edit.html.haml @@ -9,7 +9,7 @@ - if @conflict .alert.alert-danger Someone edited the file the same time you did. Please check out - = link_to "the file", namespace_project_blob_path(@project.namespace, @project, tree_join(@branch_name, @file_path)), target: "_blank", rel: 'noopener noreferrer' + = link_to "the file", project_blob_path(@project, tree_join(@branch_name, @file_path)), target: "_blank", rel: 'noopener noreferrer' and make sure your changes will not unintentionally remove theirs. .editor-title-row %h3.page-title.blob-edit-page-title @@ -22,13 +22,13 @@ Write %li - = link_to '#preview', 'data-preview-url' => namespace_project_preview_blob_path(@project.namespace, @project, @id) do + = link_to '#preview', 'data-preview-url' => project_preview_blob_path(@project, @id) do = editing_preview_title(@blob.name) - = form_tag(namespace_project_update_blob_path(@project.namespace, @project, @id), method: :put, class: 'form-horizontal js-quick-submit js-requires-input js-edit-blob-form', data: blob_editor_paths) do + = form_tag(project_update_blob_path(@project, @id), method: :put, class: 'form-horizontal js-quick-submit js-requires-input js-edit-blob-form', data: blob_editor_paths) do = render 'projects/blob/editor', ref: @ref, path: @path, blob_data: @blob.data = render 'shared/new_commit_form', placeholder: "Update #{@blob.name}" = hidden_field_tag 'last_commit_sha', @last_commit_sha = hidden_field_tag 'content', '', id: "file-content" = hidden_field_tag 'from_merge_request_iid', params[:from_merge_request_iid] - = render 'projects/commit_button', ref: @ref, cancel_path: namespace_project_blob_path(@project.namespace, @project, @id) + = render 'projects/commit_button', ref: @ref, cancel_path: project_blob_path(@project, @id) diff --git a/app/views/projects/blob/new.html.haml b/app/views/projects/blob/new.html.haml index 2afb909572a..8620a470041 100644 --- a/app/views/projects/blob/new.html.haml +++ b/app/views/projects/blob/new.html.haml @@ -7,10 +7,10 @@ New file = render 'template_selectors' .file-editor - = form_tag(namespace_project_create_blob_path(@project.namespace, @project, @id), method: :post, class: 'form-horizontal js-edit-blob-form js-new-blob-form js-quick-submit js-requires-input', data: blob_editor_paths) do + = form_tag(project_create_blob_path(@project, @id), method: :post, class: 'form-horizontal js-edit-blob-form js-new-blob-form js-quick-submit js-requires-input', data: blob_editor_paths) do = render 'projects/blob/editor', ref: @ref = render 'shared/new_commit_form', placeholder: "Add new file" = hidden_field_tag 'content', '', id: 'file-content' = render 'projects/commit_button', ref: @ref, - cancel_path: namespace_project_tree_path(@project.namespace, @project, @id) + cancel_path: project_tree_path(@project, @id) diff --git a/app/views/projects/blob/show.html.haml b/app/views/projects/blob/show.html.haml index 41f75a491a5..6e2ae4717cd 100644 --- a/app/views/projects/blob/show.html.haml +++ b/app/views/projects/blob/show.html.haml @@ -16,4 +16,4 @@ = render 'projects/blob/remove' - title = "Replace #{@blob.name}" - = render 'projects/blob/upload', title: title, placeholder: title, button_title: 'Replace file', form_path: namespace_project_update_blob_path(@project.namespace, @project, @id), method: :put + = render 'projects/blob/upload', title: title, placeholder: title, button_title: 'Replace file', form_path: project_update_blob_path(@project, @id), method: :put diff --git a/app/views/projects/blob/viewers/_changelog.html.haml b/app/views/projects/blob/viewers/_changelog.html.haml index 53921e63b5f..46e3e7f798a 100644 --- a/app/views/projects/blob/viewers/_changelog.html.haml +++ b/app/views/projects/blob/viewers/_changelog.html.haml @@ -1,4 +1,4 @@ = icon('history fw') = succeed '.' do To find the state of this project's repository at the time of any of these versions, check out - = link_to "the tags", namespace_project_tags_path(viewer.project.namespace, viewer.project) + = link_to "the tags", project_tags_path(viewer.project) diff --git a/app/views/projects/blob/viewers/_readme.html.haml b/app/views/projects/blob/viewers/_readme.html.haml index 334b33faf48..507f44d4745 100644 --- a/app/views/projects/blob/viewers/_readme.html.haml +++ b/app/views/projects/blob/viewers/_readme.html.haml @@ -1,4 +1,4 @@ = icon('info-circle fw') = succeed '.' do To learn more about this project, read - = link_to "the wiki", namespace_project_wikis_path(viewer.project.namespace, viewer.project) + = link_to "the wiki", project_wikis_path(viewer.project) diff --git a/app/views/projects/boards/_show.html.haml b/app/views/projects/boards/_show.html.haml index 8e070a7cc0c..364c4c0e473 100644 --- a/app/views/projects/boards/_show.html.haml +++ b/app/views/projects/boards/_show.html.haml @@ -4,7 +4,7 @@ - page_title "Boards" - if show_new_nav? - - breadcrumbs_extra_links("Issues", namespace_project_issues_path(@project.namespace, @project)) + - breadcrumbs_extra_links("Issues", project_issues_path(@project.namespace)) - content_for :page_specific_javascripts do = webpack_bundle_tag 'common_vue' @@ -34,7 +34,7 @@ ":key" => "_uid" } = render "projects/boards/components/sidebar" %board-add-issues-modal{ "blank-state-image" => render('shared/empty_states/icons/issues.svg'), - "new-issue-path" => new_namespace_project_issue_path(@project.namespace, @project), + "new-issue-path" => new_project_issue_path(@project), "milestone-path" => milestones_filter_dropdown_path, "label-path" => labels_filter_path, ":issue-link-base" => "issueLinkBase", diff --git a/app/views/projects/boards/components/sidebar/_assignee.html.haml b/app/views/projects/boards/components/sidebar/_assignee.html.haml index e8db868f49b..8d957613be1 100644 --- a/app/views/projects/boards/components/sidebar/_assignee.html.haml +++ b/app/views/projects/boards/components/sidebar/_assignee.html.haml @@ -19,10 +19,11 @@ ":data-name" => "assignee.name", ":data-username" => "assignee.username" } .dropdown - %button.dropdown-menu-toggle.js-user-search.js-author-search.js-multiselect.js-save-user-data.js-issue-board-sidebar{ type: "button", ref: "assigneeDropdown", data: { toggle: "dropdown", field_name: "issue[assignee_ids][]", first_user: (current_user.username if current_user), current_user: "true", project_id: @project.id, null_user: "true", multi_select: "true", 'max-select' => 1, dropdown: { header: 'Assignee' } }, + - dropdown_options = issue_assignees_dropdown_options + %button.dropdown-menu-toggle.js-user-search.js-author-search.js-multiselect.js-save-user-data.js-issue-board-sidebar{ type: 'button', ref: 'assigneeDropdown', data: { toggle: 'dropdown', field_name: 'issue[assignee_ids][]', first_user: current_user&.username, current_user: 'true', project_id: @project.id, null_user: 'true', multi_select: 'true', 'dropdown-header': dropdown_options[:data][:'dropdown-header'], 'max-select': dropdown_options[:data][:'max-select'] }, ":data-issuable-id" => "issue.id", - ":data-issue-update" => "'#{namespace_project_issues_path(@project.namespace, @project)}/' + issue.id + '.json'" } - Select assignee + ":data-issue-update" => "'#{project_issues_path(@project)}/' + issue.id + '.json'" } + = dropdown_options[:title] = icon("chevron-down") .dropdown-menu.dropdown-select.dropdown-menu-user.dropdown-menu-selectable.dropdown-menu-author = dropdown_title("Assign to") diff --git a/app/views/projects/boards/components/sidebar/_due_date.html.haml b/app/views/projects/boards/components/sidebar/_due_date.html.haml index 1a3b88e28c5..f44a9d49a54 100644 --- a/app/views/projects/boards/components/sidebar/_due_date.html.haml +++ b/app/views/projects/boards/components/sidebar/_due_date.html.haml @@ -23,7 +23,7 @@ .dropdown %button.dropdown-menu-toggle.js-due-date-select.js-issue-boards-due-date{ type: 'button', data: { toggle: 'dropdown', field_name: "issue[due_date]", ability_name: "issue" }, - ":data-issue-update" => "'#{namespace_project_issues_path(@project.namespace, @project)}/' + issue.id + '.json'" } + ":data-issue-update" => "'#{project_issues_path(@project)}/' + issue.id + '.json'" } %span.dropdown-toggle-text Due date = icon('chevron-down') .dropdown-menu.dropdown-menu-due-date diff --git a/app/views/projects/boards/components/sidebar/_labels.html.haml b/app/views/projects/boards/components/sidebar/_labels.html.haml index bee0f3dd065..7d0c35fe183 100644 --- a/app/views/projects/boards/components/sidebar/_labels.html.haml +++ b/app/views/projects/boards/components/sidebar/_labels.html.haml @@ -19,8 +19,8 @@ ":value" => "label.id" } .dropdown %button.dropdown-menu-toggle.js-label-select.js-multiselect.js-issue-board-sidebar{ type: "button", - data: { toggle: "dropdown", field_name: "issue[label_names][]", show_no: "true", show_any: "true", project_id: @project.id, labels: namespace_project_labels_path(@project.namespace, @project, :json), namespace_path: @project.try(:namespace).try(:full_path), project_path: @project.try(:path) }, - ":data-issue-update" => "'#{namespace_project_issues_path(@project.namespace, @project)}/' + issue.id + '.json'" } + data: { toggle: "dropdown", field_name: "issue[label_names][]", show_no: "true", show_any: "true", project_id: @project.id, labels: project_labels_path(@project, :json), namespace_path: @project.try(:namespace).try(:full_path), project_path: @project.try(:path) }, + ":data-issue-update" => "'#{project_issues_path(@project)}/' + issue.id + '.json'" } %span.dropdown-toggle-text Label = icon('chevron-down') diff --git a/app/views/projects/boards/components/sidebar/_milestone.html.haml b/app/views/projects/boards/components/sidebar/_milestone.html.haml index 4e46351bf8a..002e9994ee0 100644 --- a/app/views/projects/boards/components/sidebar/_milestone.html.haml +++ b/app/views/projects/boards/components/sidebar/_milestone.html.haml @@ -16,10 +16,10 @@ name: "issue[milestone_id]", "v-if" => "issue.milestone" } .dropdown - %button.dropdown-menu-toggle.js-milestone-select.js-issue-board-sidebar{ type: "button", data: { toggle: "dropdown", show_no: "true", field_name: "issue[milestone_id]", project_id: @project.id, milestones: namespace_project_milestones_path(@project.namespace, @project, :json), ability_name: "issue", use_id: "true", default_no: "true" }, + %button.dropdown-menu-toggle.js-milestone-select.js-issue-board-sidebar{ type: "button", data: { toggle: "dropdown", show_no: "true", field_name: "issue[milestone_id]", project_id: @project.id, milestones: project_milestones_path(@project, :json), ability_name: "issue", use_id: "true", default_no: "true" }, ":data-selected" => "milestoneTitle", ":data-issuable-id" => "issue.id", - ":data-issue-update" => "'#{namespace_project_issues_path(@project.namespace, @project)}/' + issue.id + '.json'" } + ":data-issue-update" => "'#{project_issues_path(@project)}/' + issue.id + '.json'" } Milestone = icon("chevron-down") .dropdown-menu.dropdown-select.dropdown-menu-selectable diff --git a/app/views/projects/boards/components/sidebar/_notifications.html.haml b/app/views/projects/boards/components/sidebar/_notifications.html.haml index a08c7f2af09..aaddd7e249f 100644 --- a/app/views/projects/boards/components/sidebar/_notifications.html.haml +++ b/app/views/projects/boards/components/sidebar/_notifications.html.haml @@ -1,5 +1,5 @@ - if current_user - .block.light.subscription{ ":data-url" => "'#{namespace_project_issues_path(@project.namespace, @project)}/' + issue.id + '/toggle_subscription'" } + .block.light.subscription{ ":data-url" => "'#{project_issues_path(@project)}/' + issue.id + '/toggle_subscription'" } %span.issuable-header-text.hide-collapsed.pull-left Notifications %button.btn.btn-default.pull-right.js-subscribe-button.issuable-subscribe-button.hide-collapsed{ type: "button" } diff --git a/app/views/projects/branches/_branch.html.haml b/app/views/projects/branches/_branch.html.haml index 869633e016d..19712a8f1be 100644 --- a/app/views/projects/branches/_branch.html.haml +++ b/app/views/projects/branches/_branch.html.haml @@ -6,7 +6,7 @@ - merge_project = can?(current_user, :create_merge_request, @project) ? @project : (current_user && current_user.fork_of(@project)) %li{ class: "js-branch-#{branch.name}" } %div - = link_to namespace_project_tree_path(@project.namespace, @project, branch.name), class: 'item-title str-truncated ref-name' do + = link_to project_tree_path(@project, branch.name), class: 'item-title str-truncated ref-name' do = icon('code-fork') = branch.name @@ -25,7 +25,7 @@ Merge request - if branch.name != @repository.root_ref - = link_to namespace_project_compare_index_path(@project.namespace, @project, from: @repository.root_ref, to: branch.name), class: "btn btn-default #{'prepend-left-10' unless merge_project}", method: :post, title: "Compare" do + = link_to project_compare_index_path(@project, from: @repository.root_ref, to: branch.name), class: "btn btn-default #{'prepend-left-10' unless merge_project}", method: :post, title: "Compare" do Compare = render 'projects/buttons/download', project: @project, ref: branch.name, pipeline: @refs_pipelines[branch.name] @@ -42,7 +42,7 @@ title: "Delete protected branch", data: { toggle: "modal", target: "#modal-delete-branch", - delete_path: namespace_project_branch_path(@project.namespace, @project, branch.name), + delete_path: project_branch_path(@project, branch.name), branch_name: branch.name } } = icon("trash-o") - else @@ -51,7 +51,7 @@ title: "Only a project master or owner can delete a protected branch" } = icon("trash-o") - else - = link_to namespace_project_branch_path(@project.namespace, @project, branch.name), + = link_to project_branch_path(@project, branch.name), class: "btn btn-remove remove-row js-ajax-loading-spinner has-tooltip", title: "Delete branch", method: :delete, diff --git a/app/views/projects/branches/_commit.html.haml b/app/views/projects/branches/_commit.html.haml index ad8f9da0621..18fbb81c167 100644 --- a/app/views/projects/branches/_commit.html.haml +++ b/app/views/projects/branches/_commit.html.haml @@ -1,9 +1,9 @@ .branch-commit .icon-container.commit-icon = custom_icon("icon_commit") - = link_to commit.short_id, namespace_project_commit_path(project.namespace, project, commit.id), class: "commit-sha" + = link_to commit.short_id, project_commit_path(project, commit.id), class: "commit-sha" · %span.str-truncated - = link_to_gfm commit.title, namespace_project_commit_path(project.namespace, project, commit.id), class: "commit-row-message" + = link_to_gfm commit.title, project_commit_path(project, commit.id), class: "commit-row-message" · #{time_ago_with_tooltip(commit.committed_date)} diff --git a/app/views/projects/branches/index.html.haml b/app/views/projects/branches/index.html.haml index b4d5d045a2a..4f70a57243b 100644 --- a/app/views/projects/branches/index.html.haml +++ b/app/views/projects/branches/index.html.haml @@ -9,7 +9,7 @@ .top-area.adjust .nav-text Protected branches can be managed in - = link_to 'project settings', namespace_project_protected_branches_path(@project.namespace, @project) + = link_to 'project settings', project_protected_branches_path(@project) .nav-controls = form_tag(filter_branches_path, method: :get) do @@ -28,9 +28,9 @@ = link_to title, filter_branches_path(sort: value), class: ("is-active" if @sort == value) - if can? current_user, :push_code, @project - = link_to namespace_project_merged_branches_path(@project.namespace, @project), class: 'btn btn-inverted btn-remove has-tooltip', title: "Delete all branches that are merged into '#{@project.repository.root_ref}'", method: :delete, data: { confirm: "Deleting the merged branches cannot be undone. Are you sure?", container: 'body' } do + = link_to project_merged_branches_path(@project), class: 'btn btn-inverted btn-remove has-tooltip', title: "Delete all branches that are merged into '#{@project.repository.root_ref}'", method: :delete, data: { confirm: "Deleting the merged branches cannot be undone. Are you sure?", container: 'body' } do Delete merged branches - = link_to new_namespace_project_branch_path(@project.namespace, @project), class: 'btn btn-create' do + = link_to new_project_branch_path(@project), class: 'btn btn-create' do New branch - if @branches.any? diff --git a/app/views/projects/branches/new.html.haml b/app/views/projects/branches/new.html.haml index 5a0eba3551f..03eefcc2b4d 100644 --- a/app/views/projects/branches/new.html.haml +++ b/app/views/projects/branches/new.html.haml @@ -27,7 +27,7 @@ .help-block Existing branch name, tag, or commit SHA .form-actions = button_tag 'Create branch', class: 'btn btn-create', tabindex: 3 - = link_to 'Cancel', namespace_project_branches_path(@project.namespace, @project), class: 'btn btn-cancel' + = link_to 'Cancel', project_branches_path(@project), class: 'btn btn-cancel' :javascript var availableRefs = #{@project.repository.ref_names.to_json}; diff --git a/app/views/projects/buttons/_download.html.haml b/app/views/projects/buttons/_download.html.haml index a73ddd5eb33..883922dbf04 100644 --- a/app/views/projects/buttons/_download.html.haml +++ b/app/views/projects/buttons/_download.html.haml @@ -10,19 +10,19 @@ %li.dropdown-header #{ _('Source code') } %li - = link_to archive_namespace_project_repository_path(project.namespace, project, ref: ref, format: 'zip'), rel: 'nofollow', download: '' do + = link_to archive_project_repository_path(project, ref: ref, format: 'zip'), rel: 'nofollow', download: '' do %i.fa.fa-download %span= _('Download zip') %li - = link_to archive_namespace_project_repository_path(project.namespace, project, ref: ref, format: 'tar.gz'), rel: 'nofollow', download: '' do + = link_to archive_project_repository_path(project, ref: ref, format: 'tar.gz'), rel: 'nofollow', download: '' do %i.fa.fa-download %span= _('Download tar.gz') %li - = link_to archive_namespace_project_repository_path(project.namespace, project, ref: ref, format: 'tar.bz2'), rel: 'nofollow', download: '' do + = link_to archive_project_repository_path(project, ref: ref, format: 'tar.bz2'), rel: 'nofollow', download: '' do %i.fa.fa-download %span= _('Download tar.bz2') %li - = link_to archive_namespace_project_repository_path(project.namespace, project, ref: ref, format: 'tar'), rel: 'nofollow', download: '' do + = link_to archive_project_repository_path(project, ref: ref, format: 'tar'), rel: 'nofollow', download: '' do %i.fa.fa-download %span= _('Download tar') @@ -37,7 +37,7 @@ %li.dropdown-header Previous Artifacts - artifacts.each do |job| %li - = link_to latest_succeeded_namespace_project_artifacts_path(project.namespace, project, "#{ref}/download", job: job.name), rel: 'nofollow', download: '' do + = link_to latest_succeeded_project_artifacts_path(project, "#{ref}/download", job: job.name), rel: 'nofollow', download: '' do %i.fa.fa-download %span #{ s_('DownloadArtifacts|Download') } '#{job.name}' diff --git a/app/views/projects/buttons/_dropdown.html.haml b/app/views/projects/buttons/_dropdown.html.haml index aa1a533b5cb..b04d6a1fa5e 100644 --- a/app/views/projects/buttons/_dropdown.html.haml +++ b/app/views/projects/buttons/_dropdown.html.haml @@ -10,19 +10,19 @@ - if can_create_issue %li - = link_to new_namespace_project_issue_path(@project.namespace, @project) do + = link_to new_project_issue_path(@project) do = icon('exclamation-circle fw') #{ _('New issue') } - if merge_project %li - = link_to namespace_project_new_merge_request_path(merge_project.namespace, merge_project) do + = link_to project_new_merge_request_path(merge_project) do = icon('tasks fw') #{ _('New merge request') } - if can_create_snippet %li - = link_to new_namespace_project_snippet_path(@project.namespace, @project) do + = link_to new_project_snippet_path(@project) do = icon('file-text-o fw') #{ _('New snippet') } @@ -31,28 +31,28 @@ - if can?(current_user, :push_code, @project) %li - = link_to namespace_project_new_blob_path(@project.namespace, @project, @project.default_branch || 'master') do + = link_to project_new_blob_path(@project, @project.default_branch || 'master') do = icon('file fw') #{ _('New file') } %li - = link_to new_namespace_project_branch_path(@project.namespace, @project) do + = link_to new_project_branch_path(@project) do = icon('code-fork fw') #{ _('New branch') } %li - = link_to new_namespace_project_tag_path(@project.namespace, @project) do + = link_to new_project_tag_path(@project) do = icon('tags fw') #{ _('New tag') } - elsif current_user && current_user.already_forked?(@project) %li - = link_to namespace_project_new_blob_path(@project.namespace, @project, @project.default_branch || 'master') do + = link_to project_new_blob_path(@project, @project.default_branch || 'master') do = icon('file fw') #{ _('New file') } - elsif can?(current_user, :fork_project, @project) %li - - continue_params = { to: namespace_project_new_blob_path(@project.namespace, @project, @project.default_branch || 'master'), + - continue_params = { to: project_new_blob_path(@project, @project.default_branch || 'master'), notice: edit_in_new_fork_notice, notice_now: edit_in_new_fork_notice_now } - - fork_path = namespace_project_forks_path(@project.namespace, @project, namespace_key: current_user.namespace.id, + - fork_path = project_forks_path(@project, namespace_key: current_user.namespace.id, continue: continue_params) = link_to fork_path, method: :post do = icon('file fw') diff --git a/app/views/projects/buttons/_fork.html.haml b/app/views/projects/buttons/_fork.html.haml index 42f8c75f57b..f45cc7f0f45 100644 --- a/app/views/projects/buttons/_fork.html.haml +++ b/app/views/projects/buttons/_fork.html.haml @@ -5,14 +5,14 @@ = custom_icon('icon_fork') %span= s_('GoToYourFork|Fork') - elsif !current_user.can_create_project? - = link_to new_namespace_project_fork_path(@project.namespace, @project), title: _('You have reached your project limit'), class: 'btn has-tooltip disabled' do + = link_to new_project_fork_path(@project), title: _('You have reached your project limit'), class: 'btn has-tooltip disabled' do = custom_icon('icon_fork') %span= s_('CreateNewFork|Fork') - else - = link_to new_namespace_project_fork_path(@project.namespace, @project), class: 'btn' do + = link_to new_project_fork_path(@project), class: 'btn' do = custom_icon('icon_fork') %span= s_('CreateNewFork|Fork') .count-with-arrow %span.arrow - = link_to namespace_project_forks_path(@project.namespace, @project), title: n_('Fork', 'Forks', @project.forks_count), class: 'count' do + = link_to project_forks_path(@project), title: n_('Fork', 'Forks', @project.forks_count), class: 'count' do = @project.forks_count diff --git a/app/views/projects/buttons/_star.html.haml b/app/views/projects/buttons/_star.html.haml index 58413e2fc52..e248676be0d 100644 --- a/app/views/projects/buttons/_star.html.haml +++ b/app/views/projects/buttons/_star.html.haml @@ -1,5 +1,5 @@ - if current_user - = link_to toggle_star_namespace_project_path(@project.namespace, @project), { class: 'btn star-btn toggle-star', method: :post, remote: true } do + = link_to toggle_star_project_path(@project), { class: 'btn star-btn toggle-star', method: :post, remote: true } do - if current_user.starred?(@project) = icon('star') %span.starred= _('Unstar') diff --git a/app/views/projects/ci/builds/_build.html.haml b/app/views/projects/ci/builds/_build.html.haml index d9f28d66b66..c1842527480 100644 --- a/app/views/projects/ci/builds/_build.html.haml +++ b/app/views/projects/ci/builds/_build.html.haml @@ -14,7 +14,7 @@ %td.branch-commit - if can?(current_user, :read_build, job) - = link_to namespace_project_job_url(job.project.namespace, job.project, job) do + = link_to project_job_url(job.project, job) do %span.build-link ##{job.id} - else %span.build-link ##{job.id} @@ -30,7 +30,7 @@ = custom_icon("icon_commit") - if commit_sha - = link_to job.short_sha, namespace_project_commit_path(job.project.namespace, job.project, job.sha), class: "commit-sha" + = link_to job.short_sha, project_commit_path(job.project, job.sha), class: "commit-sha" - if job.stuck? = icon('warning', class: 'text-warning has-tooltip', title: 'Job is stuck. Check runners.') @@ -63,7 +63,7 @@ - if admin %td - if job.project - = link_to job.project.name_with_namespace, admin_namespace_project_path(job.project.namespace, job.project) + = link_to job.project.name_with_namespace, admin_project_path(job.project) %td - if job.try(:runner) = runner_link(job.runner) @@ -95,16 +95,16 @@ %td .pull-right - if can?(current_user, :read_build, job) && job.artifacts? - = link_to download_namespace_project_job_artifacts_path(job.project.namespace, job.project, job), rel: 'nofollow', download: '', title: 'Download artifacts', class: 'btn btn-build' do + = link_to download_project_job_artifacts_path(job.project, job), rel: 'nofollow', download: '', title: 'Download artifacts', class: 'btn btn-build' do = icon('download') - if can?(current_user, :update_build, job) - if job.active? - = link_to cancel_namespace_project_job_path(job.project.namespace, job.project, job, return_to: request.original_url), method: :post, title: 'Cancel', class: 'btn btn-build' do + = link_to cancel_project_job_path(job.project, job, return_to: request.original_url), method: :post, title: 'Cancel', class: 'btn btn-build' do = icon('remove', class: 'cred') - elsif allow_retry - if job.playable? && !admin && can?(current_user, :update_build, job) - = link_to play_namespace_project_job_path(job.project.namespace, job.project, job, return_to: request.original_url), method: :post, title: 'Play', class: 'btn btn-build' do + = link_to play_project_job_path(job.project, job, return_to: request.original_url), method: :post, title: 'Play', class: 'btn btn-build' do = custom_icon('icon_play') - elsif job.retryable? - = link_to retry_namespace_project_job_path(job.project.namespace, job.project, job, return_to: request.original_url), method: :post, title: 'Retry', class: 'btn btn-build' do + = link_to retry_project_job_path(job.project, job, return_to: request.original_url), method: :post, title: 'Retry', class: 'btn btn-build' do = icon('repeat') diff --git a/app/views/projects/commit/_change.html.haml b/app/views/projects/commit/_change.html.haml index 2267f123e38..d0a380516f9 100644 --- a/app/views/projects/commit/_change.html.haml +++ b/app/views/projects/commit/_change.html.haml @@ -22,7 +22,7 @@ = label_tag 'start_branch', branch_label, class: 'control-label' .col-sm-10 = hidden_field_tag :start_branch, @project.default_branch, id: 'start_branch' - = dropdown_tag(@project.default_branch, options: { title: s_("BranchSwitcherTitle|Switch branch"), filter: true, placeholder: s_("BranchSwitcherPlaceholder|Search branches"), toggle_class: 'js-project-refs-dropdown dynamic', dropdown_class: 'dropdown-menu-selectable', data: { field_name: "start_branch", selected: @project.default_branch, start_branch: @project.default_branch, refs_url: namespace_project_branches_path(@project.namespace, @project), submit_form_on_click: false } }) + = dropdown_tag(@project.default_branch, options: { title: s_("BranchSwitcherTitle|Switch branch"), filter: true, placeholder: s_("BranchSwitcherPlaceholder|Search branches"), toggle_class: 'js-project-refs-dropdown dynamic', dropdown_class: 'dropdown-menu-selectable', data: { field_name: "start_branch", selected: @project.default_branch, start_branch: @project.default_branch, refs_url: project_branches_path(@project), submit_form_on_click: false } }) - if can?(current_user, :push_code, @project) = render 'shared/new_merge_request_checkbox' diff --git a/app/views/projects/commit/_ci_menu.html.haml b/app/views/projects/commit/_ci_menu.html.haml index 8aed88da38b..f3f11b5b405 100644 --- a/app/views/projects/commit/_ci_menu.html.haml +++ b/app/views/projects/commit/_ci_menu.html.haml @@ -1,10 +1,10 @@ %ul.nav-links.no-top.no-bottom.commit-ci-menu = nav_link(path: 'commit#show') do - = link_to namespace_project_commit_path(@project.namespace, @project, @commit.id) do + = link_to project_commit_path(@project, @commit.id) do Changes %span.badge= @diffs.size - if can?(current_user, :read_pipeline, @project) = nav_link(path: 'commit#pipelines') do - = link_to pipelines_namespace_project_commit_path(@project.namespace, @project, @commit.id) do + = link_to pipelines_project_commit_path(@project, @commit.id) do Pipelines %span.badge= @commit.pipelines.size diff --git a/app/views/projects/commit/_commit_box.html.haml b/app/views/projects/commit/_commit_box.html.haml index 7fe44816bae..572c368990e 100644 --- a/app/views/projects/commit/_commit_box.html.haml +++ b/app/views/projects/commit/_commit_box.html.haml @@ -21,7 +21,7 @@ %span.btn.disabled.btn-grouped.hidden-xs.append-right-10 = icon('comment') = @notes_count - = link_to namespace_project_tree_path(@project.namespace, @project, @commit), class: "btn btn-default append-right-10 hidden-xs hidden-sm" do + = link_to project_tree_path(@project, @commit), class: "btn btn-default append-right-10 hidden-xs hidden-sm" do #{ _('Browse files') } .dropdown.inline %a.btn.btn-default.dropdown-toggle{ data: { toggle: "dropdown" } } @@ -29,22 +29,22 @@ = icon('caret-down') %ul.dropdown-menu.dropdown-menu-align-right %li.visible-xs-block.visible-sm-block - = link_to namespace_project_tree_path(@project.namespace, @project, @commit) do + = link_to project_tree_path(@project, @commit) do _('Browse Files') - unless @commit.has_been_reverted?(current_user) %li.clearfix - = revert_commit_link(@commit, namespace_project_commit_path(@project.namespace, @project, @commit.id), has_tooltip: false) + = revert_commit_link(@commit, project_commit_path(@project, @commit.id), has_tooltip: false) %li.clearfix - = cherry_pick_commit_link(@commit, namespace_project_commit_path(@project.namespace, @project, @commit.id), has_tooltip: false) + = cherry_pick_commit_link(@commit, project_commit_path(@project, @commit.id), has_tooltip: false) - if can_collaborate_with_project? %li.clearfix - = link_to s_("CreateTag|Tag"), new_namespace_project_tag_path(@project.namespace, @project, ref: @commit) + = link_to s_("CreateTag|Tag"), new_project_tag_path(@project, ref: @commit) %li.divider %li.dropdown-header #{ _('Download') } - unless @commit.parents.length > 1 - %li= link_to s_("DownloadCommit|Email Patches"), namespace_project_commit_path(@project.namespace, @project, @commit, format: :patch) - %li= link_to s_("DownloadCommit|Plain Diff"), namespace_project_commit_path(@project.namespace, @project, @commit, format: :diff) + %li= link_to s_("DownloadCommit|Email Patches"), project_commit_path(@project, @commit, format: :patch) + %li= link_to s_("DownloadCommit|Plain Diff"), project_commit_path(@project, @commit, format: :diff) .commit-box %h3.commit-title @@ -59,7 +59,7 @@ = custom_icon("icon_commit") %span.cgray= n_('parent', 'parents', @commit.parents.count) - @commit.parents.each do |parent| - = link_to parent.short_id, namespace_project_commit_path(@project.namespace, @project, parent), class: "commit-sha" + = link_to parent.short_id, project_commit_path(@project, parent), class: "commit-sha" %span.commit-info.branches %i.fa.fa-spinner.fa-spin @@ -67,10 +67,10 @@ - last_pipeline = @commit.last_pipeline .well-segment.pipeline-info .status-icon-container{ class: "ci-status-icon-#{@commit.status}" } - = link_to namespace_project_pipeline_path(@project.namespace, @project, last_pipeline.id) do + = link_to project_pipeline_path(@project, last_pipeline.id) do = ci_icon_for_status(last_pipeline.status) #{ _('Pipeline') } - = link_to "##{last_pipeline.id}", namespace_project_pipeline_path(@project.namespace, @project, last_pipeline.id) + = link_to "##{last_pipeline.id}", project_pipeline_path(@project, last_pipeline.id) = ci_label_for_status(last_pipeline.status) - if last_pipeline.stages_count.nonzero? #{ n_(s_('Pipeline|with stage'), s_('Pipeline|with stages'), last_pipeline.stages_count) } @@ -80,4 +80,4 @@ = time_interval_in_words last_pipeline.duration :javascript - $(".commit-info.branches").load("#{branches_namespace_project_commit_path(@project.namespace, @project, @commit.id)}"); + $(".commit-info.branches").load("#{branches_project_commit_path(@project, @commit.id)}"); diff --git a/app/views/projects/commit/pipelines.html.haml b/app/views/projects/commit/pipelines.html.haml index ac93eac41ac..c66ea873dba 100644 --- a/app/views/projects/commit/pipelines.html.haml +++ b/app/views/projects/commit/pipelines.html.haml @@ -2,4 +2,4 @@ = render 'commit_box' = render 'ci_menu' -= render 'projects/commit/pipelines_list', endpoint: pipelines_namespace_project_commit_path(@project.namespace, @project, @commit.id) += render 'projects/commit/pipelines_list', endpoint: pipelines_project_commit_path(@project, @commit.id) diff --git a/app/views/projects/commits/_commit.atom.builder b/app/views/projects/commits/_commit.atom.builder index 1657fb46163..d806acdda13 100644 --- a/app/views/projects/commits/_commit.atom.builder +++ b/app/views/projects/commits/_commit.atom.builder @@ -1,6 +1,6 @@ xml.entry do - xml.id namespace_project_commit_url(@project.namespace, @project, id: commit.id) - xml.link href: namespace_project_commit_url(@project.namespace, @project, id: commit.id) + xml.id project_commit_url(@project, id: commit.id) + xml.link href: project_commit_url(@project, id: commit.id) xml.title truncate(commit.title, length: 80) xml.updated commit.committed_date.xmlschema xml.media :thumbnail, width: "40", height: "40", url: image_url(avatar_icon(commit.author_email)) diff --git a/app/views/projects/commits/_commit.html.haml b/app/views/projects/commits/_commit.html.haml index 8a4ef5a45b3..1033bad0d49 100644 --- a/app/views/projects/commits/_commit.html.haml +++ b/app/views/projects/commits/_commit.html.haml @@ -16,7 +16,7 @@ .commit-detail .commit-content - = link_to_gfm commit.title, namespace_project_commit_path(project.namespace, project, commit.id), class: "commit-row-message item-title" + = link_to_gfm commit.title, project_commit_path(project, commit.id), class: "commit-row-message item-title" %span.commit-row-message.visible-xs-inline · = commit.short_id @@ -39,6 +39,6 @@ .commit-actions.flex-row.hidden-xs - if commit.status(ref) = render_commit_status(commit, ref: ref) - = link_to commit.short_id, namespace_project_commit_path(project.namespace, project, commit), class: "commit-sha btn btn-transparent" + = link_to commit.short_id, project_commit_path(project, commit), class: "commit-sha btn btn-transparent" = clipboard_button(text: commit.id, title: _("Copy commit SHA to clipboard")) = link_to_browse_code(project, commit) diff --git a/app/views/projects/commits/_commits.html.haml b/app/views/projects/commits/_commits.html.haml index cf8dffc8957..c764e35dd2a 100644 --- a/app/views/projects/commits/_commits.html.haml +++ b/app/views/projects/commits/_commits.html.haml @@ -12,4 +12,4 @@ - if hidden > 0 %li.alert.alert-warning - = n_('%d additional commit has been omitted to prevent performance issues.', '%d additional commits have been omitted to prevent performance issues.', hidden) % number_with_delimiter(hidden) + = n_('%s additional commit has been omitted to prevent performance issues.', '%s additional commits have been omitted to prevent performance issues.', hidden) % number_with_delimiter(hidden) diff --git a/app/views/projects/commits/_head.html.haml b/app/views/projects/commits/_head.html.haml index ebeaab863bc..e1549baef89 100644 --- a/app/views/projects/commits/_head.html.haml +++ b/app/views/projects/commits/_head.html.haml @@ -4,33 +4,33 @@ .nav-links.sub-nav.scrolling-tabs %ul{ class: (container_class) } = nav_link(controller: %w(tree blob blame edit_tree new_tree find_file)) do - = link_to project_files_path(@project) do + = link_to project_tree_path(@project) do #{ _('Files') } = nav_link(controller: [:commit, :commits]) do - = link_to namespace_project_commits_path(@project.namespace, @project, current_ref) do + = link_to project_commits_path(@project, current_ref) do #{ _('Commits') } = nav_link(html_options: {class: branches_tab_class}) do - = link_to namespace_project_branches_path(@project.namespace, @project) do + = link_to project_branches_path(@project) do #{ _('Branches') } = nav_link(controller: [:tags, :releases]) do - = link_to namespace_project_tags_path(@project.namespace, @project) do + = link_to project_tags_path(@project) do #{ _('Tags') } = nav_link(path: 'graphs#show') do - = link_to namespace_project_graph_path(@project.namespace, @project, current_ref) do + = link_to project_graph_path(@project, current_ref) do #{ _('Contributors') } = nav_link(controller: %w(network)) do - = link_to namespace_project_network_path(@project.namespace, @project, current_ref) do + = link_to project_network_path(@project, current_ref) do #{ s_('ProjectNetworkGraph|Graph') } = nav_link(controller: :compare) do - = link_to namespace_project_compare_index_path(@project.namespace, @project, from: @repository.root_ref, to: current_ref) do + = link_to project_compare_index_path(@project, from: @repository.root_ref, to: current_ref) do #{ _('Compare') } = nav_link(path: 'graphs#charts') do - = link_to charts_namespace_project_graph_path(@project.namespace, @project, current_ref) do + = link_to charts_project_graph_path(@project, current_ref) do #{ _('Charts') } diff --git a/app/views/projects/commits/_inline_commit.html.haml b/app/views/projects/commits/_inline_commit.html.haml index 5fb89935467..48cefbe45f2 100644 --- a/app/views/projects/commits/_inline_commit.html.haml +++ b/app/views/projects/commits/_inline_commit.html.haml @@ -1,8 +1,8 @@ %li.commit.inline-commit .commit-row-title - = link_to commit.short_id, namespace_project_commit_path(project.namespace, project, commit), class: "commit-sha" + = link_to commit.short_id, project_commit_path(project, commit), class: "commit-sha" %span.str-truncated - = link_to_gfm commit.title, namespace_project_commit_path(project.namespace, project, commit.id), class: "commit-row-message" + = link_to_gfm commit.title, project_commit_path(project, commit.id), class: "commit-row-message" .pull-right #{time_ago_with_tooltip(commit.committed_date)} diff --git a/app/views/projects/commits/show.atom.builder b/app/views/projects/commits/show.atom.builder index 9cf792e1721..a9b77631474 100644 --- a/app/views/projects/commits/show.atom.builder +++ b/app/views/projects/commits/show.atom.builder @@ -1,7 +1,7 @@ xml.title "#{@project.name}:#{@ref} commits" -xml.link href: namespace_project_commits_url(@project.namespace, @project, @ref, rss_url_options), rel: "self", type: "application/atom+xml" -xml.link href: namespace_project_commits_url(@project.namespace, @project, @ref), rel: "alternate", type: "text/html" -xml.id namespace_project_commits_url(@project.namespace, @project, @ref) +xml.link href: project_commits_url(@project, @ref, rss_url_options), rel: "self", type: "application/atom+xml" +xml.link href: project_commits_url(@project, @ref), rel: "alternate", type: "text/html" +xml.id project_commits_url(@project, @ref) xml.updated @commits.first.committed_date.xmlschema if @commits.any? xml << render(@commits) if @commits.any? diff --git a/app/views/projects/commits/show.html.haml b/app/views/projects/commits/show.html.haml index a824af14171..edebd08dbb5 100644 --- a/app/views/projects/commits/show.html.haml +++ b/app/views/projects/commits/show.html.haml @@ -2,7 +2,7 @@ - page_title _("Commits"), @ref = content_for :meta_tags do - = auto_discovery_link_tag(:atom, namespace_project_commits_url(@project.namespace, @project, @ref, rss_url_options), title: "#{@project.name}:#{@ref} commits") + = auto_discovery_link_tag(:atom, project_commits_url(@project, @ref, rss_url_options), title: "#{@project.name}:#{@ref} commits") - if show_new_nav? - breadcrumbs_extra_links("Repository", project_files_path(@project)) @@ -22,16 +22,16 @@ .tree-controls.hidden-xs.hidden-sm - if @merge_request.present? .control - = link_to _("View open merge request"), namespace_project_merge_request_path(@project.namespace, @project, @merge_request), class: 'btn' + = link_to _("View open merge request"), project_merge_request_path(@project, @merge_request), class: 'btn' - elsif create_mr_button?(@repository.root_ref, @ref) .control = link_to _("Create merge request"), create_mr_path(@repository.root_ref, @ref), class: 'btn btn-success' .control - = form_tag(namespace_project_commits_path(@project.namespace, @project, @id), method: :get, class: 'commits-search-form') do + = form_tag(project_commits_path(@project, @id), method: :get, class: 'commits-search-form') do = search_field_tag :search, params[:search], { placeholder: _('Filter by commit message'), id: 'commits-search', class: 'form-control search-text-input input-short', spellcheck: false } .control - = link_to namespace_project_commits_path(@project.namespace, @project, @ref, rss_url_options), title: _("Commits feed"), class: 'btn' do + = link_to project_commits_path(@project, @ref, rss_url_options), title: _("Commits feed"), class: 'btn' do = icon("rss") %div{ id: dom_id(@project) } diff --git a/app/views/projects/compare/_form.html.haml b/app/views/projects/compare/_form.html.haml index adb724c1b8d..94b7db5eb25 100644 --- a/app/views/projects/compare/_form.html.haml +++ b/app/views/projects/compare/_form.html.haml @@ -1,4 +1,4 @@ -= form_tag namespace_project_compare_index_path(@project.namespace, @project), method: :post, class: 'form-inline js-requires-input' do += form_tag project_compare_index_path(@project), method: :post, class: 'form-inline js-requires-input' do .clearfix - if params[:to] && params[:from] .compare-switch-container @@ -7,7 +7,7 @@ .input-group.inline-input-group %span.input-group-addon from = hidden_field_tag :from, params[:from] - = button_tag type: 'button', title: params[:from], class: "form-control compare-dropdown-toggle js-compare-dropdown has-tooltip git-revision-dropdown-toggle", required: true, data: { refs_url: refs_namespace_project_path(@project.namespace, @project), toggle: "dropdown", target: ".js-compare-from-dropdown", selected: params[:from], field_name: :from } do + = button_tag type: 'button', title: params[:from], class: "form-control compare-dropdown-toggle js-compare-dropdown has-tooltip git-revision-dropdown-toggle", required: true, data: { refs_url: refs_project_path(@project), toggle: "dropdown", target: ".js-compare-from-dropdown", selected: params[:from], field_name: :from } do .dropdown-toggle-text.str-truncated= params[:from] || 'Select branch/tag' = render 'shared/ref_dropdown' .compare-ellipsis.inline ... @@ -15,12 +15,12 @@ .input-group.inline-input-group %span.input-group-addon to = hidden_field_tag :to, params[:to] - = button_tag type: 'button', title: params[:to], class: "form-control compare-dropdown-toggle js-compare-dropdown has-tooltip git-revision-dropdown-toggle", required: true, data: { refs_url: refs_namespace_project_path(@project.namespace, @project), toggle: "dropdown", target: ".js-compare-to-dropdown", selected: params[:to], field_name: :to } do + = button_tag type: 'button', title: params[:to], class: "form-control compare-dropdown-toggle js-compare-dropdown has-tooltip git-revision-dropdown-toggle", required: true, data: { refs_url: refs_project_path(@project), toggle: "dropdown", target: ".js-compare-to-dropdown", selected: params[:to], field_name: :to } do .dropdown-toggle-text.str-truncated= params[:to] || 'Select branch/tag' = render 'shared/ref_dropdown' = button_tag "Compare", class: "btn btn-create commits-compare-btn" - if @merge_request.present? - = link_to "View open merge request", namespace_project_merge_request_path(@project.namespace, @project, @merge_request), class: 'prepend-left-10 btn' + = link_to "View open merge request", project_merge_request_path(@project, @merge_request), class: 'prepend-left-10 btn' - elsif create_mr_button? = link_to "Create merge request", create_mr_path, class: 'prepend-left-10 btn' diff --git a/app/views/projects/deploy_keys/_index.html.haml b/app/views/projects/deploy_keys/_index.html.haml index cb98ce04430..45985a5ecef 100644 --- a/app/views/projects/deploy_keys/_index.html.haml +++ b/app/views/projects/deploy_keys/_index.html.haml @@ -12,4 +12,4 @@ Create a new deploy key for this project = render @deploy_keys.form_partial_path %hr - #js-deploy-keys{ data: { endpoint: namespace_project_deploy_keys_path } } + #js-deploy-keys{ data: { endpoint: project_deploy_keys_path(@project) } } diff --git a/app/views/projects/deploy_keys/edit.html.haml b/app/views/projects/deploy_keys/edit.html.haml index 37219f8d7ae..cd910b82b57 100644 --- a/app/views/projects/deploy_keys/edit.html.haml +++ b/app/views/projects/deploy_keys/edit.html.haml @@ -7,4 +7,4 @@ = render partial: 'shared/deploy_keys/form', locals: { form: f, deploy_key: @deploy_key } .form-actions = f.submit 'Save changes', class: 'btn-save btn' - = link_to 'Cancel', namespace_project_settings_repository_path(@project.namespace, @project), class: 'btn btn-cancel' + = link_to 'Cancel', project_settings_repository_path(@project), class: 'btn btn-cancel' diff --git a/app/views/projects/deployments/_commit.html.haml b/app/views/projects/deployments/_commit.html.haml index 4502c397d29..4c22166c256 100644 --- a/app/views/projects/deployments/_commit.html.haml +++ b/app/views/projects/deployments/_commit.html.haml @@ -6,12 +6,12 @@ = link_to deployment.ref, project_ref_path(@project, deployment.ref), class: "ref-name" .icon-container.commit-icon = custom_icon("icon_commit") - = link_to deployment.short_sha, namespace_project_commit_path(@project.namespace, @project, deployment.sha), class: "commit-sha" + = link_to deployment.short_sha, project_commit_path(@project, deployment.sha), class: "commit-sha" %p.commit-title.flex-truncate-parent %span.flex-truncate-child - if commit_title = deployment.commit_title = author_avatar(deployment.commit, size: 20) - = link_to_gfm commit_title, namespace_project_commit_path(@project.namespace, @project, deployment.sha), class: "commit-row-message" + = link_to_gfm commit_title, project_commit_path(@project, deployment.sha), class: "commit-row-message" - else Cant find HEAD commit for this branch diff --git a/app/views/projects/diffs/_warning.html.haml b/app/views/projects/diffs/_warning.html.haml index 402c18c447e..da34a83d8e0 100644 --- a/app/views/projects/diffs/_warning.html.haml +++ b/app/views/projects/diffs/_warning.html.haml @@ -3,8 +3,8 @@ Too many changes to show. .pull-right - if current_controller?(:commit) - = link_to "Plain diff", namespace_project_commit_path(@project.namespace, @project, @commit, format: :diff), class: "btn btn-sm" - = link_to "Email patch", namespace_project_commit_path(@project.namespace, @project, @commit, format: :patch), class: "btn btn-sm" + = link_to "Plain diff", project_commit_path(@project, @commit, format: :diff), class: "btn btn-sm" + = link_to "Email patch", project_commit_path(@project, @commit, format: :patch), class: "btn btn-sm" - elsif current_controller?('projects/merge_requests/diffs') && @merge_request&.persisted? = link_to "Plain diff", merge_request_path(@merge_request, format: :diff), class: "btn btn-sm" = link_to "Email patch", merge_request_path(@merge_request, format: :patch), class: "btn btn-sm" diff --git a/app/views/projects/diffs/viewers/_image.html.haml b/app/views/projects/diffs/viewers/_image.html.haml index 19d08181223..33d3dcbeafa 100644 --- a/app/views/projects/diffs/viewers/_image.html.haml +++ b/app/views/projects/diffs/viewers/_image.html.haml @@ -15,7 +15,7 @@ .two-up.view %span.wrap .frame.deleted - %a{ href: namespace_project_blob_path(@project.namespace, @project, tree_join(diff_file.old_content_sha, diff_file.old_path)) } + %a{ href: project_blob_path(@project, tree_join(diff_file.old_content_sha, diff_file.old_path)) } %img{ src: old_blob_raw_path, alt: diff_file.old_path } %p.image-info.hide %span.meta-filesize= number_to_human_size(old_blob.size) @@ -27,7 +27,7 @@ %span.meta-height %span.wrap .frame.added - %a{ href: namespace_project_blob_path(@project.namespace, @project, tree_join(diff_file.content_sha, diff_file.new_path)) } + %a{ href: project_blob_path(@project, tree_join(diff_file.content_sha, diff_file.new_path)) } %img{ src: blob_raw_path, alt: diff_file.new_path } %p.image-info.hide %span.meta-filesize= number_to_human_size(blob.size) diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml index 61c414b2e13..9f4d0faf3a2 100644 --- a/app/views/projects/edit.html.haml +++ b/app/views/projects/edit.html.haml @@ -135,7 +135,7 @@ .help-block The maximum file size allowed is 200KB. - if @project.avatar? %hr - = link_to 'Remove avatar', namespace_project_avatar_path(@project.namespace, @project), data: { confirm: "Project avatar will be removed. Are you sure?"}, method: :delete, class: "btn btn-remove btn-sm remove-avatar" + = link_to 'Remove avatar', project_avatar_path(@project), data: { confirm: "Project avatar will be removed. Are you sure?"}, method: :delete, class: "btn btn-remove btn-sm remove-avatar" = f.submit 'Save changes', class: "btn btn-save" .row.prepend-top-default @@ -149,7 +149,7 @@ Runs a number of housekeeping tasks within the current repository, such as compressing file revisions and removing unreachable objects. .col-lg-8 - = link_to 'Housekeeping', housekeeping_namespace_project_path(@project.namespace, @project), + = link_to 'Housekeeping', housekeeping_project_path(@project), method: :post, class: "btn btn-default" %hr .row.prepend-top-default @@ -165,12 +165,12 @@ .col-lg-8 - if @project.export_project_path - = link_to 'Download export', download_export_namespace_project_path(@project.namespace, @project), + = link_to 'Download export', download_export_project_path(@project), rel: 'nofollow', download: '', method: :get, class: "btn btn-default" - = link_to 'Generate new export', generate_new_export_namespace_project_path(@project.namespace, @project), + = link_to 'Generate new export', generate_new_export_project_path(@project), method: :post, class: "btn btn-default" - else - = link_to 'Export project', export_namespace_project_path(@project.namespace, @project), + = link_to 'Export project', export_project_path(@project), method: :post, class: "btn btn-default" .bs-callout.bs-callout-info @@ -208,13 +208,13 @@ - if @project.archived? %p %strong Once active this project shows up in the search and on the dashboard. - = link_to 'Unarchive project', unarchive_namespace_project_path(@project.namespace, @project), + = link_to 'Unarchive project', unarchive_project_path(@project), data: { confirm: "Are you sure that you want to unarchive this project?\nWhen this project is unarchived it is active and can be committed to again." }, method: :post, class: "btn btn-success" - else %p %strong Archived projects cannot be committed to! - = link_to 'Archive project', archive_namespace_project_path(@project.namespace, @project), + = link_to 'Archive project', archive_project_path(@project), data: { confirm: "Are you sure that you want to archive this project?\nAn archived project cannot be committed to." }, method: :post, class: "btn btn-warning" %hr @@ -253,7 +253,7 @@ %p.append-bottom-0 Please select the group you want to transfer this project to in the dropdown to the right. .col-lg-8 - = form_for([@project.namespace.becomes(Namespace), @project], url: transfer_namespace_project_path(@project.namespace, @project), method: :put, remote: true, html: { class: 'js-project-transfer-form' } ) do |f| + = form_for([@project.namespace.becomes(Namespace), @project], url: transfer_project_path(@project), method: :put, remote: true, html: { class: 'js-project-transfer-form' } ) do |f| .form-group = label_tag :new_namespace_id, nil, class: 'label-light' do %span Select a new namespace @@ -277,7 +277,7 @@ = succeed "." do = link_to @project.forked_from_project.name_with_namespace, project_path(@project.forked_from_project) .col-lg-8 - = form_for([@project.namespace.becomes(Namespace), @project], url: remove_fork_namespace_project_path(@project.namespace, @project), method: :delete, remote: true, html: { class: 'transfer-project' }) do |f| + = form_for([@project.namespace.becomes(Namespace), @project], url: remove_fork_project_path(@project), method: :delete, remote: true, html: { class: 'transfer-project' }) do |f| %p %strong Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source. = button_to 'Remove fork relationship', '#', class: "btn btn-remove js-confirm-danger", data: { "confirm-danger-message" => remove_fork_project_message(@project) } @@ -290,7 +290,7 @@ %p.append-bottom-0 Removing the project will delete its repository and all related resources including issues, merge requests etc. .col-lg-8 - = form_tag(namespace_project_path(@project.namespace, @project), method: :delete) do + = form_tag(project_path(@project), method: :delete) do %p %strong Removed projects cannot be restored! = button_to 'Remove project', '#', class: "btn btn-remove js-confirm-danger", data: { "confirm-danger-message" => remove_project_message(@project) } diff --git a/app/views/projects/environments/_form.html.haml b/app/views/projects/environments/_form.html.haml index 6d040f5cfe6..1605f3a3351 100644 --- a/app/views/projects/environments/_form.html.haml +++ b/app/views/projects/environments/_form.html.haml @@ -19,4 +19,4 @@ .form-actions = f.submit 'Save', class: 'btn btn-save' - = link_to 'Cancel', namespace_project_environments_path(@project.namespace, @project), class: 'btn btn-cancel' + = link_to 'Cancel', project_environments_path(@project), class: 'btn btn-cancel' diff --git a/app/views/projects/environments/_stop.html.haml b/app/views/projects/environments/_stop.html.haml index 14a2d627203..c35f9af2873 100644 --- a/app/views/projects/environments/_stop.html.haml +++ b/app/views/projects/environments/_stop.html.haml @@ -1,5 +1,5 @@ - if can?(current_user, :create_deployment, environment) && environment.stop_action? .inline - = link_to stop_namespace_project_environment_path(@project.namespace, @project, environment), method: :post, + = link_to stop_project_environment_path(@project, environment), method: :post, class: 'btn stop-env-link', rel: 'nofollow', data: { confirm: 'Are you sure you want to stop this environment?' } do = icon('stop', class: 'stop-env-icon') diff --git a/app/views/projects/environments/_terminal_button.html.haml b/app/views/projects/environments/_terminal_button.html.haml index 97de9c95de7..a6201bdbc42 100644 --- a/app/views/projects/environments/_terminal_button.html.haml +++ b/app/views/projects/environments/_terminal_button.html.haml @@ -1,3 +1,3 @@ - if environment.has_terminals? && can?(current_user, :admin_environment, @project) - = link_to terminal_namespace_project_environment_path(@project.namespace, @project, environment), class: 'btn terminal-button' do + = link_to terminal_project_environment_path(@project, environment), class: 'btn terminal-button' do = icon('terminal') diff --git a/app/views/projects/environments/index.html.haml b/app/views/projects/environments/index.html.haml index 80d2b6f5d95..30cdbc5ae04 100644 --- a/app/views/projects/environments/index.html.haml +++ b/app/views/projects/environments/index.html.haml @@ -12,6 +12,6 @@ "can-create-environment" => can?(current_user, :create_environment, @project).to_s, "project-environments-path" => project_environments_path(@project), "project-stopped-environments-path" => project_environments_path(@project, scope: :stopped), - "new-environment-path" => new_namespace_project_environment_path(@project.namespace, @project), + "new-environment-path" => new_project_environment_path(@project), "help-page-path" => help_page_path("ci/environments"), "css-class" => container_class } } diff --git a/app/views/projects/environments/metrics.html.haml b/app/views/projects/environments/metrics.html.haml index c5722cf5997..e9e1ad9ef30 100644 --- a/app/views/projects/environments/metrics.html.haml +++ b/app/views/projects/environments/metrics.html.haml @@ -10,12 +10,12 @@ .top-area .row .col-sm-6 - %h3.page-title + %h3 Environment: = link_to @environment.name, environment_path(@environment) - #prometheus-graphs{ data: { "settings-path": edit_namespace_project_service_path(@project.namespace, @project, 'prometheus'), + #prometheus-graphs{ data: { "settings-path": edit_project_service_path(@project, 'prometheus'), "documentation-path": help_page_path('administration/monitoring/prometheus/index.md'), - "additional-metrics": additional_metrics_namespace_project_environment_path(@project.namespace, @project, @environment, format: :json), - "has-metrics": "#{@environment.has_metrics?}", deployment_endpoint: namespace_project_environment_deployments_path(@project.namespace, @project, @environment, format: :json) } } + "additional-metrics": additional_metrics_project_environment_path(@project, @environment, format: :json), + "has-metrics": "#{@environment.has_metrics?}", deployment_endpoint: project_environment_deployments_path(@project, @environment, format: :json) } } diff --git a/app/views/projects/environments/show.html.haml b/app/views/projects/environments/show.html.haml index 31e2bb11ce8..0ce0f5465fc 100644 --- a/app/views/projects/environments/show.html.haml +++ b/app/views/projects/environments/show.html.haml @@ -12,9 +12,9 @@ = render 'projects/environments/external_url', environment: @environment = render 'projects/environments/metrics_button', environment: @environment - if can?(current_user, :update_environment, @environment) - = link_to 'Edit', edit_namespace_project_environment_path(@project.namespace, @project, @environment), class: 'btn' + = link_to 'Edit', edit_project_environment_path(@project, @environment), class: 'btn' - if can?(current_user, :stop_environment, @environment) - = link_to 'Stop', stop_namespace_project_environment_path(@project.namespace, @project, @environment), data: { confirm: 'Are you sure you want to stop this environment?' }, class: 'btn btn-danger', method: :post + = link_to 'Stop', stop_project_environment_path(@project, @environment), data: { confirm: 'Are you sure you want to stop this environment?' }, class: 'btn btn-danger', method: :post .environments-container - if @deployments.blank? diff --git a/app/views/projects/environments/terminal.html.haml b/app/views/projects/environments/terminal.html.haml index 4c4aa0baff3..464135b5ac7 100644 --- a/app/views/projects/environments/terminal.html.haml +++ b/app/views/projects/environments/terminal.html.haml @@ -22,4 +22,4 @@ = render 'projects/deployments/actions', deployment: @environment.last_deployment .terminal-container{ class: container_class } - #terminal{ data: { project_path: "#{terminal_namespace_project_environment_path(@project.namespace, @project, @environment)}.ws" } } + #terminal{ data: { project_path: "#{terminal_project_environment_path(@project, @environment)}.ws" } } diff --git a/app/views/projects/find_file/show.html.haml b/app/views/projects/find_file/show.html.haml index 8a409541fe5..e3bf48ee47f 100644 --- a/app/views/projects/find_file/show.html.haml +++ b/app/views/projects/find_file/show.html.haml @@ -7,7 +7,7 @@ = render 'shared/ref_switcher', destination: 'find_file', path: @path %ul.breadcrumb.repo-breadcrumb %li - = link_to namespace_project_tree_path(@project.namespace, @project, @ref) do + = link_to project_tree_path(@project, @ref) do = @project.path %li.file-finder %input#file_find.form-control.file-finder-input{ type: "text", placeholder: _('Find by path'), autocomplete: 'off' } @@ -20,8 +20,8 @@ :javascript var projectFindFile = new ProjectFindFile($(".file-finder-holder"), { - url: "#{escape_javascript(namespace_project_files_path(@project.namespace, @project, @ref, @options.merge(format: :json)))}", - treeUrl: "#{escape_javascript(namespace_project_tree_path(@project.namespace, @project, @ref))}", - blobUrlTemplate: "#{escape_javascript(namespace_project_blob_path(@project.namespace, @project, @id || @commit.id))}" + url: "#{escape_javascript(project_files_path(@project, @ref, @options.merge(format: :json)))}", + treeUrl: "#{escape_javascript(project_tree_path(@project, @ref))}", + blobUrlTemplate: "#{escape_javascript(project_blob_path(@project, @id || @commit.id))}" }); new ShortcutsFindFile(projectFindFile); diff --git a/app/views/projects/forks/error.html.haml b/app/views/projects/forks/error.html.haml index 524b77783ef..d365bcd4ecc 100644 --- a/app/views/projects/forks/error.html.haml +++ b/app/views/projects/forks/error.html.haml @@ -20,6 +20,6 @@ = error %p - = link_to new_namespace_project_fork_path(@project.namespace, @project), title: "Fork", class: "btn" do + = link_to new_project_fork_path(@project), title: "Fork", class: "btn" do %i.fa.fa-code-fork Try to fork again diff --git a/app/views/projects/forks/index.html.haml b/app/views/projects/forks/index.html.haml index f4aa523b32d..111cbcda266 100644 --- a/app/views/projects/forks/index.html.haml +++ b/app/views/projects/forks/index.html.haml @@ -34,7 +34,7 @@ = custom_icon('icon_fork') %span Fork - else - = link_to new_namespace_project_fork_path(@project.namespace, @project), title: "Fork project", class: 'btn btn-new' do + = link_to new_project_fork_path(@project), title: "Fork project", class: 'btn btn-new' do = custom_icon('icon_fork') %span Fork diff --git a/app/views/projects/forks/new.html.haml b/app/views/projects/forks/new.html.haml index 5242bc72b71..0f36e1a7353 100644 --- a/app/views/projects/forks/new.html.haml +++ b/app/views/projects/forks/new.html.haml @@ -30,7 +30,7 @@ = namespace.human_name - else .fork-thumbnail - = link_to namespace_project_forks_path(@project.namespace, @project, namespace_key: namespace.id), method: "POST" do + = link_to project_forks_path(@project, namespace_key: namespace.id), method: "POST" do - if /no_((\w*)_)*avatar/.match(avatar) .no-avatar = icon 'question' diff --git a/app/views/projects/generic_commit_statuses/_generic_commit_status.html.haml b/app/views/projects/generic_commit_statuses/_generic_commit_status.html.haml index b23bbadbdb4..b98dc09534f 100644 --- a/app/views/projects/generic_commit_statuses/_generic_commit_status.html.haml +++ b/app/views/projects/generic_commit_statuses/_generic_commit_status.html.haml @@ -20,14 +20,14 @@ - if generic_commit_status.ref .icon-container = generic_commit_status.tags.any? ? icon('tag') : icon('code-fork') - = link_to generic_commit_status.ref, namespace_project_commits_path(generic_commit_status.project.namespace, generic_commit_status.project, generic_commit_status.ref) + = link_to generic_commit_status.ref, project_commits_path(generic_commit_status.project, generic_commit_status.ref) - else .light none .icon-container.commit-icon = custom_icon("icon_commit") - if commit_sha - = link_to generic_commit_status.short_sha, namespace_project_commit_path(generic_commit_status.project.namespace, generic_commit_status.project, generic_commit_status.sha), class: "commit-sha" + = link_to generic_commit_status.short_sha, project_commit_path(generic_commit_status.project, generic_commit_status.sha), class: "commit-sha" - if retried = icon('warning', class: 'text-warning has-tooltip', title: 'Status was retried.') @@ -53,7 +53,7 @@ - if admin %td - if generic_commit_status.project - = link_to generic_commit_status.project.name_with_namespace, admin_namespace_project_path(generic_commit_status.project.namespace, generic_commit_status.project) + = link_to generic_commit_status.project.name_with_namespace, admin_project_path(generic_commit_status.project) %td - if generic_commit_status.try(:runner) = runner_link(generic_commit_status.runner) diff --git a/app/views/projects/graphs/show.html.haml b/app/views/projects/graphs/show.html.haml index 67383a23423..1b4b12ba517 100644 --- a/app/views/projects/graphs/show.html.haml +++ b/app/views/projects/graphs/show.html.haml @@ -40,7 +40,7 @@ :javascript $.ajax({ type: "GET", - url: "#{namespace_project_graph_path(@project.namespace, @project, current_ref, format: :json)}", + url: "#{project_graph_path(@project, current_ref, format: :json)}", dataType: "json", success: function (data) { var graph = new ContributorsStatGraph(); diff --git a/app/views/projects/hook_logs/_index.html.haml b/app/views/projects/hook_logs/_index.html.haml index 6962b223451..05b06cfc8b2 100644 --- a/app/views/projects/hook_logs/_index.html.haml +++ b/app/views/projects/hook_logs/_index.html.haml @@ -28,7 +28,7 @@ %td.light = time_ago_with_tooltip(hook_log.created_at) %td - = link_to 'View details', namespace_project_hook_hook_log_path(project.namespace, project, hook, hook_log) + = link_to 'View details', project_hook_hook_log_path(project, hook, hook_log) = paginate hook_logs, theme: 'gitlab' diff --git a/app/views/projects/hook_logs/show.html.haml b/app/views/projects/hook_logs/show.html.haml index 2eabe92f8eb..ab5a7b117d7 100644 --- a/app/views/projects/hook_logs/show.html.haml +++ b/app/views/projects/hook_logs/show.html.haml @@ -6,6 +6,6 @@ Request details .col-lg-9 - = link_to 'Resend Request', retry_namespace_project_hook_hook_log_path(@project.namespace, @project, @hook, @hook_log), class: "btn btn-default pull-right prepend-left-10" + = link_to 'Resend Request', retry_project_hook_hook_log_path(@project, @hook, @hook_log), class: "btn btn-default pull-right prepend-left-10" = render partial: 'shared/hook_logs/content', locals: { hook_log: @hook_log } diff --git a/app/views/projects/hooks/edit.html.haml b/app/views/projects/hooks/edit.html.haml index fd382c1d63f..4944e0c8041 100644 --- a/app/views/projects/hooks/edit.html.haml +++ b/app/views/projects/hooks/edit.html.haml @@ -9,14 +9,13 @@ #{link_to 'Webhooks', help_page_path('user/project/integrations/webhooks')} can be used for binding events when something is happening within the project. .col-lg-9.append-bottom-default - = form_for [@project.namespace.becomes(Namespace), @project, @hook], as: :hook, url: namespace_project_hook_path do |f| + = form_for [@project.namespace.becomes(Namespace), @project, @hook], as: :hook, url: project_hook_path(@project, @hook) do |f| = render partial: 'shared/web_hooks/form', locals: { form: f, hook: @hook } = f.submit 'Save changes', class: 'btn btn-create' - = link_to 'Test hook', test_namespace_project_hook_path(@project.namespace, @project, @hook), class: 'btn btn-default' - = link_to 'Remove', namespace_project_hook_path(@project.namespace, @project, @hook), method: :delete, class: 'btn btn-remove pull-right', data: { confirm: 'Are you sure?' } + = link_to 'Test hook', test_project_hook_path(@project, @hook), class: 'btn btn-default' + = link_to 'Remove', project_hook_path(@project, @hook), method: :delete, class: 'btn btn-remove pull-right', data: { confirm: 'Are you sure?' } %hr = render partial: 'projects/hook_logs/index', locals: { hook: @hook, hook_logs: @hook_logs, project: @project } - diff --git a/app/views/projects/imports/new.html.haml b/app/views/projects/imports/new.html.haml index 25a87411cac..778ff91362d 100644 --- a/app/views/projects/imports/new.html.haml +++ b/app/views/projects/imports/new.html.haml @@ -12,7 +12,7 @@ :preserve #{h(sanitize_repo_path(@project, @project.import_error))} -= form_for @project, url: namespace_project_import_path(@project.namespace, @project), method: :post, html: { class: 'form-horizontal' } do |f| += form_for @project, url: project_import_path(@project), method: :post, html: { class: 'form-horizontal' } do |f| = render "shared/import_form", f: f .form-actions diff --git a/app/views/projects/issues/_head.html.haml b/app/views/projects/issues/_head.html.haml index 7a188cb6445..e9f21594a71 100644 --- a/app/views/projects/issues/_head.html.haml +++ b/app/views/projects/issues/_head.html.haml @@ -5,29 +5,29 @@ %ul{ class: (container_class) } - if project_nav_tab?(:issues) && !current_controller?(:merge_requests) = nav_link(controller: :issues) do - = link_to namespace_project_issues_path(@project.namespace, @project), title: 'Issues' do + = link_to project_issues_path(@project), title: 'Issues' do %span List = nav_link(controller: :boards) do - = link_to namespace_project_boards_path(@project.namespace, @project), title: 'Board' do + = link_to project_boards_path(@project), title: 'Board' do %span Board - if project_nav_tab?(:merge_requests) && current_controller?(:merge_requests) = nav_link(controller: :merge_requests) do - = link_to namespace_project_merge_requests_path(@project.namespace, @project), title: 'Merge Requests' do + = link_to project_merge_requests_path(@project), title: 'Merge Requests' do %span Merge Requests - if project_nav_tab? :labels = nav_link(controller: :labels) do - = link_to namespace_project_labels_path(@project.namespace, @project), title: 'Labels' do + = link_to project_labels_path(@project), title: 'Labels' do %span Labels - if project_nav_tab? :milestones = nav_link(controller: :milestones) do - = link_to namespace_project_milestones_path(@project.namespace, @project), title: 'Milestones' do + = link_to project_milestones_path(@project), title: 'Milestones' do %span Milestones diff --git a/app/views/projects/issues/_issue.html.haml b/app/views/projects/issues/_issue.html.haml index 6a0d96f50cd..7dc35be57a6 100644 --- a/app/views/projects/issues/_issue.html.haml +++ b/app/views/projects/issues/_issue.html.haml @@ -24,7 +24,7 @@ - if issue.milestone %span.issuable-milestone.hidden-xs - = link_to namespace_project_issues_path(issue.project.namespace, issue.project, milestone_title: issue.milestone.title) do + = link_to project_issues_path(issue.project, milestone_title: issue.milestone.title) do = icon('clock-o') = issue.milestone.title - if issue.due_date diff --git a/app/views/projects/issues/_issue_by_email.html.haml b/app/views/projects/issues/_issue_by_email.html.haml index 35b7d1b920c..264032a3a31 100644 --- a/app/views/projects/issues/_issue_by_email.html.haml +++ b/app/views/projects/issues/_issue_by_email.html.haml @@ -30,5 +30,5 @@ Anyone who gets ahold of it can create issues as if they were you. You should - = link_to 'reset it', new_issue_address_namespace_project_path(@project.namespace, @project), class: 'incoming-email-token-reset' + = link_to 'reset it', new_issue_address_project_path(@project), class: 'incoming-email-token-reset' if that ever happens. diff --git a/app/views/projects/issues/_merge_requests.html.haml b/app/views/projects/issues/_merge_requests.html.haml index bda52fe461c..6a567487514 100644 --- a/app/views/projects/issues/_merge_requests.html.haml +++ b/app/views/projects/issues/_merge_requests.html.haml @@ -18,7 +18,7 @@ - unless @issue.project.id == merge_request.target_project.id in - project = merge_request.target_project - = link_to project.name_with_namespace, namespace_project_path(project.namespace, project) + = link_to project.name_with_namespace, project_path(project) - if merge_request.merged? %span.merge-request-status.prepend-left-10.merged diff --git a/app/views/projects/issues/_nav_btns.html.haml b/app/views/projects/issues/_nav_btns.html.haml index 698959ec74f..756faf4625e 100644 --- a/app/views/projects/issues/_nav_btns.html.haml +++ b/app/views/projects/issues/_nav_btns.html.haml @@ -2,10 +2,9 @@ = icon('rss') - if @can_bulk_update = button_tag "Edit Issues", class: "btn btn-default append-right-10 js-bulk-update-toggle" -= link_to "New issue", new_namespace_project_issue_path(@project.namespace, - @project, - issue: { assignee_id: issues_finder.assignee.try(:id), - milestone_id: issues_finder.milestones.first.try(:id) }), - class: "btn btn-new", - title: "New issue", - id: "new_issue_link" += link_to "New issue", new_project_issue_path(@project, + issue: { assignee_id: issues_finder.assignee.try(:id), + milestone_id: issues_finder.milestones.first.try(:id) }), + class: "btn btn-new", + title: "New issue", + id: "new_issue_link" diff --git a/app/views/projects/issues/_new_branch.html.haml b/app/views/projects/issues/_new_branch.html.haml index dba092c8844..e1b4a49850a 100644 --- a/app/views/projects/issues/_new_branch.html.haml +++ b/app/views/projects/issues/_new_branch.html.haml @@ -1,5 +1,5 @@ - if can?(current_user, :push_code, @project) - .create-mr-dropdown-wrap{ data: { can_create_path: can_create_branch_namespace_project_issue_path(@project.namespace, @project, @issue), create_mr_path: create_merge_request_namespace_project_issue_path(@project.namespace, @project, @issue), create_branch_path: namespace_project_branches_path(@project.namespace, @project, branch_name: @issue.to_branch_name, issue_iid: @issue.iid) } } + .create-mr-dropdown-wrap{ data: { can_create_path: can_create_branch_project_issue_path(@project, @issue), create_mr_path: create_merge_request_project_issue_path(@project, @issue), create_branch_path: project_branches_path(@project, branch_name: @issue.to_branch_name, issue_iid: @issue.iid) } } .btn-group.unavailable %button.btn.btn-grouped{ type: 'button', disabled: 'disabled' } = icon('spinner', class: 'fa-spin') diff --git a/app/views/projects/issues/_related_branches.html.haml b/app/views/projects/issues/_related_branches.html.haml index 8c9f6f3b4df..1df38db9fd4 100644 --- a/app/views/projects/issues/_related_branches.html.haml +++ b/app/views/projects/issues/_related_branches.html.haml @@ -11,4 +11,4 @@ = render_pipeline_status(pipeline) %span.related-branch-info %strong - = link_to branch, namespace_project_compare_path(@project.namespace, @project, from: @project.default_branch, to: branch), class: "ref-name" + = link_to branch, project_compare_path(@project, from: @project.default_branch, to: branch), class: "ref-name" diff --git a/app/views/projects/issues/index.atom.builder b/app/views/projects/issues/index.atom.builder index 61346884346..4029926f373 100644 --- a/app/views/projects/issues/index.atom.builder +++ b/app/views/projects/issues/index.atom.builder @@ -1,7 +1,7 @@ xml.title "#{@project.name} issues" xml.link href: url_for(params), rel: "self", type: "application/atom+xml" -xml.link href: namespace_project_issues_url(@project.namespace, @project), rel: "alternate", type: "text/html" -xml.id namespace_project_issues_url(@project.namespace, @project) +xml.link href: project_issues_url(@project), rel: "alternate", type: "text/html" +xml.id project_issues_url(@project) xml.updated @issues.first.updated_at.xmlschema if @issues.reorder(nil).any? xml << render(partial: 'issues/issue', collection: @issues) if @issues.reorder(nil).any? diff --git a/app/views/projects/issues/index.html.haml b/app/views/projects/issues/index.html.haml index 89ac5ff7128..aacb057840d 100644 --- a/app/views/projects/issues/index.html.haml +++ b/app/views/projects/issues/index.html.haml @@ -33,4 +33,4 @@ - if new_issue_email = render 'issue_by_email', email: new_issue_email - else - = render 'shared/empty_states/issues', button_path: new_namespace_project_issue_path(@project.namespace, @project) + = render 'shared/empty_states/issues', button_path: new_project_issue_path(@project) diff --git a/app/views/projects/issues/show.html.haml b/app/views/projects/issues/show.html.haml index d909b0bfbbd..cf8493faba8 100644 --- a/app/views/projects/issues/show.html.haml +++ b/app/views/projects/issues/show.html.haml @@ -31,26 +31,26 @@ %ul - if can_update_issue %li - = link_to 'Edit', edit_namespace_project_issue_path(@project.namespace, @project, @issue), class: 'issuable-edit' + = link_to 'Edit', edit_project_issue_path(@project, @issue), class: 'issuable-edit' %li = link_to 'Close issue', issue_path(@issue, issue: { state_event: :close }, format: 'json'), class: "btn-close #{issue_button_visibility(@issue, true)}", title: 'Close issue' %li = link_to 'Reopen issue', issue_path(@issue, issue: { state_event: :reopen }, format: 'json'), class: "btn-reopen #{issue_button_visibility(@issue, false)}", title: 'Reopen issue' - if can_report_spam %li - = link_to 'Submit as spam', mark_as_spam_namespace_project_issue_path(@project.namespace, @project, @issue), method: :post, class: 'btn-spam', title: 'Submit as spam' + = link_to 'Submit as spam', mark_as_spam_project_issue_path(@project, @issue), method: :post, class: 'btn-spam', title: 'Submit as spam' - if can_update_issue || can_report_spam %li.divider %li - = link_to 'New issue', new_namespace_project_issue_path(@project.namespace, @project), title: 'New issue', id: 'new_issue_link' + = link_to 'New issue', new_project_issue_path(@project), title: 'New issue', id: 'new_issue_link' - if can_update_issue - = link_to 'Edit', edit_namespace_project_issue_path(@project.namespace, @project, @issue), class: 'hidden-xs hidden-sm btn btn-grouped issuable-edit' + = link_to 'Edit', edit_project_issue_path(@project, @issue), class: 'hidden-xs hidden-sm btn btn-grouped issuable-edit' = link_to 'Close issue', issue_path(@issue, issue: { state_event: :close }, format: 'json'), class: "hidden-xs hidden-sm btn btn-grouped btn-close #{issue_button_visibility(@issue, true)}", title: 'Close issue' = link_to 'Reopen issue', issue_path(@issue, issue: { state_event: :reopen }, format: 'json'), class: "hidden-xs hidden-sm btn btn-grouped btn-reopen #{issue_button_visibility(@issue, false)}", title: 'Reopen issue' - if can_report_spam - = link_to 'Submit as spam', mark_as_spam_namespace_project_issue_path(@project.namespace, @project, @issue), method: :post, class: 'hidden-xs hidden-sm btn btn-grouped btn-spam', title: 'Submit as spam' - = link_to new_namespace_project_issue_path(@project.namespace, @project), class: 'hidden-xs hidden-sm btn btn-grouped new-issue-link btn-new btn-inverted', title: 'New issue', id: 'new_issue_link' do + = link_to 'Submit as spam', mark_as_spam_project_issue_path(@project, @issue), method: :post, class: 'hidden-xs hidden-sm btn btn-grouped btn-spam', title: 'Submit as spam' + = link_to new_project_issue_path(@project), class: 'hidden-xs hidden-sm btn btn-grouped new-issue-link btn-new btn-inverted', title: 'New issue', id: 'new_issue_link' do New issue .issue-details.issuable-details @@ -65,10 +65,10 @@ = edited_time_ago_with_tooltip(@issue, placement: 'bottom', html_class: 'issue-edited-ago js-issue-edited-ago') - #merge-requests{ data: { url: referenced_merge_requests_namespace_project_issue_url(@project.namespace, @project, @issue) } } + #merge-requests{ data: { url: referenced_merge_requests_project_issue_url(@project, @issue) } } // This element is filled in using JavaScript. - #related-branches{ data: { url: related_branches_namespace_project_issue_url(@project.namespace, @project, @issue) } } + #related-branches{ data: { url: related_branches_project_issue_url(@project, @issue) } } // This element is filled in using JavaScript. .content-block.emoji-block diff --git a/app/views/projects/jobs/_header.html.haml b/app/views/projects/jobs/_header.html.haml index ad72ab5b199..d81b8f6bb4c 100644 --- a/app/views/projects/jobs/_header.html.haml +++ b/app/views/projects/jobs/_header.html.haml @@ -6,13 +6,13 @@ = render 'ci/status/badge', status: @build.detailed_status(current_user), link: false, title: @build.status_title %strong Job - = link_to "##{@build.id}", namespace_project_job_path(@project.namespace, @project, @build), class: 'js-build-id' + = link_to "##{@build.id}", project_job_path(@project, @build), class: 'js-build-id' in pipeline %strong = link_to "##{pipeline.id}", pipeline_path(pipeline) for %strong - = link_to pipeline.short_sha, namespace_project_commit_path(@project.namespace, @project, pipeline.sha), class: 'commit-sha' + = link_to pipeline.short_sha, project_commit_path(@project, pipeline.sha), class: 'commit-sha' from %strong = link_to @build.ref, project_ref_path(@project, @build.ref), class: 'ref-name' @@ -24,8 +24,8 @@ - if show_controls .nav-controls - if can?(current_user, :create_issue, @project) && @build.failed? - = link_to "New issue", new_namespace_project_issue_path(@project.namespace, @project, issue: build_failed_issue_options), class: 'btn btn-new btn-inverted' + = link_to "New issue", new_project_issue_path(@project, issue: build_failed_issue_options), class: 'btn btn-new btn-inverted' - if can?(current_user, :update_build, @build) && @build.retryable? - = link_to "Retry job", retry_namespace_project_job_path(@project.namespace, @project, @build), class: 'btn btn-inverted-secondary', method: :post + = link_to "Retry job", retry_project_job_path(@project, @build), class: 'btn btn-inverted-secondary', method: :post %button.btn.btn-default.pull-right.visible-xs-block.visible-sm-block.build-gutter-toggle.js-sidebar-build-toggle{ role: "button", type: "button" } = icon('angle-double-left') diff --git a/app/views/projects/jobs/_sidebar.html.haml b/app/views/projects/jobs/_sidebar.html.haml index 93e8a4e385c..bddb587ddc6 100644 --- a/app/views/projects/jobs/_sidebar.html.haml +++ b/app/views/projects/jobs/_sidebar.html.haml @@ -26,14 +26,14 @@ - if @build.artifacts? .btn-group.btn-group-justified{ role: :group } - if @build.has_expiring_artifacts? && can?(current_user, :update_build, @build) - = link_to keep_namespace_project_job_artifacts_path(@project.namespace, @project, @build), class: 'btn btn-sm btn-default', method: :post do + = link_to keep_project_job_artifacts_path(@project, @build), class: 'btn btn-sm btn-default', method: :post do Keep - = link_to download_namespace_project_job_artifacts_path(@project.namespace, @project, @build), rel: 'nofollow', download: '', class: 'btn btn-sm btn-default' do + = link_to download_project_job_artifacts_path(@project, @build), rel: 'nofollow', download: '', class: 'btn btn-sm btn-default' do Download - if @build.artifacts_metadata? - = link_to browse_namespace_project_job_artifacts_path(@project.namespace, @project, @build), class: 'btn btn-sm btn-default' do + = link_to browse_project_job_artifacts_path(@project, @build), class: 'btn btn-sm btn-default' do Browse - if @build.trigger_request @@ -58,7 +58,7 @@ .block %p Commit - = link_to @build.pipeline.short_sha, namespace_project_commit_path(@project.namespace, @project, @build.pipeline.sha), class: 'commit-sha link-commit' + = link_to @build.pipeline.short_sha, project_commit_path(@project, @build.pipeline.sha), class: 'commit-sha link-commit' = clipboard_button(text: @build.pipeline.short_sha, title: "Copy commit SHA to clipboard") - if @build.merge_request in @@ -73,9 +73,9 @@ %span{ class: "ci-status-icon-#{@build.pipeline.status}" } = ci_icon_for_status(@build.pipeline.status) Pipeline - = link_to "##{@build.pipeline.id}", namespace_project_pipeline_path(@project.namespace, @project, @build.pipeline), class: 'link-commit' + = link_to "##{@build.pipeline.id}", project_pipeline_path(@project, @build.pipeline), class: 'link-commit' from - = link_to "#{@build.pipeline.ref}", namespace_project_branch_path(@project.namespace, @project, @build.pipeline.ref), class: 'link-commit' + = link_to "#{@build.pipeline.ref}", project_branch_path(@project, @build.pipeline.ref), class: 'link-commit' %button.dropdown-menu-toggle{ type: 'button', 'data-toggle' => 'dropdown' } %span.stage-selection More = icon('chevron-down') @@ -88,7 +88,7 @@ - HasStatus::ORDERED_STATUSES.each do |build_status| - builds.select{|build| build.status == build_status}.each do |build| .build-job{ class: sidebar_build_class(build, @build), data: { stage: build.stage } } - = link_to namespace_project_job_path(@project.namespace, @project, build) do + = link_to project_job_path(@project, build) do = icon('arrow-right') %span{ class: "ci-status-icon-#{build.status}" } = ci_icon_for_status(build.status) diff --git a/app/views/projects/jobs/index.html.haml b/app/views/projects/jobs/index.html.haml index a33e3978ee1..8604c7d3ea4 100644 --- a/app/views/projects/jobs/index.html.haml +++ b/app/views/projects/jobs/index.html.haml @@ -10,7 +10,7 @@ .nav-controls - if can?(current_user, :update_build, @project) - if @all_builds.running_or_pending.any? - = link_to 'Cancel running', cancel_all_namespace_project_jobs_path(@project.namespace, @project), + = link_to 'Cancel running', cancel_all_project_jobs_path(@project), data: { confirm: 'Are you sure?' }, class: 'btn btn-danger', method: :post - unless @repository.gitlab_ci_yml diff --git a/app/views/projects/jobs/show.html.haml b/app/views/projects/jobs/show.html.haml index c73bae0a2c9..fa086413fbe 100644 --- a/app/views/projects/jobs/show.html.haml +++ b/app/views/projects/jobs/show.html.haml @@ -21,7 +21,7 @@ %br Go to - = link_to namespace_project_runners_path(@build.project.namespace, @build.project) do + = link_to project_runners_path(@build.project) do Runners page - if @build.starts_environment? @@ -54,23 +54,24 @@ - else Job has been erased #{time_ago_with_tooltip(@build.erased_at)} - .build-trace-container#build-trace - .top-bar.sticky + .build-trace-container.prepend-top-default + .top-bar.js-top-bar .js-truncated-info.truncated-info.hidden< Showing last %span.js-truncated-info-size.truncated-info-size>< KiB of log - - %a.js-raw-link.raw-link{ href: raw_namespace_project_job_path(@project.namespace, @project, @build) }>< Complete Raw + %a.js-raw-link.raw-link{ href: raw_project_job_path(@project, @build) }>< Complete Raw + .controllers - if @build.has_trace? - = link_to raw_namespace_project_job_path(@project.namespace, @project, @build), + = link_to raw_project_job_path(@project, @build), title: 'Show complete raw', data: { placement: 'top', container: 'body' }, class: 'js-raw-link-controller has-tooltip controllers-buttons' do = icon('file-text-o') - if can?(current_user, :update_build, @project) && @build.erasable? - = link_to erase_namespace_project_job_path(@project.namespace, @project, @build), + = link_to erase_project_job_path(@project, @build), method: :post, data: { confirm: 'Are you sure you want to erase this build?', placement: 'top', container: 'body' }, title: 'Erase job log', @@ -82,15 +83,17 @@ .has-tooltip.controllers-buttons{ title: 'Scroll to bottom', data: { placement: 'top', container: 'body'} } %button.js-scroll-down.btn-scroll.btn-transparent.btn-blank{ type: 'button', disabled: true } = custom_icon('scroll_down') - .bash.sticky.js-scroll-container - %code.js-build-output + + %pre.build-trace#build-trace + %code.bash.js-build-output .build-loader-animation.js-build-refresh + = render "sidebar" .js-build-options{ data: javascript_build_options } -#js-job-details-vue{ data: { endpoint: namespace_project_job_path(@project.namespace, @project, @build, format: :json) } } +#js-job-details-vue{ data: { endpoint: project_job_path(@project, @build, format: :json) } } - content_for :page_specific_javascripts do = webpack_bundle_tag('common_vue') diff --git a/app/views/projects/labels/edit.html.haml b/app/views/projects/labels/edit.html.haml index 7f0059cdcda..84b0b65d1c0 100644 --- a/app/views/projects/labels/edit.html.haml +++ b/app/views/projects/labels/edit.html.haml @@ -6,4 +6,4 @@ %h3.page-title Edit Label %hr - = render 'shared/labels/form', url: namespace_project_label_path(@project.namespace.becomes(Namespace), @project, @label), back_path: namespace_project_labels_path(@project.namespace, @project) + = render 'shared/labels/form', url: project_label_path(@project, @label), back_path: project_labels_path(@project) diff --git a/app/views/projects/labels/index.html.haml b/app/views/projects/labels/index.html.haml index 0a63325f26e..d02ea5cccc3 100644 --- a/app/views/projects/labels/index.html.haml +++ b/app/views/projects/labels/index.html.haml @@ -16,7 +16,8 @@ .nav-controls{ class: ("visible-xs" if show_new_nav?) } - if can?(current_user, :admin_label, @project) - = link_to "New label", new_namespace_project_label_path(@project.namespace, @project), class: "btn btn-new" + = link_to new_project_label_path(@project), class: "btn btn-new" do + New label .labels - if can?(current_user, :admin_label, @project) @@ -24,7 +25,7 @@ - hide = @available_labels.empty? || (params[:page].present? && params[:page] != '1') .prioritized-labels{ class: ('hide' if hide) } %h5 Prioritized Labels - %ul.content-list.manage-labels-list.js-prioritized-labels{ "data-url" => set_priorities_namespace_project_labels_path(@project.namespace, @project) } + %ul.content-list.manage-labels-list.js-prioritized-labels{ "data-url" => set_priorities_project_labels_path(@project) } #js-priority-labels-empty-state{ class: "#{'hidden' unless @prioritized_labels.empty?}" } = render 'shared/empty_states/priority_labels' - if @prioritized_labels.present? diff --git a/app/views/projects/labels/new.html.haml b/app/views/projects/labels/new.html.haml index 8f6c085a361..79e90b7ca3b 100644 --- a/app/views/projects/labels/new.html.haml +++ b/app/views/projects/labels/new.html.haml @@ -6,4 +6,4 @@ %h3.page-title New Label %hr - = render 'shared/labels/form', url: namespace_project_labels_path(@project.namespace.becomes(Namespace), @project), back_path: namespace_project_labels_path(@project.namespace, @project) + = render 'shared/labels/form', url: project_labels_path(@project), back_path: project_labels_path(@project) diff --git a/app/views/projects/mattermosts/_no_teams.html.haml b/app/views/projects/mattermosts/_no_teams.html.haml index aac74a25b75..243dcfdc187 100644 --- a/app/views/projects/mattermosts/_no_teams.html.haml +++ b/app/views/projects/mattermosts/_no_teams.html.haml @@ -13,4 +13,4 @@ and try again. %hr .clearfix - = link_to 'Go back', edit_namespace_project_service_path(@project.namespace, @project, @service), class: 'btn btn-lg pull-right' + = link_to 'Go back', edit_project_service_path(@project, @service), class: 'btn btn-lg pull-right' diff --git a/app/views/projects/mattermosts/_team_selection.html.haml b/app/views/projects/mattermosts/_team_selection.html.haml index 04bd4e8b683..3bdb5d0adc4 100644 --- a/app/views/projects/mattermosts/_team_selection.html.haml +++ b/app/views/projects/mattermosts/_team_selection.html.haml @@ -2,7 +2,7 @@ This service will be installed on the Mattermost instance at %strong= link_to Gitlab.config.mattermost.host, Gitlab.config.mattermost.host %hr -= form_for(:mattermost, method: :post, url: namespace_project_mattermost_path(@project.namespace, @project), html: { class: 'js-requires-input'} ) do |f| += form_for(:mattermost, method: :post, url: project_mattermost_path(@project), html: { class: 'js-requires-input'} ) do |f| %h4 Team %p = @teams.one? ? 'The team' : 'Select the team' @@ -42,5 +42,5 @@ %hr .clearfix .pull-right - = link_to 'Cancel', edit_namespace_project_service_path(@project.namespace, @project, @service), class: 'btn btn-lg' + = link_to 'Cancel', edit_project_service_path(@project, @service), class: 'btn btn-lg' = f.submit 'Install', class: 'btn btn-save btn-lg' diff --git a/app/views/projects/merge_requests/_head.html.haml b/app/views/projects/merge_requests/_head.html.haml index b7f73fe5339..1e505222887 100644 --- a/app/views/projects/merge_requests/_head.html.haml +++ b/app/views/projects/merge_requests/_head.html.haml @@ -4,18 +4,18 @@ .nav-links.sub-nav.scrolling-tabs %ul{ class: (container_class) } = nav_link(controller: :merge_requests) do - = link_to namespace_project_merge_requests_path(@project.namespace, @project), title: 'Merge Requests' do + = link_to project_merge_requests_path(@project), title: 'Merge Requests' do %span List - if project_nav_tab? :labels = nav_link(controller: :labels) do - = link_to namespace_project_labels_path(@project.namespace, @project), title: 'Labels' do + = link_to project_labels_path(@project), title: 'Labels' do %span Labels - if project_nav_tab? :milestones = nav_link(controller: :milestones) do - = link_to namespace_project_milestones_path(@project.namespace, @project), title: 'Milestones' do + = link_to project_milestones_path(@project), title: 'Milestones' do %span Milestones diff --git a/app/views/projects/merge_requests/_merge_request.html.haml b/app/views/projects/merge_requests/_merge_request.html.haml index 3599f2271b5..0a1ebcb8124 100644 --- a/app/views/projects/merge_requests/_merge_request.html.haml +++ b/app/views/projects/merge_requests/_merge_request.html.haml @@ -23,7 +23,7 @@ - if merge_request.milestone %span.issuable-milestone.hidden-xs - = link_to namespace_project_merge_requests_path(merge_request.project.namespace, merge_request.project, milestone_title: merge_request.milestone.title) do + = link_to project_merge_requests_path(merge_request.project, milestone_title: merge_request.milestone.title) do = icon('clock-o') = merge_request.milestone.title - if merge_request.target_project.default_branch != merge_request.target_branch diff --git a/app/views/projects/merge_requests/_mr_title.html.haml b/app/views/projects/merge_requests/_mr_title.html.haml index d9428b8562e..3182aecd0a8 100644 --- a/app/views/projects/merge_requests/_mr_title.html.haml +++ b/app/views/projects/merge_requests/_mr_title.html.haml @@ -28,8 +28,8 @@ %li{ class: merge_request_button_visibility(@merge_request, false) } = link_to 'Reopen', merge_request_path(@merge_request, merge_request: {state_event: :reopen }), method: :put, class: 'reopen-mr-link', title: 'Reopen merge request' %li - = link_to 'Edit', edit_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), class: 'issuable-edit' + = link_to 'Edit', edit_project_merge_request_path(@project, @merge_request), class: 'issuable-edit' = link_to 'Close', merge_request_path(@merge_request, merge_request: { state_event: :close }), method: :put, class: "hidden-xs hidden-sm btn btn-grouped btn-close #{merge_request_button_visibility(@merge_request, true)}", title: 'Close merge request' = link_to 'Reopen', merge_request_path(@merge_request, merge_request: {state_event: :reopen }), method: :put, class: "hidden-xs hidden-sm btn btn-grouped btn-reopen reopen-mr-link #{merge_request_button_visibility(@merge_request, false)}", title: 'Reopen merge request' - = link_to edit_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), class: "hidden-xs hidden-sm btn btn-grouped issuable-edit" do + = link_to edit_project_merge_request_path(@project, @merge_request), class: "hidden-xs hidden-sm btn btn-grouped issuable-edit" do Edit diff --git a/app/views/projects/merge_requests/_pipelines.html.haml b/app/views/projects/merge_requests/_pipelines.html.haml index 2f1dbe87619..473b7b919c8 100644 --- a/app/views/projects/merge_requests/_pipelines.html.haml +++ b/app/views/projects/merge_requests/_pipelines.html.haml @@ -1,4 +1,4 @@ -- endpoint_path = local_assigns[:endpoint] || pipelines_namespace_project_merge_request_path(@project.namespace, @project, @merge_request, format: :json) +- endpoint_path = local_assigns[:endpoint] || pipelines_project_merge_request_path(@project, @merge_request, format: :json) - disable_initialization = local_assigns.fetch(:disable_initialization, false) = render 'projects/commit/pipelines_list', endpoint: endpoint_path, disable_initialization: disable_initialization diff --git a/app/views/projects/merge_requests/conflicts.html.haml b/app/views/projects/merge_requests/conflicts.html.haml index f016b9c13b3..454bc359b6b 100644 --- a/app/views/projects/merge_requests/conflicts.html.haml +++ b/app/views/projects/merge_requests/conflicts.html.haml @@ -10,8 +10,8 @@ = render 'shared/issuable/sidebar', issuable: @merge_request -#conflicts{ "v-cloak" => "true", data: { conflicts_path: conflicts_namespace_project_merge_request_path(@merge_request.project.namespace, @merge_request.project, @merge_request, format: :json), - resolve_conflicts_path: resolve_conflicts_namespace_project_merge_request_path(@merge_request.project.namespace, @merge_request.project, @merge_request) } } +#conflicts{ "v-cloak" => "true", data: { conflicts_path: conflicts_project_merge_request_path(@merge_request.project, @merge_request, format: :json), + resolve_conflicts_path: resolve_conflicts_project_merge_request_path(@merge_request.project, @merge_request) } } .loading{ "v-if" => "isLoading" } %i.fa.fa-spinner.fa-spin diff --git a/app/views/projects/merge_requests/conflicts/_submit_form.html.haml b/app/views/projects/merge_requests/conflicts/_submit_form.html.haml index e675e1830d0..13026b7566a 100644 --- a/app/views/projects/merge_requests/conflicts/_submit_form.html.haml +++ b/app/views/projects/merge_requests/conflicts/_submit_form.html.haml @@ -13,4 +13,4 @@ %button.btn.btn-success.js-submit-button{ type: "button", "@click" => "commit()", ":disabled" => "!readyToCommit" } %span {{commitButtonText}} .col-xs-6.text-right - = link_to "Cancel", namespace_project_merge_request_path(@merge_request.project.namespace, @merge_request.project, @merge_request), class: "btn btn-cancel" + = link_to "Cancel", project_merge_request_path(@merge_request.project, @merge_request), class: "btn btn-cancel" diff --git a/app/views/projects/merge_requests/conflicts/show.html.haml b/app/views/projects/merge_requests/conflicts/show.html.haml index f016b9c13b3..454bc359b6b 100644 --- a/app/views/projects/merge_requests/conflicts/show.html.haml +++ b/app/views/projects/merge_requests/conflicts/show.html.haml @@ -10,8 +10,8 @@ = render 'shared/issuable/sidebar', issuable: @merge_request -#conflicts{ "v-cloak" => "true", data: { conflicts_path: conflicts_namespace_project_merge_request_path(@merge_request.project.namespace, @merge_request.project, @merge_request, format: :json), - resolve_conflicts_path: resolve_conflicts_namespace_project_merge_request_path(@merge_request.project.namespace, @merge_request.project, @merge_request) } } +#conflicts{ "v-cloak" => "true", data: { conflicts_path: conflicts_project_merge_request_path(@merge_request.project, @merge_request, format: :json), + resolve_conflicts_path: resolve_conflicts_project_merge_request_path(@merge_request.project, @merge_request) } } .loading{ "v-if" => "isLoading" } %i.fa.fa-spinner.fa-spin diff --git a/app/views/projects/merge_requests/creations/_new_compare.html.haml b/app/views/projects/merge_requests/creations/_new_compare.html.haml index 7cda326afef..4e5aae496b1 100644 --- a/app/views/projects/merge_requests/creations/_new_compare.html.haml +++ b/app/views/projects/merge_requests/creations/_new_compare.html.haml @@ -1,7 +1,7 @@ %h3.page-title New Merge Request -= form_for [@project.namespace.becomes(Namespace), @project, @merge_request], url: namespace_project_new_merge_request_path(@project.namespace, @project), method: :get, html: { class: "merge-request-form form-inline js-requires-input" } do |f| += form_for [@project.namespace.becomes(Namespace), @project, @merge_request], url: project_new_merge_request_path(@project), method: :get, html: { class: "merge-request-form form-inline js-requires-input" } do |f| .hide.alert.alert-danger.mr-compare-errors .merge-request-branches.row .col-md-6 @@ -69,7 +69,7 @@ :javascript new Compare({ - targetProjectUrl: "#{namespace_project_new_merge_request_update_branches_path(@source_project.namespace, @source_project)}", - sourceBranchUrl: "#{namespace_project_new_merge_request_branch_from_path(@source_project.namespace, @source_project)}", - targetBranchUrl: "#{namespace_project_new_merge_request_branch_to_path(@source_project.namespace, @source_project)}" + targetProjectUrl: "#{project_new_merge_request_update_branches_path(@source_project)}", + sourceBranchUrl: "#{project_new_merge_request_branch_from_path(@source_project)}", + targetBranchUrl: "#{project_new_merge_request_branch_to_path(@source_project)}" }); diff --git a/app/views/projects/merge_requests/diffs/_versions.html.haml b/app/views/projects/merge_requests/diffs/_versions.html.haml index 0999b95c9c9..9f7152b9824 100644 --- a/app/views/projects/merge_requests/diffs/_versions.html.haml +++ b/app/views/projects/merge_requests/diffs/_versions.html.haml @@ -77,7 +77,7 @@ = icon('info-circle') Selected versions have different base commits. Changes will include - = link_to namespace_project_compare_path(@project.namespace, @project, from: @start_version.base_commit_sha, to: @merge_request_diff.base_commit_sha) do + = link_to project_compare_path(@project, from: @start_version.base_commit_sha, to: @merge_request_diff.base_commit_sha) do new commits from = succeed '.' do @@ -94,4 +94,4 @@ of the diff. .pull-right - = link_to 'Show latest version', diffs_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), class: 'btn btn-sm' + = link_to 'Show latest version', diffs_project_merge_request_path(@project, @merge_request), class: 'btn btn-sm' diff --git a/app/views/projects/merge_requests/index.html.haml b/app/views/projects/merge_requests/index.html.haml index 6fe44ba3c3d..bfeb746ee83 100644 --- a/app/views/projects/merge_requests/index.html.haml +++ b/app/views/projects/merge_requests/index.html.haml @@ -1,7 +1,7 @@ - @no_container = true - @can_bulk_update = can?(current_user, :admin_merge_request, @project) - merge_project = can?(current_user, :create_merge_request, @project) ? @project : (current_user && current_user.fork_of(@project)) -- new_merge_request_path = namespace_project_new_merge_request_path(merge_project.namespace, merge_project) if merge_project +- new_merge_request_path = project_new_merge_request_path(merge_project) if merge_project - page_title "Merge Requests" - unless @project.default_issues_tracker? diff --git a/app/views/projects/merge_requests/show.html.haml b/app/views/projects/merge_requests/show.html.haml index dbbf1bde088..13012151349 100644 --- a/app/views/projects/merge_requests/show.html.haml +++ b/app/views/projects/merge_requests/show.html.haml @@ -35,21 +35,21 @@ .nav-links.scrolling-tabs %ul.merge-request-tabs %li.notes-tab - = link_to namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: { target: 'div#notes', action: 'show', toggle: 'tab' } do + = link_to project_merge_request_path(@project, @merge_request), data: { target: 'div#notes', action: 'show', toggle: 'tab' } do Discussion %span.badge= @merge_request.related_notes.user.count - if @merge_request.source_project %li.commits-tab - = link_to commits_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: { target: 'div#commits', action: 'commits', toggle: 'tab' } do + = link_to commits_project_merge_request_path(@project, @merge_request), data: { target: 'div#commits', action: 'commits', toggle: 'tab' } do Commits %span.badge= @commits_count - if @pipelines.any? %li.pipelines-tab - = link_to pipelines_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: { target: '#pipelines', action: 'pipelines', toggle: 'tab' } do + = link_to pipelines_project_merge_request_path(@project, @merge_request), data: { target: '#pipelines', action: 'pipelines', toggle: 'tab' } do Pipelines %span.badge= @pipelines.size %li.diffs-tab - = link_to diffs_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: { target: 'div#diffs', action: 'diffs', toggle: 'tab' } do + = link_to diffs_project_merge_request_path(@project, @merge_request), data: { target: 'div#diffs', action: 'diffs', toggle: 'tab' } do Changes %span.badge= @merge_request.diff_size #resolve-count-app.line-resolve-all-container.prepend-top-10{ "v-cloak" => true } @@ -76,7 +76,7 @@ -# This tab is always loaded via AJAX #pipelines.pipelines.tab-pane - if @pipelines.any? - = render 'projects/commit/pipelines_list', disable_initialization: true, endpoint: pipelines_namespace_project_merge_request_path(@project.namespace, @project, @merge_request) + = render 'projects/commit/pipelines_list', disable_initialization: true, endpoint: pipelines_project_merge_request_path(@project, @merge_request) #diffs.diffs.tab-pane -# This tab is always loaded via AJAX diff --git a/app/views/projects/milestones/_form.html.haml b/app/views/projects/milestones/_form.html.haml index 9a95b2a82ff..2e74b1b83cb 100644 --- a/app/views/projects/milestones/_form.html.haml +++ b/app/views/projects/milestones/_form.html.haml @@ -19,7 +19,7 @@ .form-actions - if @milestone.new_record? = f.submit 'Create milestone', class: "btn-create btn" - = link_to "Cancel", namespace_project_milestones_path(@project.namespace, @project), class: "btn btn-cancel" + = link_to "Cancel", project_milestones_path(@project), class: "btn btn-cancel" - else = f.submit 'Save changes', class: "btn-save btn" - = link_to "Cancel", namespace_project_milestone_path(@project.namespace, @project, @milestone), class: "btn btn-cancel" + = link_to "Cancel", project_milestone_path(@project, @milestone), class: "btn btn-cancel" diff --git a/app/views/projects/milestones/_milestone.html.haml b/app/views/projects/milestones/_milestone.html.haml index 77b566db6b6..bc82b45f902 100644 --- a/app/views/projects/milestones/_milestone.html.haml +++ b/app/views/projects/milestones/_milestone.html.haml @@ -1,5 +1,5 @@ = render 'shared/milestones/milestone', - milestone_path: namespace_project_milestone_path(milestone.project.namespace, milestone.project, milestone), - issues_path: namespace_project_issues_path(milestone.project.namespace, milestone.project, milestone_title: milestone.title), - merge_requests_path: namespace_project_merge_requests_path(milestone.project.namespace, milestone.project, milestone_title: milestone.title), + milestone_path: project_milestone_path(milestone.project, milestone), + issues_path: project_issues_path(milestone.project, milestone_title: milestone.title), + merge_requests_path: project_merge_requests_path(milestone.project, milestone_title: milestone.title), milestone: milestone diff --git a/app/views/projects/milestones/index.html.haml b/app/views/projects/milestones/index.html.haml index 63522a11b9d..a89387bc8f1 100644 --- a/app/views/projects/milestones/index.html.haml +++ b/app/views/projects/milestones/index.html.haml @@ -14,7 +14,8 @@ .nav-controls = render 'shared/milestones_sort_dropdown' - if can?(current_user, :admin_milestone, @project) - = link_to "New milestone", new_namespace_project_milestone_path(@project.namespace, @project), class: "btn btn-new #{("visible-xs hidden-sm hidden-md hidden-lg" if show_new_nav?)}", title: 'New milestone' + = link_to new_project_milestone_path(@project), class: 'btn btn-new', title: 'New milestone' do + New milestone .milestones %ul.content-list diff --git a/app/views/projects/milestones/show.html.haml b/app/views/projects/milestones/show.html.haml index 4b692aba11c..0bf0e11c107 100644 --- a/app/views/projects/milestones/show.html.haml +++ b/app/views/projects/milestones/show.html.haml @@ -23,14 +23,14 @@ .milestone-buttons - if can?(current_user, :admin_milestone, @project) - if @milestone.active? - = link_to 'Close milestone', namespace_project_milestone_path(@project.namespace, @project, @milestone, milestone: {state_event: :close }), method: :put, class: "btn btn-close btn-nr btn-grouped" + = link_to 'Close milestone', project_milestone_path(@project, @milestone, milestone: {state_event: :close }), method: :put, class: "btn btn-close btn-nr btn-grouped" - else - = link_to 'Reopen milestone', namespace_project_milestone_path(@project.namespace, @project, @milestone, milestone: {state_event: :activate }), method: :put, class: "btn btn-reopen btn-nr btn-grouped" + = link_to 'Reopen milestone', project_milestone_path(@project, @milestone, milestone: {state_event: :activate }), method: :put, class: "btn btn-reopen btn-nr btn-grouped" - = link_to edit_namespace_project_milestone_path(@project.namespace, @project, @milestone), class: "btn btn-grouped btn-nr" do + = link_to edit_project_milestone_path(@project, @milestone), class: "btn btn-grouped btn-nr" do Edit - = link_to namespace_project_milestone_path(@project.namespace, @project, @milestone), data: { confirm: 'Are you sure?' }, method: :delete, class: "btn btn-grouped btn-danger" do + = link_to project_milestone_path(@project, @milestone), data: { confirm: 'Are you sure?' }, method: :delete, class: "btn btn-grouped btn-danger" do Delete %a.btn.btn-default.btn-grouped.pull-right.visible-xs-block.js-sidebar-toggle{ href: "#" } diff --git a/app/views/projects/network/show.html.haml b/app/views/projects/network/show.html.haml index efe0513037e..1125207ef73 100644 --- a/app/views/projects/network/show.html.haml +++ b/app/views/projects/network/show.html.haml @@ -9,7 +9,7 @@ %div{ class: container_class } .project-network .controls - = form_tag namespace_project_network_path(@project.namespace, @project, @id), method: :get, class: 'form-inline network-form' do |f| + = form_tag project_network_path(@project, @id), method: :get, class: 'form-inline network-form' do |f| = text_field_tag :extended_sha1, @options[:extended_sha1], placeholder: "Git revision", class: 'search-input form-control input-mx-250 search-sha' = button_tag class: 'btn btn-success' do = icon('search') diff --git a/app/views/projects/no_repo.html.haml b/app/views/projects/no_repo.html.haml index 1cf286ddc40..ba5845877e5 100644 --- a/app/views/projects/no_repo.html.haml +++ b/app/views/projects/no_repo.html.haml @@ -9,12 +9,12 @@ %hr .no-repo-actions - = link_to namespace_project_repository_path(@project.namespace, @project), method: :post, class: 'btn btn-primary' do + = link_to project_repository_path(@project), method: :post, class: 'btn btn-primary' do #{ _('Create empty bare repository') } %strong.prepend-left-10.append-right-10 or - = link_to new_namespace_project_import_path(@project.namespace, @project), class: 'btn' do + = link_to new_project_import_path(@project), class: 'btn' do #{ _('Import repository') } - if can? current_user, :remove_project, @project diff --git a/app/views/projects/pages/_destroy.haml b/app/views/projects/pages/_destroy.haml index 42d9ef5ccba..7d6c30b7f8d 100644 --- a/app/views/projects/pages/_destroy.haml +++ b/app/views/projects/pages/_destroy.haml @@ -7,6 +7,6 @@ %p Removing the pages will prevent from exposing them to outside world. .form-actions - = link_to 'Remove pages', namespace_project_pages_path(@project.namespace, @project), data: { confirm: 'Are you sure?'}, method: :delete, class: "btn btn-remove" + = link_to 'Remove pages', project_pages_path(@project), data: { confirm: 'Are you sure?'}, method: :delete, class: "btn btn-remove" - else .nothing-here-block Only the project owner can remove pages diff --git a/app/views/projects/pages/_list.html.haml b/app/views/projects/pages/_list.html.haml index 4f2dd1a1398..a85cda407af 100644 --- a/app/views/projects/pages/_list.html.haml +++ b/app/views/projects/pages/_list.html.haml @@ -6,8 +6,8 @@ - @domains.each do |domain| %li .pull-right - = link_to 'Details', namespace_project_pages_domain_path(@project.namespace, @project, domain), class: "btn btn-sm btn-grouped" - = link_to 'Remove', namespace_project_pages_domain_path(@project.namespace, @project, domain), data: { confirm: 'Are you sure?'}, method: :delete, class: "btn btn-remove btn-sm btn-grouped" + = link_to 'Details', project_pages_domain_path(@project, domain), class: "btn btn-sm btn-grouped" + = link_to 'Remove', project_pages_domain_path(@project, domain), data: { confirm: 'Are you sure?'}, method: :delete, class: "btn btn-remove btn-sm btn-grouped" .clearfix %span= link_to domain.domain, domain.url %p diff --git a/app/views/projects/pages/show.html.haml b/app/views/projects/pages/show.html.haml index b22a54d75c8..098b0ef56ef 100644 --- a/app/views/projects/pages/show.html.haml +++ b/app/views/projects/pages/show.html.haml @@ -5,7 +5,7 @@ Pages - if can?(current_user, :update_pages, @project) && (Gitlab.config.pages.external_http || Gitlab.config.pages.external_https) - = link_to new_namespace_project_pages_domain_path(@project.namespace, @project), class: 'btn btn-new pull-right', title: 'New Domain' do + = link_to new_project_pages_domain_path(@project), class: 'btn btn-new pull-right', title: 'New Domain' do %i.fa.fa-plus New Domain diff --git a/app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml b/app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml index 966d6cd8495..08ccd57c81a 100644 --- a/app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml +++ b/app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml @@ -9,7 +9,7 @@ %td - if pipeline_schedule.last_pipeline .status-icon-container{ class: "ci-status-icon-#{pipeline_schedule.last_pipeline.status}" } - = link_to namespace_project_pipeline_path(@project.namespace, @project, pipeline_schedule.last_pipeline.id) do + = link_to project_pipeline_path(@project, pipeline_schedule.last_pipeline.id) do = ci_icon_for_status(pipeline_schedule.last_pipeline.status) %span ##{pipeline_schedule.last_pipeline.id} - else diff --git a/app/views/projects/pipeline_schedules/index.html.haml b/app/views/projects/pipeline_schedules/index.html.haml index cbda522f28f..5f9518e5102 100644 --- a/app/views/projects/pipeline_schedules/index.html.haml +++ b/app/views/projects/pipeline_schedules/index.html.haml @@ -22,7 +22,8 @@ = render "tabs", schedule_path_proc: schedule_path_proc, all_schedules: @all_schedules, scope: @scope .nav-controls{ class: ("visible-xs" if show_new_nav?) } - = link_to _('New schedule'), new_namespace_project_pipeline_schedule_path(@project.namespace, @project), class: 'btn btn-create' + = link_to new_project_pipeline_schedule_path(@project), class: 'btn btn-create' do + %span= _('New schedule') - if @schedules.present? %ul.content-list diff --git a/app/views/projects/pipelines/_head.html.haml b/app/views/projects/pipelines/_head.html.haml index d2f0cb0806f..ee2f236cec4 100644 --- a/app/views/projects/pipelines/_head.html.haml +++ b/app/views/projects/pipelines/_head.html.haml @@ -29,6 +29,6 @@ - if @project.feature_available?(:builds, current_user) && !@project.empty_repo? = nav_link(path: 'pipelines#charts') do - = link_to charts_namespace_project_pipelines_path(@project.namespace, @project), title: 'Charts', class: 'shortcuts-pipelines-charts' do + = link_to charts_project_pipelines_path(@project), title: 'Charts', class: 'shortcuts-pipelines-charts' do %span Charts diff --git a/app/views/projects/pipelines/_info.html.haml b/app/views/projects/pipelines/_info.html.haml index 673c3370b62..f5149306734 100644 --- a/app/views/projects/pipelines/_info.html.haml +++ b/app/views/projects/pipelines/_info.html.haml @@ -26,10 +26,10 @@ .well-segment.branch-info .icon-container.commit-icon = custom_icon("icon_commit") - = link_to @commit.short_id, namespace_project_commit_path(@project.namespace, @project, @pipeline.sha), class: "commit-sha js-details-short" + = link_to @commit.short_id, project_commit_path(@project, @pipeline.sha), class: "commit-sha js-details-short" = link_to("#", class: "js-details-expand hidden-xs hidden-sm") do %span.text-expander \... %span.js-details-content.hide - = link_to @pipeline.sha, namespace_project_commit_path(@project.namespace, @project, @pipeline.sha), class: "commit-sha commit-hash-full" + = link_to @pipeline.sha, project_commit_path(@project, @pipeline.sha), class: "commit-sha commit-hash-full" = clipboard_button(text: @pipeline.sha, title: "Copy commit SHA to clipboard") diff --git a/app/views/projects/pipelines/_with_tabs.html.haml b/app/views/projects/pipelines/_with_tabs.html.haml index 85550e8fd32..ad61f033a1c 100644 --- a/app/views/projects/pipelines/_with_tabs.html.haml +++ b/app/views/projects/pipelines/_with_tabs.html.haml @@ -3,15 +3,15 @@ .tabs-holder %ul.pipelines-tabs.nav-links.no-top.no-bottom %li.js-pipeline-tab-link - = link_to namespace_project_pipeline_path(@project.namespace, @project, @pipeline), data: { target: 'div#js-tab-pipeline', action: 'pipelines', toggle: 'tab' }, class: 'pipeline-tab' do + = link_to project_pipeline_path(@project, @pipeline), data: { target: 'div#js-tab-pipeline', action: 'pipelines', toggle: 'tab' }, class: 'pipeline-tab' do Pipeline %li.js-builds-tab-link - = link_to builds_namespace_project_pipeline_path(@project.namespace, @project, @pipeline), data: {target: 'div#js-tab-builds', action: 'builds', toggle: 'tab' }, class: 'builds-tab' do + = link_to builds_project_pipeline_path(@project, @pipeline), data: {target: 'div#js-tab-builds', action: 'builds', toggle: 'tab' }, class: 'builds-tab' do Jobs %span.badge.js-builds-counter= pipeline.statuses.count - if failed_builds.present? %li.js-failures-tab-link - = link_to failures_namespace_project_pipeline_path(@project.namespace, @project, @pipeline), data: {target: 'div#js-tab-failures', action: 'failures', toggle: 'tab' }, class: 'failures-tab' do + = link_to failures_project_pipeline_path(@project, @pipeline), data: {target: 'div#js-tab-failures', action: 'failures', toggle: 'tab' }, class: 'failures-tab' do Failed Jobs %span.badge.js-failures-counter= failed_builds.count diff --git a/app/views/projects/pipelines/charts.html.haml b/app/views/projects/pipelines/charts.html.haml index d557126bf3b..ef949ad4443 100644 --- a/app/views/projects/pipelines/charts.html.haml +++ b/app/views/projects/pipelines/charts.html.haml @@ -1,6 +1,6 @@ - @no_container = true - @breadcrumb_title = "Charts" -- page_title "Charts", "Pipelines" +- page_title _("Charts"), _("Pipelines") - if show_new_nav? - breadcrumbs_extra_links("Pipelines", project_pipelines_path(@project)) - content_for :page_specific_javascripts do @@ -11,7 +11,7 @@ %div{ class: container_class } .sub-header-block .oneline - A collection of graphs for Continuous Integration + = _("A collection of graphs regarding Continuous Integration") #charts.ci-charts .row diff --git a/app/views/projects/pipelines/charts/_overall.haml b/app/views/projects/pipelines/charts/_overall.haml index 93083397d5b..66786c7ff59 100644 --- a/app/views/projects/pipelines/charts/_overall.haml +++ b/app/views/projects/pipelines/charts/_overall.haml @@ -1,15 +1,15 @@ -%h4 Overall stats +%h4= s_("PipelineCharts|Overall statistics") %ul %li - Total: - %strong= pluralize @counts[:total], 'pipeline' + = s_("PipelineCharts|Total:") + %strong= n_("1 pipeline", "%d pipelines", @counts[:total]) % @counts[:total] %li - Successful: - %strong= pluralize @counts[:success], 'pipeline' + = s_("PipelineCharts|Successful:") + %strong= n_("1 pipeline", "%d pipelines", @counts[:success]) % @counts[:success] %li - Failed: - %strong= pluralize @counts[:failed], 'pipeline' + = s_("PipelineCharts|Failed:") + %strong= n_("1 pipeline", "%d pipelines", @counts[:failed]) % @counts[:failed] %li - Success ratio: + = s_("PipelineCharts|Success ratio:") %strong #{success_ratio(@counts)}% diff --git a/app/views/projects/pipelines/charts/_pipeline_times.haml b/app/views/projects/pipelines/charts/_pipeline_times.haml index aee7c5492aa..1292f580a81 100644 --- a/app/views/projects/pipelines/charts/_pipeline_times.haml +++ b/app/views/projects/pipelines/charts/_pipeline_times.haml @@ -1,6 +1,6 @@ %div %p.light - Commit duration in minutes for last 30 commits + = _("Commit duration in minutes for last 30 commits") %canvas#build_timesChart{ height: 200 } diff --git a/app/views/projects/pipelines/charts/_pipelines.haml b/app/views/projects/pipelines/charts/_pipelines.haml index b6f453b9736..be884448087 100644 --- a/app/views/projects/pipelines/charts/_pipelines.haml +++ b/app/views/projects/pipelines/charts/_pipelines.haml @@ -1,29 +1,29 @@ -%h4 Pipelines charts +%h4= _("Pipelines charts") %p %span.cgreen = icon("circle") - success + = s_("Pipeline|success") %span.cgray = icon("circle") - all + = s_("Pipeline|all") .prepend-top-default %p.light - Jobs for last week + = _("Jobs for last week") (#{date_from_to(Date.today - 7.days, Date.today)}) %canvas#weekChart{ height: 200 } .prepend-top-default %p.light - Jobs for last month + = _("Jobs for last month") (#{date_from_to(Date.today - 30.days, Date.today)}) %canvas#monthChart{ height: 200 } .prepend-top-default %p.light - Jobs for last year + = _("Jobs for last year") %canvas#yearChart.padded{ height: 250 } - [:week, :month, :year].each do |scope| diff --git a/app/views/projects/pipelines/index.html.haml b/app/views/projects/pipelines/index.html.haml index 38237d2d97d..c1729850cf4 100644 --- a/app/views/projects/pipelines/index.html.haml +++ b/app/views/projects/pipelines/index.html.haml @@ -2,10 +2,10 @@ - page_title "Pipelines" = render "projects/pipelines/head" -#pipelines-list-vue{ data: { endpoint: namespace_project_pipelines_path(@project.namespace, @project, format: :json), +#pipelines-list-vue{ data: { endpoint: project_pipelines_path(@project, format: :json), "css-class" => container_class, "help-page-path" => help_page_path('ci/quick_start/README'), - "new-pipeline-path" => new_namespace_project_pipeline_path(@project.namespace, @project), + "new-pipeline-path" => new_project_pipeline_path(@project), "can-create-pipeline" => can?(current_user, :create_pipeline, @project).to_s, "all-path" => project_pipelines_path(@project), "pending-path" => project_pipelines_path(@project, scope: :pending), diff --git a/app/views/projects/pipelines/new.html.haml b/app/views/projects/pipelines/new.html.haml index 71a8e490c3e..308f2611e02 100644 --- a/app/views/projects/pipelines/new.html.haml +++ b/app/views/projects/pipelines/new.html.haml @@ -4,7 +4,7 @@ New Pipeline %hr -= form_for @pipeline, as: :pipeline, url: namespace_project_pipelines_path(@project.namespace, @project), html: { id: "new-pipeline-form", class: "form-horizontal js-new-pipeline-form js-requires-input" } do |f| += form_for @pipeline, as: :pipeline, url: project_pipelines_path(@project), html: { id: "new-pipeline-form", class: "form-horizontal js-new-pipeline-form js-requires-input" } do |f| = form_errors(@pipeline) .form-group = f.label :ref, 'Create for', class: 'control-label' @@ -17,7 +17,7 @@ .help-block Existing branch name, tag .form-actions = f.submit 'Create pipeline', class: 'btn btn-create', tabindex: 3 - = link_to 'Cancel', namespace_project_pipelines_path(@project.namespace, @project), class: 'btn btn-cancel' + = link_to 'Cancel', project_pipelines_path(@project), class: 'btn btn-cancel' :javascript var availableRefs = #{@project.repository.ref_names.to_json}; diff --git a/app/views/projects/pipelines/show.html.haml b/app/views/projects/pipelines/show.html.haml index b39453a50fb..63f85fc69a2 100644 --- a/app/views/projects/pipelines/show.html.haml +++ b/app/views/projects/pipelines/show.html.haml @@ -8,7 +8,7 @@ = render "projects/pipelines/with_tabs", pipeline: @pipeline -.js-pipeline-details-vue{ data: { endpoint: namespace_project_pipeline_path(@project.namespace, @project, @pipeline, format: :json) } } +.js-pipeline-details-vue{ data: { endpoint: project_pipeline_path(@project, @pipeline, format: :json) } } - content_for :page_specific_javascripts do = webpack_bundle_tag('common_vue') diff --git a/app/views/projects/pipelines_settings/_show.html.haml b/app/views/projects/pipelines_settings/_show.html.haml index 580129ca809..255d7ef38e0 100644 --- a/app/views/projects/pipelines_settings/_show.html.haml +++ b/app/views/projects/pipelines_settings/_show.html.haml @@ -3,7 +3,7 @@ %h4.prepend-top-0 Pipelines .col-lg-8 - = form_for @project, url: namespace_project_pipelines_settings_path(@project.namespace.becomes(Namespace), @project) do |f| + = form_for @project, url: project_pipelines_settings_path(@project) do |f| %fieldset.builds-feature - unless @repository.gitlab_ci_yml .form-group @@ -47,6 +47,14 @@ %hr .form-group + = f.label :ci_config_path, 'Custom CI config path', class: 'label-light' + = f.text_field :ci_config_path, class: 'form-control', placeholder: '.gitlab-ci.yml' + %p.help-block + The path to CI config file. Defaults to <code>.gitlab-ci.yml</code> + = link_to icon('question-circle'), help_page_path('user/project/pipelines/settings', anchor: 'custom-ci-config-path'), target: '_blank' + + %hr + .form-group .checkbox = f.label :public_builds do = f.check_box :public_builds diff --git a/app/views/projects/project_members/_new_project_member.html.haml b/app/views/projects/project_members/_new_project_member.html.haml index 8bf2246662a..bf5b11ea30c 100644 --- a/app/views/projects/project_members/_new_project_member.html.haml +++ b/app/views/projects/project_members/_new_project_member.html.haml @@ -1,6 +1,6 @@ .row .col-sm-12 - = form_for @project_member, as: :project_member, url: namespace_project_project_members_path(@project.namespace, @project), html: { class: 'users-project-form' } do |f| + = form_for @project_member, as: :project_member, url: project_project_members_path(@project), html: { class: 'users-project-form' } do |f| .form-group = label_tag :user_ids, "Select members to invite", class: "label-light" = users_select_tag(:user_ids, multiple: true, class: "input-clamp", scope: :all, email_user: true, placeholder: "Search for members to update or invite") @@ -18,4 +18,4 @@ = text_field_tag :expires_at, nil, class: 'form-control js-access-expiration-date', placeholder: 'Expiration date' %i.clear-icon.js-clear-input = f.submit "Add to project", class: "btn btn-create" - = link_to "Import", import_namespace_project_project_members_path(@project.namespace, @project), class: "btn btn-default", title: "Import members from another project" + = link_to "Import", import_project_project_members_path(@project), class: "btn btn-default", title: "Import members from another project" diff --git a/app/views/projects/project_members/_new_shared_group.html.haml b/app/views/projects/project_members/_new_shared_group.html.haml index 643569db646..c10ef648a8f 100644 --- a/app/views/projects/project_members/_new_shared_group.html.haml +++ b/app/views/projects/project_members/_new_shared_group.html.haml @@ -1,6 +1,6 @@ .row .col-sm-12 - = form_tag namespace_project_group_links_path(@project.namespace, @project), class: 'js-requires-input', method: :post do + = form_tag project_group_links_path(@project), class: 'js-requires-input', method: :post do .form-group = label_tag :link_group_id, "Select a group to share with", class: "label-light" = groups_select_tag(:link_group_id, data: { skip_groups: @skip_groups }, class: "input-clamp", required: true) diff --git a/app/views/projects/project_members/_team.html.haml b/app/views/projects/project_members/_team.html.haml index 7b1a26043e1..7ed467c8841 100644 --- a/app/views/projects/project_members/_team.html.haml +++ b/app/views/projects/project_members/_team.html.haml @@ -5,7 +5,7 @@ %strong #{@project.name} %span.badge= @project_members.total_count - = form_tag namespace_project_settings_members_path(@project.namespace, @project), method: :get, class: 'form-inline member-search-form flex-project-members-form' do + = form_tag project_settings_members_path(@project), method: :get, class: 'form-inline member-search-form flex-project-members-form' do .form-group = search_field_tag :search, params[:search], { placeholder: 'Find existing members by name', class: 'form-control', spellcheck: false } %button.member-search-btn{ type: "submit", "aria-label" => "Submit search" } diff --git a/app/views/projects/project_members/import.html.haml b/app/views/projects/project_members/import.html.haml index 42ce4f8001b..03b33eb2da7 100644 --- a/app/views/projects/project_members/import.html.haml +++ b/app/views/projects/project_members/import.html.haml @@ -5,11 +5,11 @@ %p.light Only project members will be imported. Group members will be skipped. %hr -= form_tag apply_import_namespace_project_project_members_path(@project.namespace, @project), method: 'post', class: 'form-horizontal' do += form_tag apply_import_project_project_members_path(@project), method: 'post', class: 'form-horizontal' do .form-group = label_tag :source_project_id, "Project", class: 'control-label' .col-sm-10= select_tag(:source_project_id, options_from_collection_for_select(current_user.authorized_projects, :id, :name_with_namespace), prompt: "Select project", class: "select2 lg", required: true) .form-actions = button_tag 'Import project members', class: "btn btn-create" - = link_to "Cancel", namespace_project_settings_members_path(@project.namespace, @project), class: "btn btn-cancel" + = link_to "Cancel", project_settings_members_path(@project), class: "btn btn-cancel" diff --git a/app/views/projects/protected_branches/_matching_branch.html.haml b/app/views/projects/protected_branches/_matching_branch.html.haml index 27896272733..98793d632e6 100644 --- a/app/views/projects/protected_branches/_matching_branch.html.haml +++ b/app/views/projects/protected_branches/_matching_branch.html.haml @@ -6,5 +6,5 @@ %span.label.label-info.prepend-left-5 default %td - commit = @project.commit(matching_branch.name) - = link_to(commit.short_id, namespace_project_commit_path(@project.namespace, @project, commit.id), class: 'commit-sha') + = link_to(commit.short_id, project_commit_path(@project, commit.id), class: 'commit-sha') = time_ago_with_tooltip(commit.committed_date) diff --git a/app/views/projects/protected_branches/_protected_branch.html.haml b/app/views/projects/protected_branches/_protected_branch.html.haml index 0f80de94392..e4dadc42cc0 100644 --- a/app/views/projects/protected_branches/_protected_branch.html.haml +++ b/app/views/projects/protected_branches/_protected_branch.html.haml @@ -1,4 +1,4 @@ -%tr.js-protected-branch-edit-form{ data: { url: namespace_project_protected_branch_path(@project.namespace, @project, protected_branch) } } +%tr.js-protected-branch-edit-form{ data: { url: project_protected_branch_path(@project, protected_branch) } } %td %span.ref-name= protected_branch.name @@ -7,10 +7,10 @@ %td - if protected_branch.wildcard? - matching_branches = protected_branch.matching(repository.branches) - = link_to pluralize(matching_branches.count, "matching branch"), namespace_project_protected_branch_path(@project.namespace, @project, protected_branch) + = link_to pluralize(matching_branches.count, "matching branch"), project_protected_branch_path(@project, protected_branch) - else - if commit = protected_branch.commit - = link_to(commit.short_id, namespace_project_commit_path(@project.namespace, @project, commit.id), class: 'commit-sha') + = link_to(commit.short_id, project_commit_path(@project, commit.id), class: 'commit-sha') = time_ago_with_tooltip(commit.committed_date) - else (branch was removed from repository) diff --git a/app/views/projects/protected_tags/_matching_tag.html.haml b/app/views/projects/protected_tags/_matching_tag.html.haml index f17353df122..05f102d1ca3 100644 --- a/app/views/projects/protected_tags/_matching_tag.html.haml +++ b/app/views/projects/protected_tags/_matching_tag.html.haml @@ -6,5 +6,5 @@ %span.label.label-info.prepend-left-5 default %td - commit = @project.commit(matching_tag.name) - = link_to(commit.short_id, namespace_project_commit_path(@project.namespace, @project, commit.id), class: 'commit-sha') + = link_to(commit.short_id, project_commit_path(@project, commit.id), class: 'commit-sha') = time_ago_with_tooltip(commit.committed_date) diff --git a/app/views/projects/protected_tags/_protected_tag.html.haml b/app/views/projects/protected_tags/_protected_tag.html.haml index f11ce0483a9..5162da5e429 100644 --- a/app/views/projects/protected_tags/_protected_tag.html.haml +++ b/app/views/projects/protected_tags/_protected_tag.html.haml @@ -1,4 +1,4 @@ -%tr.js-protected-tag-edit-form{ data: { url: namespace_project_protected_tag_path(@project.namespace, @project, protected_tag) } } +%tr.js-protected-tag-edit-form{ data: { url: project_protected_tag_path(@project, protected_tag) } } %td %span.ref-name= protected_tag.name @@ -7,10 +7,10 @@ %td - if protected_tag.wildcard? - matching_tags = protected_tag.matching(repository.tags) - = link_to pluralize(matching_tags.count, "matching tag"), namespace_project_protected_tag_path(@project.namespace, @project, protected_tag) + = link_to pluralize(matching_tags.count, "matching tag"), project_protected_tag_path(@project, protected_tag) - else - if commit = protected_tag.commit - = link_to(commit.short_id, namespace_project_commit_path(@project.namespace, @project, commit.id), class: 'commit-sha') + = link_to(commit.short_id, project_commit_path(@project, commit.id), class: 'commit-sha') = time_ago_with_tooltip(commit.committed_date) - else (tag was removed from repository) diff --git a/app/views/projects/registry/repositories/_image.html.haml b/app/views/projects/registry/repositories/_image.html.haml index dcdc432b654..a0535edafc3 100644 --- a/app/views/projects/registry/repositories/_image.html.haml +++ b/app/views/projects/registry/repositories/_image.html.haml @@ -8,7 +8,7 @@ - if can?(current_user, :update_container_image, @project) .controls.hidden-xs.pull-right - = link_to namespace_project_container_registry_path(@project.namespace, @project, image), + = link_to project_container_registry_path(@project, image), class: 'btn btn-remove has-tooltip', title: 'Remove repository', data: { confirm: 'Are you sure?' }, @@ -30,4 +30,3 @@ = render partial: 'tag', collection: image.tags - else .nothing-here-block No tags in Container Registry for this container image. - diff --git a/app/views/projects/registry/repositories/_tag.html.haml b/app/views/projects/registry/repositories/_tag.html.haml index 378a23f07e6..0b082a2137f 100644 --- a/app/views/projects/registry/repositories/_tag.html.haml +++ b/app/views/projects/registry/repositories/_tag.html.haml @@ -25,7 +25,7 @@ - if can?(current_user, :update_container_image, @project) %td.content .controls.hidden-xs.pull-right - = link_to namespace_project_registry_repository_tag_path(@project.namespace, @project, tag.repository, tag.name), + = link_to project_registry_repository_tag_path(@project, tag.repository, tag.name), method: :delete, class: 'btn btn-remove has-tooltip', title: 'Remove tag', diff --git a/app/views/projects/releases/edit.html.haml b/app/views/projects/releases/edit.html.haml index 93ee9382a6e..0a5a38a3694 100644 --- a/app/views/projects/releases/edit.html.haml +++ b/app/views/projects/releases/edit.html.haml @@ -10,11 +10,11 @@ %strong= @tag.name - = form_for(@release, method: :put, url: namespace_project_tag_release_path(@project.namespace, @project, @tag.name), html: { class: 'form-horizontal common-note-form release-form js-quick-submit' }) do |f| + = form_for(@release, method: :put, url: project_tag_release_path(@project, @tag.name), html: { class: 'form-horizontal common-note-form release-form js-quick-submit' }) do |f| = render layout: 'projects/md_preview', locals: { url: preview_markdown_path(@project), referenced_users: true } do = render 'projects/zen', f: f, attr: :description, classes: 'note-textarea', placeholder: "Write your release notes or drag files here..." = render 'shared/notes/hints' .error-alert .prepend-top-default = f.submit 'Save changes', class: 'btn btn-save' - = link_to "Cancel", namespace_project_tag_path(@project.namespace, @project, @tag.name), class: "btn btn-default btn-cancel" + = link_to "Cancel", project_tag_path(@project, @tag.name), class: "btn btn-default btn-cancel" diff --git a/app/views/projects/remove_fork.js.haml b/app/views/projects/remove_fork.js.haml index 17b9fecfeb1..6d083c5c516 100644 --- a/app/views/projects/remove_fork.js.haml +++ b/app/views/projects/remove_fork.js.haml @@ -1,2 +1,2 @@ :plain - location.href = "#{edit_namespace_project_path(@project.namespace, @project)}"; + location.href = "#{edit_project_path(@project)}"; diff --git a/app/views/projects/repositories/_feed.html.haml b/app/views/projects/repositories/_feed.html.haml index d9c39fb87b7..170f9e259df 100644 --- a/app/views/projects/repositories/_feed.html.haml +++ b/app/views/projects/repositories/_feed.html.haml @@ -1,7 +1,7 @@ - commit = update %tr %td - = link_to namespace_project_commits_path(@project.namespace, @project, commit.head.name) do + = link_to project_commits_path(@project, commit.head.name) do %strong = commit.head.name - if @project.root_ref?(commit.head.name) @@ -9,7 +9,7 @@ %td %div - = link_to namespace_project_commits_path(@project.namespace, @project, commit.id) do + = link_to project_commits_path(@project, commit.id) do %code= commit.short_id = image_tag avatar_icon(commit.author_email), class: "", width: 16, alt: '' = markdown(truncate(commit.title, length: 40), pipeline: :single_line, author: commit.author) diff --git a/app/views/projects/runners/_runner.html.haml b/app/views/projects/runners/_runner.html.haml index 674f87e8220..abc97bcdff5 100644 --- a/app/views/projects/runners/_runner.html.haml +++ b/app/views/projects/runners/_runner.html.haml @@ -9,7 +9,7 @@ = icon('lock', class: 'has-tooltip', title: 'Locked to current projects') %small - = link_to edit_namespace_project_runner_path(@project.namespace, @project, runner) do + = link_to edit_project_runner_path(@project, runner) do %i.fa.fa-edit.btn - else %span.commit-sha @@ -21,7 +21,7 @@ = link_to 'Remove Runner', runner_path(runner), data: { confirm: "Are you sure?" }, method: :delete, class: 'btn btn-danger btn-sm' - else - runner_project = @project.runner_projects.find_by(runner_id: runner) - = link_to 'Disable for this project', namespace_project_runner_project_path(@project.namespace, @project, runner_project), data: { confirm: "Are you sure?" }, method: :delete, class: 'btn btn-danger btn-sm' + = link_to 'Disable for this project', project_runner_project_path(@project, runner_project), data: { confirm: "Are you sure?" }, method: :delete, class: 'btn btn-danger btn-sm' - elsif runner.specific? = form_for [@project.namespace.becomes(Namespace), @project, @project.runner_projects.new] do |f| = f.hidden_field :runner_id, value: runner.id diff --git a/app/views/projects/runners/_shared_runners.html.haml b/app/views/projects/runners/_shared_runners.html.haml index 0671dd66e78..a4e820628f3 100644 --- a/app/views/projects/runners/_shared_runners.html.haml +++ b/app/views/projects/runners/_shared_runners.html.haml @@ -9,10 +9,10 @@ on GitLab.com). %hr - if @project.shared_runners_enabled? - = link_to toggle_shared_runners_namespace_project_runners_path(@project.namespace, @project), class: 'btn btn-warning', method: :post do + = link_to toggle_shared_runners_project_runners_path(@project), class: 'btn btn-warning', method: :post do Disable shared Runners - else - = link_to toggle_shared_runners_namespace_project_runners_path(@project.namespace, @project), class: 'btn btn-success', method: :post do + = link_to toggle_shared_runners_project_runners_path(@project), class: 'btn btn-success', method: :post do Enable shared Runners for this project diff --git a/app/views/projects/services/_form.html.haml b/app/views/projects/services/_form.html.haml index 6dffc026392..b842fd57cf3 100644 --- a/app/views/projects/services/_form.html.haml +++ b/app/views/projects/services/_form.html.haml @@ -9,20 +9,21 @@ %p= @service.description .col-lg-9 - = form_for(@service, as: :service, url: namespace_project_service_path(@project.namespace, @project, @service.to_param), method: :put, html: { class: 'gl-show-field-errors form-horizontal js-integration-settings-form', data: { 'can-test' => @service.can_test?, 'test-url' => test_namespace_project_service_path } }) do |form| + = form_for(@service, as: :service, url: project_service_path(@project, @service.to_param), method: :put, html: { class: 'gl-show-field-errors form-horizontal js-integration-settings-form', data: { 'can-test' => @service.can_test?, 'test-url' => test_project_service_path(@project, @service) } }) do |form| = render 'shared/service_settings', form: form, subject: @service - .footer-block.row-content-block - %button.btn.btn-save{ type: 'submit' } - = icon('spinner spin', class: 'hidden js-btn-spinner') - %span.js-btn-label - Save changes - - - if @service.valid? && @service.activated? - - unless @service.can_test? - - disabled_class = 'disabled' - - disabled_title = @service.disabled_title + - if @service.editable? + .footer-block.row-content-block + %button.btn.btn-save{ type: 'submit' } + = icon('spinner spin', class: 'hidden js-btn-spinner') + %span.js-btn-label + Save changes + + - if @service.valid? && @service.activated? + - unless @service.can_test? + - disabled_class = 'disabled' + - disabled_title = @service.disabled_title - = link_to 'Cancel', namespace_project_settings_integrations_path(@project.namespace, @project), class: 'btn btn-cancel' + = link_to 'Cancel', project_settings_integrations_path(@project), class: 'btn btn-cancel' - if lookup_context.template_exists?('show', "projects/services/#{@service.to_param}", true) %hr diff --git a/app/views/projects/services/_index.html.haml b/app/views/projects/services/_index.html.haml index 997b702da33..915c6b22162 100644 --- a/app/views/projects/services/_index.html.haml +++ b/app/views/projects/services/_index.html.haml @@ -21,7 +21,7 @@ %td{ "aria-label" => "#{service.title}: status " + (service.activated? ? "on" : "off") } = boolean_to_icon service.activated? %td - = link_to edit_namespace_project_service_path(@project.namespace, @project, service.to_param) do + = link_to edit_project_service_path(@project, service.to_param) do %strong= service.title %td.hidden-xs = service.description diff --git a/app/views/projects/services/mattermost_slash_commands/_installation_info.html.haml b/app/views/projects/services/mattermost_slash_commands/_installation_info.html.haml index fcc91be11cd..44c0b7a90dc 100644 --- a/app/views/projects/services/mattermost_slash_commands/_installation_info.html.haml +++ b/app/views/projects/services/mattermost_slash_commands/_installation_info.html.haml @@ -2,6 +2,6 @@ - unless @service.activated? .row .col-sm-9.col-sm-offset-3 - = link_to new_namespace_project_mattermost_path(@project.namespace, @project), class: 'btn btn-lg' do + = link_to new_project_mattermost_path(@project), class: 'btn btn-lg' do = custom_icon('mattermost_logo', size: 15) Add to Mattermost diff --git a/app/views/projects/services/prometheus/_show.html.haml b/app/views/projects/services/prometheus/_show.html.haml index c4ac384ca1a..0996ec06ab7 100644 --- a/app/views/projects/services/prometheus/_show.html.haml +++ b/app/views/projects/services/prometheus/_show.html.haml @@ -11,7 +11,7 @@ = link_to 'More information', '#' .col-lg-9 - .panel.panel-default.js-panel-monitored-metrics{ data: { "active-metrics" => "#{namespace_project_prometheus_active_metrics_path(@project.namespace, @project, :json)}" } } + .panel.panel-default.js-panel-monitored-metrics{ data: { "active-metrics" => "#{project_prometheus_active_metrics_path(@project, :json)}" } } .panel-heading %h3.panel-title Monitored diff --git a/app/views/projects/settings/_head.html.haml b/app/views/projects/settings/_head.html.haml index 00bd563999f..b5773acb5a4 100644 --- a/app/views/projects/settings/_head.html.haml +++ b/app/views/projects/settings/_head.html.haml @@ -19,16 +19,16 @@ %span Integrations = nav_link(controller: :repository) do - = link_to namespace_project_settings_repository_path(@project.namespace, @project), title: 'Repository' do + = link_to project_settings_repository_path(@project), title: 'Repository' do %span Repository - if @project.feature_available?(:builds, current_user) = nav_link(controller: :ci_cd) do - = link_to namespace_project_settings_ci_cd_path(@project.namespace, @project), title: 'Pipelines' do + = link_to project_settings_ci_cd_path(@project), title: 'Pipelines' do %span Pipelines - if Gitlab.config.pages.enabled = nav_link(controller: :pages) do - = link_to namespace_project_pages_path(@project.namespace, @project), title: 'Pages' do + = link_to project_pages_path(@project), title: 'Pages' do %span Pages diff --git a/app/views/projects/settings/integrations/_project_hook.html.haml b/app/views/projects/settings/integrations/_project_hook.html.haml index a6640592dba..00700e286c3 100644 --- a/app/views/projects/settings/integrations/_project_hook.html.haml +++ b/app/views/projects/settings/integrations/_project_hook.html.haml @@ -9,8 +9,8 @@ .col-md-4.col-lg-5.text-right-lg.prepend-top-5 %span.append-right-10.inline SSL Verification: #{hook.enable_ssl_verification ? "enabled" : "disabled"} - = link_to "Edit", edit_namespace_project_hook_path(@project.namespace, @project, hook), class: "btn btn-sm" - = link_to "Test", test_namespace_project_hook_path(@project.namespace, @project, hook), class: "btn btn-sm" - = link_to namespace_project_hook_path(@project.namespace, @project, hook), data: { confirm: 'Are you sure?'}, method: :delete, class: "btn btn-transparent" do + = link_to "Edit", edit_project_hook_path(@project, hook), class: "btn btn-sm" + = link_to "Test", test_project_hook_path(@project, hook), class: "btn btn-sm" + = link_to project_hook_path(@project, hook), data: { confirm: 'Are you sure?'}, method: :delete, class: "btn btn-transparent" do %span.sr-only Remove = icon('trash') diff --git a/app/views/projects/show.atom.builder b/app/views/projects/show.atom.builder index ed34f5c0520..39f8cb9a0e0 100644 --- a/app/views/projects/show.atom.builder +++ b/app/views/projects/show.atom.builder @@ -1,7 +1,7 @@ xml.title "#{@project.name} activity" -xml.link href: namespace_project_url(@project.namespace, @project, rss_url_options), rel: "self", type: "application/atom+xml" -xml.link href: namespace_project_url(@project.namespace, @project), rel: "alternate", type: "text/html" -xml.id namespace_project_url(@project.namespace, @project) +xml.link href: project_url(@project, rss_url_options), rel: "self", type: "application/atom+xml" +xml.link href: project_url(@project), rel: "alternate", type: "text/html" +xml.id project_url(@project) xml.updated @events[0].updated_at.xmlschema if @events[0] xml << render(@events) if @events.any? diff --git a/app/views/projects/show.html.haml b/app/views/projects/show.html.haml index cbf28a61870..75bbcf82b98 100644 --- a/app/views/projects/show.html.haml +++ b/app/views/projects/show.html.haml @@ -2,7 +2,7 @@ - @breadcrumb_title = "Project" = content_for :meta_tags do - = auto_discovery_link_tag(:atom, namespace_project_path(@project.namespace, @project, rss_url_options), title: "#{@project.name} activity") + = auto_discovery_link_tag(:atom, project_path(@project, rss_url_options), title: "#{@project.name} activity") = content_for :flash_message do - if current_user && can?(current_user, :download_code, @project) @@ -17,16 +17,16 @@ %nav.project-stats{ class: container_class } %ul.nav %li - = link_to project_files_path(@project) do + = link_to project_tree_path(@project) do #{_('Files')} (#{storage_counter(@project.statistics.total_repository_size)}) %li - = link_to namespace_project_commits_path(@project.namespace, @project, current_ref) do + = link_to project_commits_path(@project, current_ref) do #{n_('Commit', 'Commits', @project.statistics.commit_count)} (#{number_with_delimiter(@project.statistics.commit_count)}) %li - = link_to namespace_project_branches_path(@project.namespace, @project) do + = link_to project_branches_path(@project) do #{n_('Branch', 'Branches', @repository.branch_count)} (#{number_with_delimiter(@repository.branch_count)}) %li - = link_to namespace_project_tags_path(@project.namespace, @project) do + = link_to project_tags_path(@project) do #{n_('Tag', 'Tags', @repository.tag_count)} (#{number_with_delimiter(@repository.tag_count)}) - if default_project_view != 'readme' && @repository.readme @@ -74,7 +74,7 @@ = link_to add_special_file_path(@project, file_name: '.gitlab-ci.yml', commit_message: 'Set up auto deploy', branch_name: 'auto-deploy', context: 'autodeploy') do #{ _('Set up auto deploy') } -%div{ class: container_class } +%div{ class: [container_class, ("limit-container-width" unless fluid_layout)] } - if @project.archived? .text-warning.center.prepend-top-20 %p diff --git a/app/views/projects/snippets/_actions.html.haml b/app/views/projects/snippets/_actions.html.haml index 34ee4ff1937..f09871c7fcc 100644 --- a/app/views/projects/snippets/_actions.html.haml +++ b/app/views/projects/snippets/_actions.html.haml @@ -2,16 +2,16 @@ .hidden-xs - if can?(current_user, :update_project_snippet, @snippet) - = link_to edit_namespace_project_snippet_path(@project.namespace, @project, @snippet), class: "btn btn-grouped" do + = link_to edit_project_snippet_path(@project, @snippet), class: "btn btn-grouped" do Edit - if can?(current_user, :update_project_snippet, @snippet) - = link_to namespace_project_snippet_path(@project.namespace, @project, @snippet), method: :delete, data: { confirm: "Are you sure?" }, class: "btn btn-grouped btn-inverted btn-remove", title: 'Delete Snippet' do + = link_to project_snippet_path(@project, @snippet), method: :delete, data: { confirm: "Are you sure?" }, class: "btn btn-grouped btn-inverted btn-remove", title: 'Delete Snippet' do Delete - if can?(current_user, :create_project_snippet, @project) - = link_to new_namespace_project_snippet_path(@project.namespace, @project), class: 'btn btn-grouped btn-inverted btn-create', title: "New snippet" do + = link_to new_project_snippet_path(@project), class: 'btn btn-grouped btn-inverted btn-create', title: "New snippet" do New snippet - if @snippet.submittable_as_spam_by?(current_user) - = link_to 'Submit as spam', mark_as_spam_namespace_project_snippet_path(@project.namespace, @project, @snippet), method: :post, class: 'btn btn-grouped btn-spam', title: 'Submit as spam' + = link_to 'Submit as spam', mark_as_spam_project_snippet_path(@project, @snippet), method: :post, class: 'btn btn-grouped btn-spam', title: 'Submit as spam' - if can?(current_user, :create_project_snippet, @project) || can?(current_user, :update_project_snippet, @snippet) .visible-xs-block.dropdown %button.btn.btn-default.btn-block.append-bottom-0.prepend-top-5{ data: { toggle: "dropdown" } } @@ -21,16 +21,16 @@ %ul - if can?(current_user, :create_project_snippet, @project) %li - = link_to new_namespace_project_snippet_path(@project.namespace, @project), title: "New snippet" do + = link_to new_project_snippet_path(@project), title: "New snippet" do New snippet - if can?(current_user, :update_project_snippet, @snippet) %li - = link_to namespace_project_snippet_path(@project.namespace, @project, @snippet), method: :delete, data: { confirm: "Are you sure?" }, title: 'Delete Snippet' do + = link_to project_snippet_path(@project, @snippet), method: :delete, data: { confirm: "Are you sure?" }, title: 'Delete Snippet' do Delete - if can?(current_user, :update_project_snippet, @snippet) %li - = link_to edit_namespace_project_snippet_path(@project.namespace, @project, @snippet) do + = link_to edit_project_snippet_path(@project, @snippet) do Edit - if @snippet.submittable_as_spam_by?(current_user) %li - = link_to 'Submit as spam', mark_as_spam_namespace_project_snippet_path(@project.namespace, @project, @snippet), method: :post + = link_to 'Submit as spam', mark_as_spam_project_snippet_path(@project, @snippet), method: :post diff --git a/app/views/projects/snippets/edit.html.haml b/app/views/projects/snippets/edit.html.haml index 24b92094b7d..d41cc8e0425 100644 --- a/app/views/projects/snippets/edit.html.haml +++ b/app/views/projects/snippets/edit.html.haml @@ -3,4 +3,4 @@ %h3.page-title Edit Snippet %hr -= render "shared/snippets/form", url: namespace_project_snippet_path(@project.namespace, @project, @snippet) += render "shared/snippets/form", url: project_snippet_path(@project, @snippet) diff --git a/app/views/projects/snippets/index.html.haml b/app/views/projects/snippets/index.html.haml index f6d8f5e8c4f..ccc5fe80755 100644 --- a/app/views/projects/snippets/index.html.haml +++ b/app/views/projects/snippets/index.html.haml @@ -11,6 +11,6 @@ .nav-controls{ class: ("visible-xs" if show_new_nav?) } - if can?(current_user, :create_project_snippet, @project) - = link_to "New snippet", new_namespace_project_snippet_path(@project.namespace, @project), class: "btn btn-new", title: "New snippet" + = link_to "New snippet", new_project_snippet_path(@project), class: "btn btn-new", title: "New snippet" = render 'snippets/snippets' diff --git a/app/views/projects/snippets/new.html.haml b/app/views/projects/snippets/new.html.haml index cfed3a79bc5..d3e6b456f48 100644 --- a/app/views/projects/snippets/new.html.haml +++ b/app/views/projects/snippets/new.html.haml @@ -3,4 +3,4 @@ %h3.page-title New Snippet %hr -= render "shared/snippets/form", url: namespace_project_snippets_path(@project.namespace, @project, @snippet) += render "shared/snippets/form", url: project_snippets_path(@project, @snippet) diff --git a/app/views/projects/tags/_tag.html.haml b/app/views/projects/tags/_tag.html.haml index 44cb734d7b9..468ab922542 100644 --- a/app/views/projects/tags/_tag.html.haml +++ b/app/views/projects/tags/_tag.html.haml @@ -2,7 +2,7 @@ - release = @releases.find { |release| release.tag == tag.name } %li.flex-row .row-main-content.str-truncated - = link_to namespace_project_tag_path(@project.namespace, @project, tag.name), class: 'item-title ref-name' do + = link_to project_tag_path(@project, tag.name), class: 'item-title ref-name' do = icon('tag') = tag.name @@ -29,9 +29,9 @@ = render 'projects/buttons/download', project: @project, ref: tag.name, pipeline: @tags_pipelines[tag.name] - if can?(current_user, :push_code, @project) - = link_to edit_namespace_project_tag_release_path(@project.namespace, @project, tag.name), class: 'btn has-tooltip', title: "Edit release notes", data: { container: "body" } do + = link_to edit_project_tag_release_path(@project, tag.name), class: 'btn has-tooltip', title: "Edit release notes", data: { container: "body" } do = icon("pencil") - if can?(current_user, :admin_project, @project) - = link_to namespace_project_tag_path(@project.namespace, @project, tag.name), class: "btn btn-remove remove-row has-tooltip #{protected_tag?(@project, tag) ? 'disabled' : ''}", title: "Delete tag", method: :delete, data: { confirm: "Deleting the '#{tag.name}' tag cannot be undone. Are you sure?", container: 'body' }, remote: true do + = link_to project_tag_path(@project, tag.name), class: "btn btn-remove remove-row has-tooltip #{protected_tag?(@project, tag) ? 'disabled' : ''}", title: "Delete tag", method: :delete, data: { confirm: "Deleting the '#{tag.name}' tag cannot be undone. Are you sure?", container: 'body' }, remote: true do = icon("trash-o") diff --git a/app/views/projects/tags/index.html.haml b/app/views/projects/tags/index.html.haml index c0b801124b9..7fafbe1c432 100644 --- a/app/views/projects/tags/index.html.haml +++ b/app/views/projects/tags/index.html.haml @@ -27,7 +27,7 @@ %li = link_to title, filter_tags_path(sort: value), class: ("is-active" if @sort == value) - if can?(current_user, :push_code, @project) - = link_to new_namespace_project_tag_path(@project.namespace, @project), class: 'btn btn-create new-tag-btn' do + = link_to new_project_tag_path(@project), class: 'btn btn-create new-tag-btn' do New tag .tags diff --git a/app/views/projects/tags/new.html.haml b/app/views/projects/tags/new.html.haml index 52af295bddd..f1bbaf40387 100644 --- a/app/views/projects/tags/new.html.haml +++ b/app/views/projects/tags/new.html.haml @@ -39,7 +39,7 @@ .help-block Optionally, add release notes to the tag. They will be stored in the GitLab database and displayed on the tags page. .form-actions = button_tag 'Create tag', class: 'btn btn-create', tabindex: 3 - = link_to 'Cancel', namespace_project_tags_path(@project.namespace, @project), class: 'btn btn-cancel' + = link_to 'Cancel', project_tags_path(@project), class: 'btn btn-cancel' :javascript window.gl = window.gl || { }; diff --git a/app/views/projects/tags/show.html.haml b/app/views/projects/tags/show.html.haml index 2b81ce4b9fa..d02cd70f4c3 100644 --- a/app/views/projects/tags/show.html.haml +++ b/app/views/projects/tags/show.html.haml @@ -19,17 +19,17 @@ .nav-controls.controls-flex - if can?(current_user, :push_code, @project) - = link_to edit_namespace_project_tag_release_path(@project.namespace, @project, @tag.name), class: 'btn controls-item has-tooltip', title: 'Edit release notes' do + = link_to edit_project_tag_release_path(@project, @tag.name), class: 'btn controls-item has-tooltip', title: 'Edit release notes' do = icon("pencil") - = link_to namespace_project_tree_path(@project.namespace, @project, @tag.name), class: 'btn controls-item has-tooltip', title: 'Browse files' do + = link_to project_tree_path(@project, @tag.name), class: 'btn controls-item has-tooltip', title: 'Browse files' do = icon('files-o') - = link_to namespace_project_commits_path(@project.namespace, @project, @tag.name), class: 'btn controls-item has-tooltip', title: 'Browse commits' do + = link_to project_commits_path(@project, @tag.name), class: 'btn controls-item has-tooltip', title: 'Browse commits' do = icon('history') .btn-container.controls-item = render 'projects/buttons/download', project: @project, ref: @tag.name - if can?(current_user, :admin_project, @project) .btn-container.controls-item-full - = link_to namespace_project_tag_path(@project.namespace, @project, @tag.name), class: "btn btn-remove remove-row has-tooltip #{protected_tag?(@project, @tag) ? 'disabled' : ''}", title: "Delete tag", method: :delete, data: { confirm: "Deleting the '#{@tag.name}' tag cannot be undone. Are you sure?" } do + = link_to project_tag_path(@project, @tag.name), class: "btn btn-remove remove-row has-tooltip #{protected_tag?(@project, @tag) ? 'disabled' : ''}", title: "Delete tag", method: :delete, data: { confirm: "Deleting the '#{@tag.name}' tag cannot be undone. Are you sure?" } do %i.fa.fa-trash-o - if @tag.message.present? diff --git a/app/views/projects/transfer.js.haml b/app/views/projects/transfer.js.haml index 17b9fecfeb1..6d083c5c516 100644 --- a/app/views/projects/transfer.js.haml +++ b/app/views/projects/transfer.js.haml @@ -1,2 +1,2 @@ :plain - location.href = "#{edit_namespace_project_path(@project.namespace, @project)}"; + location.href = "#{edit_project_path(@project)}"; diff --git a/app/views/projects/tree/_blob_item.html.haml b/app/views/projects/tree/_blob_item.html.haml index 425b460eb09..fd8175e1e01 100644 --- a/app/views/projects/tree/_blob_item.html.haml +++ b/app/views/projects/tree/_blob_item.html.haml @@ -2,7 +2,7 @@ %td.tree-item-file-name = tree_icon(type, blob_item.mode, blob_item.name) - file_name = blob_item.name - = link_to namespace_project_blob_path(@project.namespace, @project, tree_join(@id || @commit.id, blob_item.name)), title: file_name do + = link_to project_blob_path(@project, tree_join(@id || @commit.id, blob_item.name)), title: file_name do %span.str-truncated= file_name %td.hidden-xs.tree-commit %td.tree-time-ago.cgray.text-right diff --git a/app/views/projects/tree/_readme.html.haml b/app/views/projects/tree/_readme.html.haml index f9147815427..4579a912f39 100644 --- a/app/views/projects/tree/_readme.html.haml +++ b/app/views/projects/tree/_readme.html.haml @@ -2,8 +2,8 @@ %article.file-holder.readme-holder{ class: ("limited-width-container" unless fluid_layout) } .js-file-title.file-title = blob_icon readme.mode, readme.name - = link_to namespace_project_blob_path(@project.namespace, @project, tree_join(@ref, readme.path)) do + = link_to project_blob_path(@project, tree_join(@ref, readme.path)) do %strong = readme.name - = render 'projects/blob/viewer', viewer: readme.rich_viewer, viewer_url: namespace_project_blob_path(@project.namespace, @project, tree_join(@ref, readme.path), viewer: :rich, format: :json) + = render 'projects/blob/viewer', viewer: readme.rich_viewer, viewer_url: project_blob_path(@project, tree_join(@ref, readme.path), viewer: :rich, format: :json) diff --git a/app/views/projects/tree/_tree_commit_column.html.haml b/app/views/projects/tree/_tree_commit_column.html.haml index 84da16b6bb1..f3d4706809f 100644 --- a/app/views/projects/tree/_tree_commit_column.html.haml +++ b/app/views/projects/tree/_tree_commit_column.html.haml @@ -1,2 +1,2 @@ %span.str-truncated - = link_to_gfm commit.full_title, namespace_project_commit_path(@project.namespace, @project, commit.id), class: "tree-commit-link" + = link_to_gfm commit.full_title, project_commit_path(@project, commit.id), class: "tree-commit-link" diff --git a/app/views/projects/tree/_tree_content.html.haml b/app/views/projects/tree/_tree_content.html.haml index 7854e1305db..6560bd5ab3f 100644 --- a/app/views/projects/tree/_tree_content.html.haml +++ b/app/views/projects/tree/_tree_content.html.haml @@ -10,7 +10,7 @@ - if @path.present? %tr.tree-item %td.tree-item-file-name - = link_to "..", namespace_project_tree_path(@project.namespace, @project, up_dir_path), class: 'prepend-left-10' + = link_to "..", project_tree_path(@project, up_dir_path), class: 'prepend-left-10' %td %td.hidden-xs @@ -20,7 +20,7 @@ = render "projects/tree/readme", readme: tree.readme - if can_edit_tree? - = render 'projects/blob/upload', title: _('Upload New File'), placeholder: _('Upload New File'), button_title: _('Upload file'), form_path: namespace_project_create_blob_path(@project.namespace, @project, @id), method: :post + = render 'projects/blob/upload', title: _('Upload New File'), placeholder: _('Upload New File'), button_title: _('Upload file'), form_path: project_create_blob_path(@project, @id), method: :post = render 'projects/blob/new_dir' :javascript diff --git a/app/views/projects/tree/_tree_header.html.haml b/app/views/projects/tree/_tree_header.html.haml index 00da76349da..858418ff8df 100644 --- a/app/views/projects/tree/_tree_header.html.haml +++ b/app/views/projects/tree/_tree_header.html.haml @@ -4,11 +4,11 @@ %ul.breadcrumb.repo-breadcrumb %li - = link_to namespace_project_tree_path(@project.namespace, @project, @ref) do + = link_to project_tree_path(@project, @ref) do = @project.path - path_breadcrumbs do |title, path| %li - = link_to truncate(title, length: 40), namespace_project_tree_path(@project.namespace, @project, tree_join(@ref, path)) + = link_to truncate(title, length: 40), project_tree_path(@project, tree_join(@ref, path)) - if current_user %li @@ -23,7 +23,7 @@ %ul.dropdown-menu - if can_edit_tree? %li - = link_to namespace_project_new_blob_path(@project.namespace, @project, @id) do + = link_to project_new_blob_path(@project, @id) do = icon('pencil fw') #{ _('New file') } %li @@ -36,10 +36,10 @@ #{ _('New directory') } - elsif can?(current_user, :fork_project, @project) %li - - continue_params = { to: namespace_project_new_blob_path(@project.namespace, @project, @id), + - continue_params = { to: project_new_blob_path(@project, @id), notice: edit_in_new_fork_notice, notice_now: edit_in_new_fork_notice_now } - - fork_path = namespace_project_forks_path(@project.namespace, @project, namespace_key: current_user.namespace.id, + - fork_path = project_forks_path(@project, namespace_key: current_user.namespace.id, continue: continue_params) = link_to fork_path, method: :post do = icon('pencil fw') @@ -48,7 +48,7 @@ - continue_params = { to: request.fullpath, notice: edit_in_new_fork_notice + " Try to upload a file again.", notice_now: edit_in_new_fork_notice_now } - - fork_path = namespace_project_forks_path(@project.namespace, @project, namespace_key: current_user.namespace.id, + - fork_path = project_forks_path(@project, namespace_key: current_user.namespace.id, continue: continue_params) = link_to fork_path, method: :post do = icon('file fw') @@ -57,7 +57,7 @@ - continue_params = { to: request.fullpath, notice: edit_in_new_fork_notice + " Try to create a new directory again.", notice_now: edit_in_new_fork_notice_now } - - fork_path = namespace_project_forks_path(@project.namespace, @project, namespace_key: current_user.namespace.id, + - fork_path = project_forks_path(@project, namespace_key: current_user.namespace.id, continue: continue_params) = link_to fork_path, method: :post do = icon('folder fw') @@ -65,17 +65,17 @@ %li.divider %li - = link_to new_namespace_project_branch_path(@project.namespace, @project) do + = link_to new_project_branch_path(@project) do = icon('code-fork fw') #{ _('New branch') } %li - = link_to new_namespace_project_tag_path(@project.namespace, @project) do + = link_to new_project_tag_path(@project) do = icon('tags fw') #{ _('New tag') } .tree-controls = render 'projects/find_file_link' - = link_to s_('Commits|History'), namespace_project_commits_path(@project.namespace, @project, @id), class: 'btn' + = link_to s_('Commits|History'), project_commits_path(@project, @id), class: 'btn' = render 'projects/buttons/download', project: @project, ref: @ref diff --git a/app/views/projects/tree/_tree_item.html.haml b/app/views/projects/tree/_tree_item.html.haml index 15c9536133c..0c9c8750f2c 100644 --- a/app/views/projects/tree/_tree_item.html.haml +++ b/app/views/projects/tree/_tree_item.html.haml @@ -2,7 +2,7 @@ %td.tree-item-file-name = tree_icon(type, tree_item.mode, tree_item.name) - path = flatten_tree(tree_item) - = link_to namespace_project_tree_path(@project.namespace, @project, tree_join(@id || @commit.id, path)), title: path do + = link_to project_tree_path(@project, tree_join(@id || @commit.id, path)), title: path do %span.str-truncated= path %td.hidden-xs.tree-commit %td.tree-time-ago.text-right diff --git a/app/views/projects/tree/show.html.haml b/app/views/projects/tree/show.html.haml index 722e20763c8..3f3fa67f390 100644 --- a/app/views/projects/tree/show.html.haml +++ b/app/views/projects/tree/show.html.haml @@ -3,7 +3,7 @@ - page_title @path.presence || _("Files"), @ref = content_for :meta_tags do - = auto_discovery_link_tag(:atom, namespace_project_commits_url(@project.namespace, @project, @ref, rss_url_options), title: "#{@project.name}:#{@ref} commits") + = auto_discovery_link_tag(:atom, project_commits_url(@project, @ref, rss_url_options), title: "#{@project.name}:#{@ref} commits") = render "projects/commits/head" = render 'projects/last_push' diff --git a/app/views/projects/triggers/_trigger.html.haml b/app/views/projects/triggers/_trigger.html.haml index 9b5f63ae81a..6249c32b7cc 100644 --- a/app/views/projects/triggers/_trigger.html.haml +++ b/app/views/projects/triggers/_trigger.html.haml @@ -33,10 +33,10 @@ - take_ownership_confirmation = "By taking ownership you will bind this trigger to your user account. With this the trigger will have access to all your projects as if it was you. Are you sure?" - revoke_trigger_confirmation = "By revoking a trigger you will break any processes making use of it. Are you sure?" - if trigger.owner != current_user && can?(current_user, :manage_trigger, trigger) - = link_to 'Take ownership', take_ownership_namespace_project_trigger_path(@project.namespace, @project, trigger), data: { confirm: take_ownership_confirmation }, method: :post, class: "btn btn-default btn-sm btn-trigger-take-ownership" + = link_to 'Take ownership', take_ownership_project_trigger_path(@project, trigger), data: { confirm: take_ownership_confirmation }, method: :post, class: "btn btn-default btn-sm btn-trigger-take-ownership" - if can?(current_user, :admin_trigger, trigger) - = link_to edit_namespace_project_trigger_path(@project.namespace, @project, trigger), method: :get, title: "Edit", class: "btn btn-default btn-sm" do + = link_to edit_project_trigger_path(@project, trigger), method: :get, title: "Edit", class: "btn btn-default btn-sm" do %i.fa.fa-pencil - if can?(current_user, :manage_trigger, trigger) - = link_to namespace_project_trigger_path(@project.namespace, @project, trigger), data: { confirm: revoke_trigger_confirmation }, method: :delete, title: "Revoke", class: "btn btn-default btn-warning btn-sm btn-trigger-revoke" do + = link_to project_trigger_path(@project, trigger), data: { confirm: revoke_trigger_confirmation }, method: :delete, title: "Revoke", class: "btn btn-default btn-warning btn-sm btn-trigger-revoke" do %i.fa.fa-trash diff --git a/app/views/projects/update.js.haml b/app/views/projects/update.js.haml index dcf1f767bf7..2c05ebe52ae 100644 --- a/app/views/projects/update.js.haml +++ b/app/views/projects/update.js.haml @@ -1,6 +1,6 @@ - if @project.valid? :plain - location.href = "#{edit_namespace_project_path(@project.namespace, @project)}"; + location.href = "#{edit_project_path(@project)}"; - else :plain $(".project-edit-errors").html("#{escape_javascript(render('errors'))}"); diff --git a/app/views/projects/variables/_table.html.haml b/app/views/projects/variables/_table.html.haml index 59cd3c4b592..4ce6a828812 100644 --- a/app/views/projects/variables/_table.html.haml +++ b/app/views/projects/variables/_table.html.haml @@ -18,11 +18,11 @@ %td.variable-value{ "data-value" => variable.value }****** %td.variable-protected= Gitlab::Utils.boolean_to_yes_no(variable.protected) %td.variable-menu - = link_to namespace_project_variable_path(@project.namespace, @project, variable), class: "btn btn-transparent btn-variable-edit" do + = link_to project_variable_path(@project, variable), class: "btn btn-transparent btn-variable-edit" do %span.sr-only Update = icon("pencil") - = link_to namespace_project_variable_path(@project.namespace, @project, variable), class: "btn btn-transparent btn-variable-delete", method: :delete, data: { confirm: "Are you sure?" } do + = link_to project_variable_path(@project, variable), class: "btn btn-transparent btn-variable-delete", method: :delete, data: { confirm: "Are you sure?" } do %span.sr-only Remove = icon("trash") diff --git a/app/views/projects/wikis/_form.html.haml b/app/views/projects/wikis/_form.html.haml index c10b3004bc3..fc6b7a33943 100644 --- a/app/views/projects/wikis/_form.html.haml +++ b/app/views/projects/wikis/_form.html.haml @@ -12,7 +12,7 @@ .form-group .col-sm-12= f.label :content, class: 'control-label-full-width' .col-sm-12 - = render layout: 'projects/md_preview', locals: { url: namespace_project_wiki_preview_markdown_path(@project.namespace, @project, @page.slug) } do + = render layout: 'projects/md_preview', locals: { url: project_wiki_preview_markdown_path(@project, @page.slug) } do = render 'projects/zen', f: f, attr: :content, classes: 'note-textarea', placeholder: 'Write your content or drag files here...' = render 'shared/notes/hints' @@ -36,8 +36,8 @@ - if @page && @page.persisted? = f.submit 'Save changes', class: "btn-save btn" .pull-right - = link_to "Cancel", namespace_project_wiki_path(@project.namespace, @project, @page), class: "btn btn-cancel btn-grouped" + = link_to "Cancel", project_wiki_path(@project, @page), class: "btn btn-cancel btn-grouped" - else = f.submit 'Create page', class: "btn-create btn" .pull-right - = link_to "Cancel", namespace_project_wiki_path(@project.namespace, @project, :home), class: "btn btn-cancel" + = link_to "Cancel", project_wiki_path(@project, :home), class: "btn btn-cancel" diff --git a/app/views/projects/wikis/_main_links.html.haml b/app/views/projects/wikis/_main_links.html.haml index 6a578dbf640..3bbd8042c3a 100644 --- a/app/views/projects/wikis/_main_links.html.haml +++ b/app/views/projects/wikis/_main_links.html.haml @@ -2,8 +2,8 @@ - if can?(current_user, :create_wiki, @project) = link_to '#modal-new-wiki', class: "add-new-wiki btn btn-new", "data-toggle" => "modal" do New page - = link_to namespace_project_wiki_history_path(@project.namespace, @project, @page), class: "btn" do + = link_to project_wiki_history_path(@project, @page), class: "btn" do Page history - if can?(current_user, :create_wiki, @project) && @page.latest? - = link_to namespace_project_wiki_edit_path(@project.namespace, @project, @page), class: "btn js-wiki-edit" do + = link_to project_wiki_edit_path(@project, @page), class: "btn js-wiki-edit" do Edit diff --git a/app/views/projects/wikis/_new.html.haml b/app/views/projects/wikis/_new.html.haml index 1e553940593..13dd8461433 100644 --- a/app/views/projects/wikis/_new.html.haml +++ b/app/views/projects/wikis/_new.html.haml @@ -9,7 +9,7 @@ .form-group = label_tag :new_wiki_path do %span Page slug - = text_field_tag :new_wiki_path, nil, placeholder: 'how-to-setup', class: 'form-control', required: true, :'data-wikis-path' => namespace_project_wikis_path(@project.namespace, @project), autofocus: true + = text_field_tag :new_wiki_path, nil, placeholder: 'how-to-setup', class: 'form-control', required: true, :'data-wikis-path' => project_wikis_path(@project), autofocus: true %span.new-wiki-page-slug-tip = icon('lightbulb-o') Tip: You can specify the full path for the new file. diff --git a/app/views/projects/wikis/_pages_wiki_page.html.haml b/app/views/projects/wikis/_pages_wiki_page.html.haml index 6298cf6c8da..7c2f562d422 100644 --- a/app/views/projects/wikis/_pages_wiki_page.html.haml +++ b/app/views/projects/wikis/_pages_wiki_page.html.haml @@ -1,5 +1,5 @@ %li - = link_to wiki_page.title, namespace_project_wiki_path(@project.namespace, @project, wiki_page) + = link_to wiki_page.title, project_wiki_path(@project, wiki_page) %small (#{wiki_page.format}) .pull-right %small Last edited #{time_ago_with_tooltip(wiki_page.commit.authored_date)} diff --git a/app/views/projects/wikis/_sidebar.html.haml b/app/views/projects/wikis/_sidebar.html.haml index c2f9e65015d..62873d3aa66 100644 --- a/app/views/projects/wikis/_sidebar.html.haml +++ b/app/views/projects/wikis/_sidebar.html.haml @@ -3,7 +3,7 @@ %a.gutter-toggle.pull-right.visible-xs-block.visible-sm-block.js-sidebar-wiki-toggle{ href: "#" } = icon('angle-double-right') - - git_access_url = namespace_project_wikis_git_access_path(@project.namespace, @project) + - git_access_url = project_wikis_git_access_path(@project) = link_to git_access_url, class: active_nav_link?(path: 'wikis#git_access') ? 'active' : '' do = succeed ' ' do = icon('cloud-download') @@ -15,7 +15,7 @@ = render @sidebar_wiki_entries, context: 'sidebar' .block - = link_to namespace_project_wikis_pages_path(@project.namespace, @project), class: 'btn btn-block' do + = link_to project_wikis_pages_path(@project), class: 'btn btn-block' do More Pages = render 'projects/wikis/new' diff --git a/app/views/projects/wikis/_sidebar_wiki_page.html.haml b/app/views/projects/wikis/_sidebar_wiki_page.html.haml index 0a61d90177b..2423ac6abce 100644 --- a/app/views/projects/wikis/_sidebar_wiki_page.html.haml +++ b/app/views/projects/wikis/_sidebar_wiki_page.html.haml @@ -1,3 +1,3 @@ %li{ class: active_when(params[:id] == wiki_page.slug) } - = link_to namespace_project_wiki_path(@project.namespace, @project, wiki_page) do + = link_to project_wiki_path(@project, wiki_page) do = wiki_page.title.capitalize diff --git a/app/views/projects/wikis/edit.html.haml b/app/views/projects/wikis/edit.html.haml index fbe192a40ec..df0ec14eb3b 100644 --- a/app/views/projects/wikis/edit.html.haml +++ b/app/views/projects/wikis/edit.html.haml @@ -8,7 +8,7 @@ .nav-text %h2.wiki-page-title - if @page.persisted? - = link_to @page.title.capitalize, namespace_project_wiki_path(@project.namespace, @project, @page) + = link_to @page.title.capitalize, project_wiki_path(@project, @page) - else = @page.title.capitalize %span.light @@ -23,10 +23,10 @@ = link_to '#modal-new-wiki', class: "add-new-wiki btn btn-new", "data-toggle" => "modal" do New page - if @page.persisted? - = link_to namespace_project_wiki_history_path(@project.namespace, @project, @page), class: "btn" do + = link_to project_wiki_history_path(@project, @page), class: "btn" do Page history - if can?(current_user, :admin_wiki, @project) - = link_to namespace_project_wiki_path(@project.namespace, @project, @page), data: { confirm: "Are you sure you want to delete this page?"}, method: :delete, class: "btn btn-danger" do + = link_to project_wiki_path(@project, @page), data: { confirm: "Are you sure you want to delete this page?"}, method: :delete, class: "btn btn-danger" do Delete = render 'form' diff --git a/app/views/projects/wikis/history.html.haml b/app/views/projects/wikis/history.html.haml index 0e47e2a5fa3..306feeff259 100644 --- a/app/views/projects/wikis/history.html.haml +++ b/app/views/projects/wikis/history.html.haml @@ -6,7 +6,7 @@ .nav-text %h2.wiki-page-title - = link_to @page.title.capitalize, namespace_project_wiki_path(@project.namespace, @project, @page) + = link_to @page.title.capitalize, project_wiki_path(@project, @page) %span.light · History diff --git a/app/views/projects/wikis/pages.html.haml b/app/views/projects/wikis/pages.html.haml index 5fba2b1a5ae..dece1fad0bb 100644 --- a/app/views/projects/wikis/pages.html.haml +++ b/app/views/projects/wikis/pages.html.haml @@ -9,7 +9,7 @@ Wiki Pages .nav-controls - = link_to namespace_project_wikis_git_access_path(@project.namespace, @project), class: 'btn' do + = link_to project_wikis_git_access_path(@project), class: 'btn' do = icon('cloud-download') Clone repository diff --git a/app/views/projects/wikis/show.html.haml b/app/views/projects/wikis/show.html.haml index 0ca811e2959..42602c6366b 100644 --- a/app/views/projects/wikis/show.html.haml +++ b/app/views/projects/wikis/show.html.haml @@ -23,7 +23,7 @@ - if @page.historical? .warning_message This is an old version of this page. - You can view the #{link_to "most recent version", namespace_project_wiki_path(@project.namespace, @project, @page)} or browse the #{link_to "history", namespace_project_wiki_history_path(@project.namespace, @project, @page)}. + You can view the #{link_to "most recent version", project_wiki_path(@project, @page)} or browse the #{link_to "history", project_wiki_history_path(@project, @page)}. .wiki-holder.prepend-top-default.append-bottom-default .wiki diff --git a/app/views/search/results/_blob.html.haml b/app/views/search/results/_blob.html.haml index 7f1f807e2e7..de473c23d66 100644 --- a/app/views/search/results/_blob.html.haml +++ b/app/views/search/results/_blob.html.haml @@ -3,7 +3,7 @@ .file-holder .js-file-title.file-title - ref = @search_results.repository_ref - - blob_link = namespace_project_blob_path(@project.namespace, @project, tree_join(ref, file_name)) + - blob_link = project_blob_path(@project, tree_join(ref, file_name)) = link_to blob_link do %i.fa.fa-file %strong diff --git a/app/views/search/results/_snippet_title.html.haml b/app/views/search/results/_snippet_title.html.haml index 026f404ce07..aef825691e0 100644 --- a/app/views/search/results/_snippet_title.html.haml +++ b/app/views/search/results/_snippet_title.html.haml @@ -11,7 +11,7 @@ %small.pull-right.cgray - if snippet_title.project_id? - = link_to snippet_title.project.name_with_namespace, namespace_project_path(snippet_title.project.namespace, snippet_title.project) + = link_to snippet_title.project.name_with_namespace, project_path(snippet_title.project) .snippet-info = snippet_title.to_reference diff --git a/app/views/search/results/_wiki_blob.html.haml b/app/views/search/results/_wiki_blob.html.haml index d87f9df2677..16a0e432d62 100644 --- a/app/views/search/results/_wiki_blob.html.haml +++ b/app/views/search/results/_wiki_blob.html.haml @@ -2,7 +2,7 @@ .blob-result .file-holder .js-file-title.file-title - = link_to namespace_project_wiki_path(@project.namespace, @project, wiki_blob.basename) do + = link_to project_wiki_path(@project, wiki_blob.basename) do %i.fa.fa-file %strong = wiki_blob.basename diff --git a/app/views/shared/_label.html.haml b/app/views/shared/_label.html.haml index de0281e97c6..2f776a17f45 100644 --- a/app/views/shared/_label.html.haml +++ b/app/views/shared/_label.html.haml @@ -23,7 +23,7 @@ - if can_subscribe_to_label_in_different_levels?(label) %a.js-unsubscribe-button.label-subscribe-button{ role: 'button', href: '#', class: ('hidden' if status.unsubscribed?), data: { url: toggle_subscription_path } } %span Unsubscribe - %a.js-subscribe-button.label-subscribe-button{ role: 'button', href: '#', class: ('hidden' unless status.unsubscribed?), data: { url: toggle_subscription_namespace_project_label_path(@project.namespace, @project, label) } } + %a.js-subscribe-button.label-subscribe-button{ role: 'button', href: '#', class: ('hidden' unless status.unsubscribed?), data: { url: toggle_subscription_project_label_path(@project, label) } } %span Subscribe at project level %a.js-subscribe-button.label-subscribe-button{ role: 'button', href: '#', class: ('hidden' unless status.unsubscribed?), data: { url: toggle_subscription_group_label_path(label.group, label) } } %span Subscribe at group level @@ -56,7 +56,7 @@ = icon('chevron-down') %ul.dropdown-menu %li - %a.js-subscribe-button{ class: ('hidden' unless status.unsubscribed?), data: { url: toggle_subscription_namespace_project_label_path(@project.namespace, @project, label) } } + %a.js-subscribe-button{ class: ('hidden' unless status.unsubscribed?), data: { url: toggle_subscription_project_label_path(@project, label) } } Project level %a.js-subscribe-button{ class: ('hidden' unless status.unsubscribed?), data: { url: toggle_subscription_group_label_path(label.group, label) } } Group level @@ -66,7 +66,7 @@ = icon('spinner spin', class: 'label-subscribe-button-loading') - if label.is_a?(ProjectLabel) && label.project.group && can?(current_user, :admin_label, label.project.group) - = link_to promote_namespace_project_label_path(label.project.namespace, label.project, label), title: "Promote to Group Label", class: 'btn btn-transparent btn-action', data: {confirm: "Promoting this label will make this label available to all projects inside this group. Existing project labels with the same name will be merged. Are you sure?", toggle: "tooltip"}, method: :post do + = link_to promote_project_label_path(label.project, label), title: "Promote to Group Label", class: 'btn btn-transparent btn-action', data: {confirm: "Promoting this label will make this label available to all projects inside this group. Existing project labels with the same name will be merged. Are you sure?", toggle: "tooltip"}, method: :post do %span.sr-only Promote to Group = icon('level-up') - if can?(current_user, :admin_label, label) diff --git a/app/views/shared/_label_row.html.haml b/app/views/shared/_label_row.html.haml index 7b599dff0e3..7f58298c60f 100644 --- a/app/views/shared/_label_row.html.haml +++ b/app/views/shared/_label_row.html.haml @@ -2,7 +2,7 @@ - if can?(current_user, :admin_label, @project) .draggable-handler = icon('bars') - .js-toggle-priority.toggle-priority{ data: { url: remove_priority_namespace_project_label_path(@project.namespace, @project, label), + .js-toggle-priority.toggle-priority{ data: { url: remove_priority_project_label_path(@project, label), dom_id: dom_id(label), type: label.type } } %button.add-priority.btn.has-tooltip{ title: 'Prioritize', type: 'button', :'data-placement' => 'top' } = icon('star-o') diff --git a/app/views/shared/_mini_pipeline_graph.html.haml b/app/views/shared/_mini_pipeline_graph.html.haml index aa93572bf94..dff847159d3 100644 --- a/app/views/shared/_mini_pipeline_graph.html.haml +++ b/app/views/shared/_mini_pipeline_graph.html.haml @@ -6,7 +6,7 @@ - status_klass = "ci-status-icon ci-status-icon-#{detailed_status.group}" .stage-container.dropdown{ class: klass } - %button.mini-pipeline-graph-dropdown-toggle.has-tooltip.js-builds-dropdown-button{ class: "ci-status-icon-#{detailed_status.group}", type: 'button', data: { toggle: 'dropdown', title: "#{stage.name}: #{detailed_status.label}", placement: 'top', "stage-endpoint" => stage_namespace_project_pipeline_path(pipeline.project.namespace, pipeline.project, pipeline, stage: stage.name) } } + %button.mini-pipeline-graph-dropdown-toggle.has-tooltip.js-builds-dropdown-button{ class: "ci-status-icon-#{detailed_status.group}", type: 'button', data: { toggle: 'dropdown', title: "#{stage.name}: #{detailed_status.label}", placement: 'top', "stage-endpoint" => stage_project_pipeline_path(pipeline.project, pipeline, stage: stage.name) } } = custom_icon(icon_status) = icon('caret-down') diff --git a/app/views/shared/_ref_switcher.html.haml b/app/views/shared/_ref_switcher.html.haml index d52bb6b4dd7..4498c8f8349 100644 --- a/app/views/shared/_ref_switcher.html.haml +++ b/app/views/shared/_ref_switcher.html.haml @@ -1,12 +1,12 @@ - dropdown_toggle_text = @ref || @project.default_branch -= form_tag switch_namespace_project_refs_path(@project.namespace, @project), method: :get, class: "project-refs-form" do += form_tag switch_project_refs_path(@project), method: :get, class: "project-refs-form" do = hidden_field_tag :destination, destination - if defined?(path) = hidden_field_tag :path, path - @options && @options.each do |key, value| = hidden_field_tag key, value, id: nil .dropdown - = dropdown_toggle dropdown_toggle_text, { toggle: "dropdown", selected: dropdown_toggle_text, ref: @ref, refs_url: refs_namespace_project_path(@project.namespace, @project), field_name: 'ref', submit_form_on_click: true }, { toggle_class: "js-project-refs-dropdown" } + = dropdown_toggle dropdown_toggle_text, { toggle: "dropdown", selected: dropdown_toggle_text, ref: @ref, refs_url: refs_project_path(@project), field_name: 'ref', submit_form_on_click: true }, { toggle_class: "js-project-refs-dropdown" } .dropdown-menu.dropdown-menu-selectable.git-revision-dropdown{ class: ("dropdown-menu-align-right" if local_assigns[:align_right]) } = dropdown_title _("Switch branch/tag") = dropdown_filter _("Search branches and tags") diff --git a/app/views/shared/_service_settings.html.haml b/app/views/shared/_service_settings.html.haml index b200e5fc528..7ca14ac93cc 100644 --- a/app/views/shared/_service_settings.html.haml +++ b/app/views/shared/_service_settings.html.haml @@ -7,10 +7,11 @@ = markdown @service.help .service-settings - .form-group - = form.label :active, "Active", class: "control-label" - .col-sm-10 - = form.check_box :active + - if @service.show_active_box? + .form-group + = form.label :active, "Active", class: "control-label" + .col-sm-10 + = form.check_box :active - if @service.supported_events.present? .form-group diff --git a/app/views/shared/empty_states/_labels.html.haml b/app/views/shared/empty_states/_labels.html.haml index 5e2f4cf109d..bfda522f2f6 100644 --- a/app/views/shared/empty_states/_labels.html.haml +++ b/app/views/shared/empty_states/_labels.html.haml @@ -7,5 +7,5 @@ %h4 Labels can be applied to issues and merge requests to categorize them. %p You can also star a label to make it a priority label. - if can?(current_user, :admin_label, @project) - = link_to 'New label', new_namespace_project_label_path(@project.namespace, @project), class: 'btn btn-new', title: 'New label', id: 'new_label_link' - = link_to 'Generate a default set of labels', generate_namespace_project_labels_path(@project.namespace, @project), method: :post, class: 'btn btn-success btn-inverted', title: 'Generate a default set of labels', id: 'generate_labels_link' + = link_to 'New label', new_project_label_path(@project), class: 'btn btn-new', title: 'New label', id: 'new_label_link' + = link_to 'Generate a default set of labels', generate_project_labels_path(@project), method: :post, class: 'btn btn-success btn-inverted', title: 'Generate a default set of labels', id: 'generate_labels_link' diff --git a/app/views/shared/issuable/_bulk_update_sidebar.html.haml b/app/views/shared/issuable/_bulk_update_sidebar.html.haml index 7cfdfb6e6ee..964fe5220f7 100644 --- a/app/views/shared/issuable/_bulk_update_sidebar.html.haml +++ b/app/views/shared/issuable/_bulk_update_sidebar.html.haml @@ -31,7 +31,7 @@ .title Milestone .filter-item - = dropdown_tag("Select milestone", options: { title: "Assign milestone", toggle_class: "js-milestone-select js-extra-options js-filter-submit js-filter-bulk-update", filter: true, dropdown_class: "dropdown-menu-selectable dropdown-menu-milestone", placeholder: "Search milestones", data: { show_no: true, field_name: "update[milestone_id]", project_id: @project.id, milestones: namespace_project_milestones_path(@project.namespace, @project, :json), use_id: true, default_label: "Milestone" } }) + = dropdown_tag("Select milestone", options: { title: "Assign milestone", toggle_class: "js-milestone-select js-extra-options js-filter-submit js-filter-bulk-update", filter: true, dropdown_class: "dropdown-menu-selectable dropdown-menu-milestone", placeholder: "Search milestones", data: { show_no: true, field_name: "update[milestone_id]", project_id: @project.id, milestones: project_milestones_path(@project, :json), use_id: true, default_label: "Milestone" } }) .block .title Labels diff --git a/app/views/shared/issuable/_label_page_default.html.haml b/app/views/shared/issuable/_label_page_default.html.haml index 9a8529c6cbb..e8feff32d26 100644 --- a/app/views/shared/issuable/_label_page_default.html.haml +++ b/app/views/shared/issuable/_label_page_default.html.haml @@ -20,7 +20,7 @@ %a.dropdown-toggle-page{ href: "#" } Create new label %li - = link_to namespace_project_labels_path(@project.namespace, @project), :"data-is-link" => true do + = link_to project_labels_path(@project), :"data-is-link" => true do - if show_create && @project && can?(current_user, :admin_label, @project) Manage labels - else diff --git a/app/views/shared/issuable/_milestone_dropdown.html.haml b/app/views/shared/issuable/_milestone_dropdown.html.haml index 6750921338a..955b8866c2c 100644 --- a/app/views/shared/issuable/_milestone_dropdown.html.haml +++ b/app/views/shared/issuable/_milestone_dropdown.html.haml @@ -11,10 +11,10 @@ %ul.dropdown-footer-list - if can? current_user, :admin_milestone, project %li - = link_to new_namespace_project_milestone_path(project.namespace, project), title: "New Milestone" do + = link_to new_project_milestone_path(project), title: "New Milestone" do Create new %li - = link_to namespace_project_milestones_path(project.namespace, project) do + = link_to project_milestones_path(project) do - if can? current_user, :admin_milestone, project Manage milestones - else diff --git a/app/views/shared/issuable/_search_bar.html.haml b/app/views/shared/issuable/_search_bar.html.haml index d3d290692a2..ae890567225 100644 --- a/app/views/shared/issuable/_search_bar.html.haml +++ b/app/views/shared/issuable/_search_bar.html.haml @@ -23,7 +23,7 @@ .scroll-container %ul.tokens-container.list-unstyled %li.input-token - %input.form-control.filtered-search{ id: "filtered-search-#{type.to_s}", placeholder: 'Search or filter results...', data: { 'project-id' => @project.id, 'username-params' => @users.to_json(only: [:id, :username]), 'base-endpoint' => namespace_project_path(@project.namespace, @project) } } + %input.form-control.filtered-search{ search_filter_input_options(type) } = icon('filter') #js-dropdown-hint.filtered-search-input-dropdown-menu.dropdown-menu.hint-dropdown %ul{ data: { dropdown: true } } diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml index 745f1ee62da..ecbaa901792 100644 --- a/app/views/shared/issuable/_sidebar.html.haml +++ b/app/views/shared/issuable/_sidebar.html.haml @@ -37,13 +37,13 @@ = link_to 'Edit', '#', class: 'edit-link pull-right' .value.hide-collapsed - if issuable.milestone - = link_to issuable.milestone.title, namespace_project_milestone_path(@project.namespace, @project, issuable.milestone), class: "bold has-tooltip", title: milestone_remaining_days(issuable.milestone), data: { container: "body", html: 1 } + = link_to issuable.milestone.title, project_milestone_path(@project, issuable.milestone), class: "bold has-tooltip", title: milestone_remaining_days(issuable.milestone), data: { container: "body", html: 1 } - else %span.no-value None .selectbox.hide-collapsed = f.hidden_field 'milestone_id', value: issuable.milestone_id, id: nil - = dropdown_tag('Milestone', options: { title: 'Assign milestone', toggle_class: 'js-milestone-select js-extra-options', filter: true, dropdown_class: 'dropdown-menu-selectable', placeholder: 'Search milestones', data: { show_no: true, field_name: "#{issuable.to_ability_name}[milestone_id]", project_id: @project.id, issuable_id: issuable.id, milestones: namespace_project_milestones_path(@project.namespace, @project, :json), ability_name: issuable.to_ability_name, issue_update: issuable_json_path(issuable), use_id: true, default_no: true, selected: (issuable.milestone.name if issuable.milestone), null_default: true }}) + = dropdown_tag('Milestone', options: { title: 'Assign milestone', toggle_class: 'js-milestone-select js-extra-options', filter: true, dropdown_class: 'dropdown-menu-selectable', placeholder: 'Search milestones', data: { show_no: true, field_name: "#{issuable.to_ability_name}[milestone_id]", project_id: @project.id, issuable_id: issuable.id, milestones: project_milestones_path(@project, :json), ability_name: issuable.to_ability_name, issue_update: issuable_json_path(issuable), use_id: true, default_no: true, selected: (issuable.milestone.name if issuable.milestone), null_default: true }}) - if issuable.has_attribute?(:time_estimate) #issuable-time-tracker.block // Fallback while content is loading @@ -106,7 +106,7 @@ - selected_labels.each do |label| = hidden_field_tag "#{issuable.to_ability_name}[label_names][]", label.id, id: nil .dropdown - %button.dropdown-menu-toggle.js-label-select.js-multiselect.js-label-sidebar-dropdown{ type: "button", data: {toggle: "dropdown", default_label: "Labels", field_name: "#{issuable.to_ability_name}[label_names][]", ability_name: issuable.to_ability_name, show_no: "true", show_any: "true", namespace_path: @project.try(:namespace).try(:full_path), project_path: @project.try(:path), issue_update: issuable_json_path(issuable), labels: (namespace_project_labels_path(@project.namespace, @project, :json) if @project) } } + %button.dropdown-menu-toggle.js-label-select.js-multiselect.js-label-sidebar-dropdown{ type: "button", data: {toggle: "dropdown", default_label: "Labels", field_name: "#{issuable.to_ability_name}[label_names][]", ability_name: issuable.to_ability_name, show_no: "true", show_any: "true", namespace_path: @project.try(:namespace).try(:full_path), project_path: @project.try(:path), issue_update: issuable_json_path(issuable), labels: (project_labels_path(@project, :json) if @project) } } %span.dropdown-toggle-text{ class: ("is-default" if selected_labels.empty?) } = multi_label_name(selected_labels, "Labels") = icon('chevron-down', 'aria-hidden': 'true') diff --git a/app/views/shared/issuable/_sidebar_assignees.html.haml b/app/views/shared/issuable/_sidebar_assignees.html.haml index 2ea5eb960c0..57392cd7fbb 100644 --- a/app/views/shared/issuable/_sidebar_assignees.html.haml +++ b/app/views/shared/issuable/_sidebar_assignees.html.haml @@ -37,19 +37,20 @@ - issuable.assignees.each do |assignee| = hidden_field_tag "#{issuable.to_ability_name}[assignee_ids][]", assignee.id, id: nil, data: { avatar_url: assignee.avatar_url, name: assignee.name, username: assignee.username } - - options = { toggle_class: 'js-user-search js-author-search', title: 'Assign to', filter: true, dropdown_class: 'dropdown-menu-user dropdown-menu-selectable dropdown-menu-author', placeholder: 'Search users', data: { first_user: (current_user.username if current_user), current_user: true, project_id: (@project.id if @project), author_id: issuable.author_id, field_name: "#{issuable.to_ability_name}[assignee_ids][]", issue_update: issuable_json_path(issuable), ability_name: issuable.to_ability_name, null_user: true } } - + - options = { toggle_class: 'js-user-search js-author-search', title: 'Assign to', filter: true, dropdown_class: 'dropdown-menu-user dropdown-menu-selectable dropdown-menu-author', placeholder: 'Search users', data: { first_user: current_user&.username, current_user: true, project_id: @project&.id, author_id: issuable.author_id, field_name: "#{issuable.to_ability_name}[assignee_ids][]", issue_update: issuable_json_path(issuable), ability_name: issuable.to_ability_name, null_user: true } } - title = 'Select assignee' - if issuable.is_a?(Issue) - unless issuable.assignees.any? = hidden_field_tag "#{issuable.to_ability_name}[assignee_ids][]", 0, id: nil + - dropdown_options = issue_assignees_dropdown_options + - title = dropdown_options[:title] - options[:toggle_class] += ' js-multiselect js-save-user-data' - data = { field_name: "#{issuable.to_ability_name}[assignee_ids][]" } - data[:multi_select] = true - data['dropdown-title'] = title - - data['dropdown-header'] = 'Assignee' - - data['max-select'] = 1 + - data['dropdown-header'] = dropdown_options[:data][:'dropdown-header'] + - data['max-select'] = dropdown_options[:data][:'max-select'] - options[:data].merge!(data) = dropdown_tag(title, options: options) diff --git a/app/views/shared/issuable/form/_merge_params.html.haml b/app/views/shared/issuable/form/_merge_params.html.haml index bfa91629e1e..8f6509a8ce8 100644 --- a/app/views/shared/issuable/form/_merge_params.html.haml +++ b/app/views/shared/issuable/form/_merge_params.html.haml @@ -11,8 +11,7 @@ .col-sm-10.col-sm-offset-2 - if issuable.can_remove_source_branch?(current_user) .checkbox - - initial_checkbox_value = issuable.merge_params.key?('force_remove_source_branch') ? issuable.force_remove_source_branch? : true = label_tag 'merge_request[force_remove_source_branch]' do = hidden_field_tag 'merge_request[force_remove_source_branch]', '0', id: nil - = check_box_tag 'merge_request[force_remove_source_branch]', '1', initial_checkbox_value + = check_box_tag 'merge_request[force_remove_source_branch]', '1', issuable.force_remove_source_branch? Remove source branch when merge request is accepted. diff --git a/app/views/shared/issuable/form/_metadata_issue_assignee.html.haml b/app/views/shared/issuable/form/_metadata_issue_assignee.html.haml index 77175c839a6..567cde764e2 100644 --- a/app/views/shared/issuable/form/_metadata_issue_assignee.html.haml +++ b/app/views/shared/issuable/form/_metadata_issue_assignee.html.haml @@ -7,5 +7,5 @@ - if issuable.assignees.length === 0 = hidden_field_tag "#{issuable.to_ability_name}[assignee_ids][]", 0, id: nil, data: { meta: '' } - = dropdown_tag(users_dropdown_label(issuable.assignees), options: issue_dropdown_options(issuable,false)) + = dropdown_tag(users_dropdown_label(issuable.assignees), options: issue_assignees_dropdown_options) = link_to 'Assign to me', '#', class: "assign-to-me-link #{'hide' if issuable.assignees.include?(current_user)}" diff --git a/app/views/shared/members/_access_request_buttons.html.haml b/app/views/shared/members/_access_request_buttons.html.haml index d97fdf179d7..40224cec9e8 100644 --- a/app/views/shared/members/_access_request_buttons.html.haml +++ b/app/views/shared/members/_access_request_buttons.html.haml @@ -1,18 +1,20 @@ - model_name = source.model_name.to_s.downcase -.project-action-button.inline - - if can?(current_user, :"destroy_#{model_name}_member", source.members.find_by(user_id: current_user.id)) +- if can?(current_user, :"destroy_#{model_name}_member", source.members.find_by(user_id: current_user.id)) + .project-action-button.inline - link_text = source.is_a?(Group) ? _('Leave group') : _('Leave project') = link_to link_text, polymorphic_path([:leave, source, :members]), method: :delete, data: { confirm: leave_confirmation_message(source) }, class: 'btn' - - elsif requester = source.requesters.find_by(user_id: current_user.id) +- elsif requester = source.requesters.find_by(user_id: current_user.id) + .project-action-button.inline = link_to _('Withdraw Access Request'), polymorphic_path([:leave, source, :members]), method: :delete, data: { confirm: remove_member_message(requester) }, class: 'btn' - - elsif source.request_access_enabled && can?(current_user, :request_access, source) +- elsif source.request_access_enabled && can?(current_user, :request_access, source) + .project-action-button.inline = link_to _('Request Access'), polymorphic_path([:request_access, source, :members]), method: :post, class: 'btn' diff --git a/app/views/shared/members/_group.html.haml b/app/views/shared/members/_group.html.haml index 1d5a61cffce..bcdad3c153a 100644 --- a/app/views/shared/members/_group.html.haml +++ b/app/views/shared/members/_group.html.haml @@ -14,7 +14,7 @@ %span{ class: ('text-warning' if group_link.expires_soon?) } Expires in #{distance_of_time_in_words_to_now(group_link.expires_at)} .controls.member-controls - = form_tag namespace_project_group_link_path(@project.namespace, @project, group_link), method: :put, remote: true, class: 'form-horizontal js-edit-member-form' do + = form_tag project_group_link_path(@project, group_link), method: :put, remote: true, class: 'form-horizontal js-edit-member-form' do = hidden_field_tag "group_link[group_access]", group_link.group_access .member-form-control.dropdown.append-right-5 %button.dropdown-menu-toggle.js-member-permissions-dropdown{ type: "button", @@ -36,7 +36,7 @@ = text_field_tag 'group_link[expires_at]', group_link.expires_at, class: 'form-control js-access-expiration-date js-member-update-control', placeholder: 'Expiration date', id: "member_expires_at_#{group.id}", disabled: !can_admin_member %i.clear-icon.js-clear-input - if can_admin_member - = link_to namespace_project_group_link_path(@project.namespace, @project, group_link), + = link_to project_group_link_path(@project, group_link), method: :delete, data: { confirm: "Are you sure you want to remove #{group.name}?" }, class: 'btn btn-remove prepend-left-10' do diff --git a/app/views/shared/milestones/_milestone.html.haml b/app/views/shared/milestones/_milestone.html.haml index 680e1f3a4ea..ecc8b42979c 100644 --- a/app/views/shared/milestones/_milestone.html.haml +++ b/app/views/shared/milestones/_milestone.html.haml @@ -35,9 +35,9 @@ .col-sm-6= render('shared/milestone_expired', milestone: milestone) .col-sm-6.milestone-actions - if can?(current_user, :admin_milestone, milestone.project) and milestone.active? - = link_to edit_namespace_project_milestone_path(milestone.project.namespace, milestone.project, milestone), class: "btn btn-xs btn-grouped" do + = link_to edit_project_milestone_path(milestone.project, milestone), class: "btn btn-xs btn-grouped" do Edit \ - = link_to 'Close Milestone', namespace_project_milestone_path(@project.namespace, @project, milestone, milestone: {state_event: :close }), method: :put, remote: true, class: "btn btn-xs btn-close btn-grouped" - = link_to namespace_project_milestone_path(milestone.project.namespace, milestone.project, milestone), data: { confirm: 'Are you sure?' }, method: :delete, class: "btn btn-xs btn-remove btn-grouped" do + = link_to 'Close Milestone', project_milestone_path(@project, milestone, milestone: {state_event: :close }), method: :put, remote: true, class: "btn btn-xs btn-close btn-grouped" + = link_to project_milestone_path(milestone.project, milestone), data: { confirm: 'Are you sure?' }, method: :delete, class: "btn btn-xs btn-remove btn-grouped" do Delete diff --git a/app/views/shared/milestones/_sidebar.html.haml b/app/views/shared/milestones/_sidebar.html.haml index 9bb87640319..895fb8247b5 100644 --- a/app/views/shared/milestones/_sidebar.html.haml +++ b/app/views/shared/milestones/_sidebar.html.haml @@ -21,7 +21,7 @@ .title Start date - if @project && can?(current_user, :admin_milestone, @project) - = link_to 'Edit', edit_namespace_project_milestone_path(@project.namespace, @project, @milestone), class: 'edit-link pull-right' + = link_to 'Edit', edit_project_milestone_path(@project, @milestone), class: 'edit-link pull-right' .value %span.value-content - if milestone.start_date @@ -51,7 +51,7 @@ .title.hide-collapsed Due date - if @project && can?(current_user, :admin_milestone, @project) - = link_to 'Edit', edit_namespace_project_milestone_path(@project.namespace, @project, @milestone), class: 'edit-link pull-right' + = link_to 'Edit', edit_project_milestone_path(@project, @milestone), class: 'edit-link pull-right' .value.hide-collapsed %span.value-content - if milestone.due_date @@ -73,7 +73,7 @@ Issues %span.badge= milestone.issues_visible_to_user(current_user).count - if project && can?(current_user, :create_issue, project) - = link_to new_namespace_project_issue_path(project.namespace, project, issue: { milestone_id: milestone.id }), class: "pull-right", title: "New Issue" do + = link_to new_project_issue_path(project, issue: { milestone_id: milestone.id }), class: "pull-right", title: "New Issue" do New issue .value.hide-collapsed.bold %span.milestone-stat diff --git a/app/views/shared/milestones/_tabs.html.haml b/app/views/shared/milestones/_tabs.html.haml index 4de8a6cb15f..e2d1695b7c3 100644 --- a/app/views/shared/milestones/_tabs.html.haml +++ b/app/views/shared/milestones/_tabs.html.haml @@ -30,7 +30,7 @@ .tab-content.milestone-content - if milestone.is_a?(GlobalMilestone) || can?(current_user, :read_issue, @project) - .tab-pane.active#tab-issues{ data: { sort_endpoint: (sort_issues_namespace_project_milestone_path(@project.namespace, @project, @milestone) if @project && current_user) } } + .tab-pane.active#tab-issues{ data: { sort_endpoint: (sort_issues_project_milestone_path(@project, @milestone) if @project && current_user) } } = render 'shared/milestones/issues_tab', issues: milestone.sorted_issues(current_user), show_project_name: show_project_name, show_full_project_name: show_full_project_name .tab-pane#tab-merge-requests -# loaded async diff --git a/app/views/shared/milestones/_top.html.haml b/app/views/shared/milestones/_top.html.haml index 2562f085338..20a12613cfc 100644 --- a/app/views/shared/milestones/_top.html.haml +++ b/app/views/shared/milestones/_top.html.haml @@ -48,7 +48,7 @@ %tr %td - project_name = group ? ms.project.name : ms.project.name_with_namespace - = link_to project_name, namespace_project_milestone_path(ms.project.namespace, ms.project, ms) + = link_to project_name, project_milestone_path(ms.project, ms) %td = ms.issues_visible_to_user(current_user).opened.count %td diff --git a/app/views/shared/notes/_note.html.haml b/app/views/shared/notes/_note.html.haml index 1e34b7c1e76..7174855e176 100644 --- a/app/views/shared/notes/_note.html.haml +++ b/app/views/shared/notes/_note.html.haml @@ -60,6 +60,6 @@ = link_to note.attachment.url, target: '_blank' do = icon('paperclip') = note.attachment_identifier - = link_to delete_attachment_namespace_project_note_path(note.project.namespace, note.project, note), + = link_to delete_attachment_project_note_path(note.project, note), title: 'Delete this attachment', method: :delete, remote: true, data: { confirm: 'Are you sure you want to remove the attachment?' }, class: 'danger js-note-attachment-delete' do = icon('trash-o', class: 'cred') diff --git a/app/views/shared/projects/_project.html.haml b/app/views/shared/projects/_project.html.haml index 8c3d6351ac2..4bdbc26a4c3 100644 --- a/app/views/shared/projects/_project.html.haml +++ b/app/views/shared/projects/_project.html.haml @@ -31,7 +31,7 @@ - if show_last_commit_as_description .description.prepend-top-5 - = link_to_gfm project.commit.title, namespace_project_commit_path(project.namespace, project, project.commit), + = link_to_gfm project.commit.title, project_commit_path(project, project.commit), class: "commit-row-message" - elsif project.description.present? .description.prepend-top-5 diff --git a/app/views/shared/snippets/_form.html.haml b/app/views/shared/snippets/_form.html.haml index 8549cb91b03..43322978749 100644 --- a/app/views/shared/snippets/_form.html.haml +++ b/app/views/shared/snippets/_form.html.haml @@ -36,6 +36,6 @@ = f.submit 'Save changes', class: "btn-save btn" - if @snippet.project_id - = link_to "Cancel", namespace_project_snippets_path(@project.namespace, @project), class: "btn btn-cancel" + = link_to "Cancel", project_snippets_path(@project), class: "btn btn-cancel" - else = link_to "Cancel", snippets_path(@project), class: "btn btn-cancel" diff --git a/app/views/shared/snippets/_snippet.html.haml b/app/views/shared/snippets/_snippet.html.haml index 5d2d2317f22..7388f20a9fd 100644 --- a/app/views/shared/snippets/_snippet.html.haml +++ b/app/views/shared/snippets/_snippet.html.haml @@ -30,7 +30,7 @@ - if link_project && snippet.project_id? %span.hidden-xs in - = link_to namespace_project_path(snippet.project.namespace, snippet.project) do + = link_to project_path(snippet.project) do = snippet.project.name_with_namespace .pull-right.snippet-updated-at diff --git a/app/views/users/calendar_activities.html.haml b/app/views/users/calendar_activities.html.haml index d1e88274878..805a346a85e 100644 --- a/app/views/users/calendar_activities.html.haml +++ b/app/views/users/calendar_activities.html.haml @@ -12,7 +12,7 @@ - if event.push? #{event.action_name} #{event.ref_type} %strong - - commits_path = namespace_project_commits_path(event.project.namespace, event.project, event.ref_name) + - commits_path = project_commits_path(event.project, event.ref_name) = link_to_if event.project.repository.branch_exists?(event.ref_name), event.ref_name, commits_path - else = event_action_name(event) diff --git a/app/workers/expire_job_cache_worker.rb b/app/workers/expire_job_cache_worker.rb index 08e281e7350..e383202260d 100644 --- a/app/workers/expire_job_cache_worker.rb +++ b/app/workers/expire_job_cache_worker.rb @@ -18,18 +18,10 @@ class ExpireJobCacheWorker private def project_pipeline_path(project, pipeline) - Gitlab::Routing.url_helpers.namespace_project_pipeline_path( - project.namespace, - project, - pipeline, - format: :json) + Gitlab::Routing.url_helpers.project_pipeline_path(project, pipeline, format: :json) end def project_job_path(project, job) - Gitlab::Routing.url_helpers.namespace_project_build_path( - project.namespace, - project, - job.id, - format: :json) + Gitlab::Routing.url_helpers.project_build_path(project, job.id, format: :json) end end diff --git a/app/workers/expire_pipeline_cache_worker.rb b/app/workers/expire_pipeline_cache_worker.rb index 92e622285de..7c02d6cf892 100644 --- a/app/workers/expire_pipeline_cache_worker.rb +++ b/app/workers/expire_pipeline_cache_worker.rb @@ -23,42 +23,24 @@ class ExpirePipelineCacheWorker private def project_pipelines_path(project) - Gitlab::Routing.url_helpers.namespace_project_pipelines_path( - project.namespace, - project, - format: :json) + Gitlab::Routing.url_helpers.project_pipelines_path(project, format: :json) end def project_pipeline_path(project, pipeline) - Gitlab::Routing.url_helpers.namespace_project_pipeline_path( - project.namespace, - project, - pipeline, - format: :json) + Gitlab::Routing.url_helpers.project_pipeline_path(project, pipeline, format: :json) end def commit_pipelines_path(project, commit) - Gitlab::Routing.url_helpers.pipelines_namespace_project_commit_path( - project.namespace, - project, - commit.id, - format: :json) + Gitlab::Routing.url_helpers.pipelines_project_commit_path(project, commit.id, format: :json) end def new_merge_request_pipelines_path(project) - Gitlab::Routing.url_helpers.namespace_project_new_merge_request_path( - project.namespace, - project, - format: :json) + Gitlab::Routing.url_helpers.project_new_merge_request_path(project, format: :json) end def each_pipelines_merge_request_path(project, pipeline) pipeline.all_merge_requests.each do |merge_request| - path = Gitlab::Routing.url_helpers.pipelines_namespace_project_merge_request_path( - project.namespace, - project, - merge_request, - format: :json) + path = Gitlab::Routing.url_helpers.pipelines_project_merge_request_path(project, merge_request, format: :json) yield(path) end diff --git a/changelogs/unreleased/18000-remember-me-for-oauth-login.yml b/changelogs/unreleased/18000-remember-me-for-oauth-login.yml new file mode 100644 index 00000000000..1ef92756a76 --- /dev/null +++ b/changelogs/unreleased/18000-remember-me-for-oauth-login.yml @@ -0,0 +1,4 @@ +--- +title: Honor the "Remember me" parameter for OAuth-based login +merge_request: 11963 +author: diff --git a/changelogs/unreleased/23036-replace-dashboard-new-project-spinach.yml b/changelogs/unreleased/23036-replace-dashboard-new-project-spinach.yml new file mode 100644 index 00000000000..a5f78202c93 --- /dev/null +++ b/changelogs/unreleased/23036-replace-dashboard-new-project-spinach.yml @@ -0,0 +1,4 @@ +--- +title: Replace 'dashboard/new-project.feature' spinach with rspec +merge_request: 12550 +author: Alexander Randa (@randaalex) diff --git a/changelogs/unreleased/23036-replace-snippets-spinach.yml b/changelogs/unreleased/23036-replace-snippets-spinach.yml new file mode 100644 index 00000000000..545805b1302 --- /dev/null +++ b/changelogs/unreleased/23036-replace-snippets-spinach.yml @@ -0,0 +1,4 @@ +--- +title: Replace 'snippets/snippets.feature' spinach with rspec +merge_request: 12385 +author: Alexander Randa @randaalex diff --git a/changelogs/unreleased/23162-allow-creation-of-files-and-dirs-with-spaces-in-web-ui.yml b/changelogs/unreleased/23162-allow-creation-of-files-and-dirs-with-spaces-in-web-ui.yml new file mode 100644 index 00000000000..442406c3c04 --- /dev/null +++ b/changelogs/unreleased/23162-allow-creation-of-files-and-dirs-with-spaces-in-web-ui.yml @@ -0,0 +1,4 @@ +--- +title: Allow creation of files and directories with spaces through Web UI +merge_request: 12608 +author: diff --git a/changelogs/unreleased/32048-shared-runners-admin-buttons-have-odd-spacing.yml b/changelogs/unreleased/32048-shared-runners-admin-buttons-have-odd-spacing.yml new file mode 100644 index 00000000000..99e64b9b467 --- /dev/null +++ b/changelogs/unreleased/32048-shared-runners-admin-buttons-have-odd-spacing.yml @@ -0,0 +1,4 @@ +--- +title: Fix spacing on runner buttons. +merge_request: !12535 +author: diff --git a/changelogs/unreleased/32408-enable-disable-all-restricted-visibility-levels.yml b/changelogs/unreleased/32408-enable-disable-all-restricted-visibility-levels.yml new file mode 100644 index 00000000000..ebb27d118d7 --- /dev/null +++ b/changelogs/unreleased/32408-enable-disable-all-restricted-visibility-levels.yml @@ -0,0 +1,4 @@ +--- +title: Allow admins to disable all restricted visibility levels +merge_request: 12649 +author: diff --git a/changelogs/unreleased/32815--Add-Custom-CI-Config-Path.yml b/changelogs/unreleased/32815--Add-Custom-CI-Config-Path.yml new file mode 100644 index 00000000000..7784d7d0ce0 --- /dev/null +++ b/changelogs/unreleased/32815--Add-Custom-CI-Config-Path.yml @@ -0,0 +1,4 @@ +--- +title: Allow customize CI config path +merge_request: 12509 +author: Keith Pope diff --git a/changelogs/unreleased/32838-admin-panel-spacing.yml b/changelogs/unreleased/32838-admin-panel-spacing.yml new file mode 100644 index 00000000000..ccd703fa43f --- /dev/null +++ b/changelogs/unreleased/32838-admin-panel-spacing.yml @@ -0,0 +1,4 @@ +--- +title: Add wells to admin dashboard overview to fix spacing problems +merge_request: +author: diff --git a/changelogs/unreleased/33130-remove-group-modal.yml b/changelogs/unreleased/33130-remove-group-modal.yml new file mode 100644 index 00000000000..4672d41ded5 --- /dev/null +++ b/changelogs/unreleased/33130-remove-group-modal.yml @@ -0,0 +1,4 @@ +--- +title: "Remove group modal like remove project modal (requires typing + confirmation)" +merge_request: 12569 +author: Diego Souza diff --git a/changelogs/unreleased/33360-generate-kubeconfig.yml b/changelogs/unreleased/33360-generate-kubeconfig.yml new file mode 100644 index 00000000000..96f0b1bc93f --- /dev/null +++ b/changelogs/unreleased/33360-generate-kubeconfig.yml @@ -0,0 +1,4 @@ +--- +title: Provide KUBECONFIG from KubernetesService for runners +merge_request: 12223 +author: diff --git a/changelogs/unreleased/33580-fix-api-scoping.yml b/changelogs/unreleased/33580-fix-api-scoping.yml new file mode 100644 index 00000000000..f4ebb13c082 --- /dev/null +++ b/changelogs/unreleased/33580-fix-api-scoping.yml @@ -0,0 +1,4 @@ +--- +title: Fix API Scoping +merge_request: 12300 +author: diff --git a/changelogs/unreleased/33657-user-projects-api.yml b/changelogs/unreleased/33657-user-projects-api.yml new file mode 100644 index 00000000000..a8d485865e9 --- /dev/null +++ b/changelogs/unreleased/33657-user-projects-api.yml @@ -0,0 +1,4 @@ +--- +title: Add user projects API +merge_request: 12596 +author: Ivan Chernov diff --git a/changelogs/unreleased/33772-readonly-gitlab-ci-cache.yml b/changelogs/unreleased/33772-readonly-gitlab-ci-cache.yml new file mode 100644 index 00000000000..c2bce368a58 --- /dev/null +++ b/changelogs/unreleased/33772-readonly-gitlab-ci-cache.yml @@ -0,0 +1,4 @@ +--- +title: Introduce cache policies for CI jobs +merge_request: 12483 +author: diff --git a/changelogs/unreleased/34097-issue-board-remove-from-board-button-when-viewing-an-issue-gives-js-error-and-fails.yml b/changelogs/unreleased/34097-issue-board-remove-from-board-button-when-viewing-an-issue-gives-js-error-and-fails.yml deleted file mode 100644 index c0ea75adfa0..00000000000 --- a/changelogs/unreleased/34097-issue-board-remove-from-board-button-when-viewing-an-issue-gives-js-error-and-fails.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Remove "Remove from board" button from backlog and closed list -merge_request: 12430 -author: diff --git a/changelogs/unreleased/34116-milestone-filtering-on-group-issues.yml b/changelogs/unreleased/34116-milestone-filtering-on-group-issues.yml new file mode 100644 index 00000000000..8f8b5a96c2b --- /dev/null +++ b/changelogs/unreleased/34116-milestone-filtering-on-group-issues.yml @@ -0,0 +1,4 @@ +--- +title: Change milestone endpoint for groups +merge_request: 12374 +author: Takuya Noguchi diff --git a/changelogs/unreleased/34141-allow-unauthenticated-access-to-the-users-api.yml b/changelogs/unreleased/34141-allow-unauthenticated-access-to-the-users-api.yml new file mode 100644 index 00000000000..a3ade8db214 --- /dev/null +++ b/changelogs/unreleased/34141-allow-unauthenticated-access-to-the-users-api.yml @@ -0,0 +1,4 @@ +--- +title: Allow unauthenticated access to the /api/v4/users API +merge_request: 12445 +author: diff --git a/changelogs/unreleased/34169-add-simplified-chinese-translations-of-commits-page.yml b/changelogs/unreleased/34169-add-simplified-chinese-translations-of-commits-page.yml new file mode 100644 index 00000000000..1a631c3f0a4 --- /dev/null +++ b/changelogs/unreleased/34169-add-simplified-chinese-translations-of-commits-page.yml @@ -0,0 +1,4 @@ +--- +title: Add Simplified Chinese translations of Commits Page +merge_request: 12405 +author: Huang Tao diff --git a/changelogs/unreleased/34171-add-traditional-chinese-in-hongkong-translations-of-commits-page.yml b/changelogs/unreleased/34171-add-traditional-chinese-in-hongkong-translations-of-commits-page.yml new file mode 100644 index 00000000000..3cf7c0b547f --- /dev/null +++ b/changelogs/unreleased/34171-add-traditional-chinese-in-hongkong-translations-of-commits-page.yml @@ -0,0 +1,4 @@ +--- +title: Add Traditional Chinese in HongKong translations of Commits Page +merge_request: 12406 +author: Huang Tao diff --git a/changelogs/unreleased/34172-add-traditional-chinese-in-taiwan-translations-of-commits-page.yml b/changelogs/unreleased/34172-add-traditional-chinese-in-taiwan-translations-of-commits-page.yml new file mode 100644 index 00000000000..224b9e1852f --- /dev/null +++ b/changelogs/unreleased/34172-add-traditional-chinese-in-taiwan-translations-of-commits-page.yml @@ -0,0 +1,4 @@ +--- +title: Add Traditional Chinese in Taiwan translations of Commits Page +merge_request: 12407 +author: Huang Tao diff --git a/changelogs/unreleased/34175-add-esperanto-translations-of-commits-page.yml b/changelogs/unreleased/34175-add-esperanto-translations-of-commits-page.yml new file mode 100644 index 00000000000..b43a38f3794 --- /dev/null +++ b/changelogs/unreleased/34175-add-esperanto-translations-of-commits-page.yml @@ -0,0 +1,4 @@ +--- +title: Add Esperanto translations of Commits Page +merge_request: 12410 +author: Huang Tao diff --git a/changelogs/unreleased/34176-add-bulgarian-translations-of-commits-page.yml b/changelogs/unreleased/34176-add-bulgarian-translations-of-commits-page.yml new file mode 100644 index 00000000000..9177ae3acd1 --- /dev/null +++ b/changelogs/unreleased/34176-add-bulgarian-translations-of-commits-page.yml @@ -0,0 +1,4 @@ +--- +title: Add Bulgarian translations of Commits Page +merge_request: 12411 +author: Huang Tao diff --git a/changelogs/unreleased/34531-remove-scroll.yml b/changelogs/unreleased/34531-remove-scroll.yml new file mode 100644 index 00000000000..c3c5289f66f --- /dev/null +++ b/changelogs/unreleased/34531-remove-scroll.yml @@ -0,0 +1,4 @@ +--- +title: Update jobs page output to have a scrollable page +merge_request: 12587 +author: diff --git a/changelogs/unreleased/34544-add-italian-translation-of-cycle-analytics-page-&-project-page-&-repository-page.yml b/changelogs/unreleased/34544-add-italian-translation-of-cycle-analytics-page-&-project-page-&-repository-page.yml new file mode 100644 index 00000000000..31f4262c9f9 --- /dev/null +++ b/changelogs/unreleased/34544-add-italian-translation-of-cycle-analytics-page-&-project-page-&-repository-page.yml @@ -0,0 +1,4 @@ +--- +title: Add Italian translation of Cycle Analytics Page & Project Page & Repository Page +merge_request: 12578 +author: Huang Tao diff --git a/changelogs/unreleased/34578-sidebar-padding.yml b/changelogs/unreleased/34578-sidebar-padding.yml new file mode 100644 index 00000000000..dc4647298e6 --- /dev/null +++ b/changelogs/unreleased/34578-sidebar-padding.yml @@ -0,0 +1,4 @@ +--- +title: fix left & right padding on sidebar +merge_request: +author: diff --git a/changelogs/unreleased/34653-minor-ux-cleanups-for-performance-dashboard.yml b/changelogs/unreleased/34653-minor-ux-cleanups-for-performance-dashboard.yml new file mode 100644 index 00000000000..736991318d7 --- /dev/null +++ b/changelogs/unreleased/34653-minor-ux-cleanups-for-performance-dashboard.yml @@ -0,0 +1,4 @@ +--- +title: Cleanup minor UX issues in the performance dashboard +merge_request: +author: diff --git a/changelogs/unreleased/34688-add-italian-translations-of-commits-page.yml b/changelogs/unreleased/34688-add-italian-translations-of-commits-page.yml new file mode 100644 index 00000000000..90a1f8c98fe --- /dev/null +++ b/changelogs/unreleased/34688-add-italian-translations-of-commits-page.yml @@ -0,0 +1,4 @@ +--- +title: Add Italian translations of Commits Page +merge_request: 12645 +author: Huang Tao diff --git a/changelogs/unreleased/add-ci_variables-environment_scope-mysql.yml b/changelogs/unreleased/add-ci_variables-environment_scope-mysql.yml new file mode 100644 index 00000000000..4948d415bed --- /dev/null +++ b/changelogs/unreleased/add-ci_variables-environment_scope-mysql.yml @@ -0,0 +1,6 @@ +--- +title: Rename duplicated variables with the same key for projects. Add environment_scope + column to variables and add unique constraint to make sure that no variables could + be created with the same key within a project +merge_request: 12363 +author: diff --git a/changelogs/unreleased/dm-drop-default-scope-on-sortable-finders.yml b/changelogs/unreleased/dm-drop-default-scope-on-sortable-finders.yml new file mode 100644 index 00000000000..b359a25053a --- /dev/null +++ b/changelogs/unreleased/dm-drop-default-scope-on-sortable-finders.yml @@ -0,0 +1,4 @@ +--- +title: Improve performance of lookups of issues, merge requests etc by dropping unnecessary ORDER BY clause +merge_request: +author: diff --git a/changelogs/unreleased/dm-encode-tree-and-blob-paths.yml b/changelogs/unreleased/dm-encode-tree-and-blob-paths.yml new file mode 100644 index 00000000000..c1a026e1f29 --- /dev/null +++ b/changelogs/unreleased/dm-encode-tree-and-blob-paths.yml @@ -0,0 +1,5 @@ +--- +title: Fix issues with non-UTF8 filenames by always fixing the encoding of tree and + blob paths +merge_request: +author: diff --git a/changelogs/unreleased/enable-polling-env.yml b/changelogs/unreleased/enable-polling-env.yml new file mode 100644 index 00000000000..b3f65f02574 --- /dev/null +++ b/changelogs/unreleased/enable-polling-env.yml @@ -0,0 +1,4 @@ +--- +title: Re-enable realtime for environments table +merge_request: +author: diff --git a/changelogs/unreleased/feature-no-hypen-at-end-of-commit-ref-slug.yml b/changelogs/unreleased/feature-no-hypen-at-end-of-commit-ref-slug.yml new file mode 100644 index 00000000000..bbcf2946ea7 --- /dev/null +++ b/changelogs/unreleased/feature-no-hypen-at-end-of-commit-ref-slug.yml @@ -0,0 +1,4 @@ +--- +title: Omit trailing / leading hyphens in CI_COMMIT_REF_SLUG variable to make it usable as a hostname +merge_request: 11218 +author: Stefan Hanreich diff --git a/changelogs/unreleased/foreign-keys-for-project-model.yml b/changelogs/unreleased/foreign-keys-for-project-model.yml new file mode 100644 index 00000000000..3648b1c3735 --- /dev/null +++ b/changelogs/unreleased/foreign-keys-for-project-model.yml @@ -0,0 +1,4 @@ +--- +title: Speed up project removals by adding foreign keys with cascading deletes to various tables +merge_request: +author: diff --git a/changelogs/unreleased/hb-hide-archived-labels-from-group-issue-tracker.yml b/changelogs/unreleased/hb-hide-archived-labels-from-group-issue-tracker.yml new file mode 100644 index 00000000000..3b465d84126 --- /dev/null +++ b/changelogs/unreleased/hb-hide-archived-labels-from-group-issue-tracker.yml @@ -0,0 +1,4 @@ +--- +title: Hide archived project labels from group issue tracker +merge_request: 12547 +author: Horacio Bertorello diff --git a/changelogs/unreleased/monitoring-dashboard-fine-tuning-ux.yml b/changelogs/unreleased/monitoring-dashboard-fine-tuning-ux.yml new file mode 100644 index 00000000000..f84d41b7929 --- /dev/null +++ b/changelogs/unreleased/monitoring-dashboard-fine-tuning-ux.yml @@ -0,0 +1,4 @@ +--- +title: Improve the overall UX for the new monitoring dashboard +merge_request: +author: diff --git a/changelogs/unreleased/monitoring-dashboard-fix-y-label.yml b/changelogs/unreleased/monitoring-dashboard-fix-y-label.yml new file mode 100644 index 00000000000..8a0e9ca855c --- /dev/null +++ b/changelogs/unreleased/monitoring-dashboard-fix-y-label.yml @@ -0,0 +1,4 @@ +--- +title: Fixed the y_label not setting correctly for each graph on the monitoring dashboard +merge_request: +author: diff --git a/changelogs/unreleased/sh-allow-force-repo-create.yml b/changelogs/unreleased/sh-allow-force-repo-create.yml new file mode 100644 index 00000000000..2a65ba807bb --- /dev/null +++ b/changelogs/unreleased/sh-allow-force-repo-create.yml @@ -0,0 +1,4 @@ +--- +title: Make Project#ensure_repository force create a repo +merge_request: +author: diff --git a/changelogs/unreleased/sh-log-application-controller-exceptions-sentry.yml b/changelogs/unreleased/sh-log-application-controller-exceptions-sentry.yml new file mode 100644 index 00000000000..ec9ceab3d81 --- /dev/null +++ b/changelogs/unreleased/sh-log-application-controller-exceptions-sentry.yml @@ -0,0 +1,4 @@ +--- +title: Log rescued exceptions to Sentry +merge_request: +author: diff --git a/changelogs/unreleased/sh-optimize-project-commit-api.yml b/changelogs/unreleased/sh-optimize-project-commit-api.yml new file mode 100644 index 00000000000..e6a8a80593c --- /dev/null +++ b/changelogs/unreleased/sh-optimize-project-commit-api.yml @@ -0,0 +1,4 @@ +--- +title: Optimize creation of commit API by using Repository#commit instead of Repository#commits +merge_request: +author: diff --git a/config/application.rb b/config/application.rb index 3f39170a123..a9a961d7520 100644 --- a/config/application.rb +++ b/config/application.rb @@ -162,5 +162,25 @@ module Gitlab config.generators do |g| g.factory_girl false end + + config.after_initialize do + Rails.application.reload_routes! + + project_url_helpers = Module.new do + Gitlab::Application.routes.named_routes.helper_names.each do |name| + next unless name.include?('namespace_project') + + define_method(name.sub('namespace_project', 'project')) do |project, *args| + send(name, project&.namespace, project, *args) + end + end + end + + Gitlab::Routing.url_helpers.include project_url_helpers + Gitlab::Routing.url_helpers.extend project_url_helpers + + GitlabRoutingHelper.include project_url_helpers + GitlabRoutingHelper.extend project_url_helpers + end end end diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example index 43a8c0078ca..1eb209ac2be 100644 --- a/config/gitlab.yml.example +++ b/config/gitlab.yml.example @@ -543,6 +543,10 @@ production: &base # enabled: true # host: localhost # port: 3808 + prometheus: + # Time between sampling of unicorn socket metrics, in seconds + # unicorn_sampler_interval: 10 + # # 5. Extra customization @@ -615,6 +619,49 @@ test: title: "JIRA" url: https://sample_company.atlassian.net project_key: PROJECT + + omniauth: + enabled: true + allow_single_sign_on: true + external_providers: [] + + providers: + - { name: 'cas3', + label: 'cas3', + args: { url: 'https://sso.example.com', + disable_ssl_verification: false, + login_url: '/cas/login', + service_validate_url: '/cas/p3/serviceValidate', + logout_url: '/cas/logout'} } + - { name: 'github', + app_id: 'YOUR_APP_ID', + app_secret: 'YOUR_APP_SECRET', + url: "https://github.com/", + verify_ssl: false, + args: { scope: 'user:email' } } + - { name: 'bitbucket', + app_id: 'YOUR_APP_ID', + app_secret: 'YOUR_APP_SECRET' } + - { name: 'gitlab', + app_id: 'YOUR_APP_ID', + app_secret: 'YOUR_APP_SECRET', + args: { scope: 'api' } } + - { name: 'google_oauth2', + app_id: 'YOUR_APP_ID', + app_secret: 'YOUR_APP_SECRET', + args: { access_type: 'offline', approval_prompt: '' } } + - { name: 'facebook', + app_id: 'YOUR_APP_ID', + app_secret: 'YOUR_APP_SECRET' } + - { name: 'twitter', + app_id: 'YOUR_APP_ID', + app_secret: 'YOUR_APP_SECRET' } + - { name: 'auth0', + args: { + client_id: 'YOUR_AUTH0_CLIENT_ID', + client_secret: 'YOUR_AUTH0_CLIENT_SECRET', + namespace: 'YOUR_AUTH0_DOMAIN' } } + ldap: enabled: false servers: diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb index 8ddf8e4d2e4..cb11d2c34f4 100644 --- a/config/initializers/1_settings.rb +++ b/config/initializers/1_settings.rb @@ -495,6 +495,12 @@ Settings.webpack.dev_server['host'] ||= 'localhost' Settings.webpack.dev_server['port'] ||= 3808 # +# Prometheus metrics settings +# +Settings['prometheus'] ||= Settingslogic.new({}) +Settings.prometheus['unicorn_sampler_interval'] ||= 10 + +# # Testing settings # if Rails.env.test? diff --git a/config/initializers/8_metrics.rb b/config/initializers/8_metrics.rb index a0a63ddf8f0..d56fd7a6cfa 100644 --- a/config/initializers/8_metrics.rb +++ b/config/initializers/8_metrics.rb @@ -119,6 +119,13 @@ def instrument_classes(instrumentation) end # rubocop:enable Metrics/AbcSize +Gitlab::Metrics::UnicornSampler.initialize_instance(Settings.prometheus.unicorn_sampler_interval).start + +Gitlab::Application.configure do |config| + # 0 should be Sentry to catch errors in this middleware + config.middleware.insert(1, Gitlab::Metrics::ConnectionRackMiddleware) +end + if Gitlab::Metrics.enabled? require 'pathname' require 'influxdb' @@ -175,7 +182,7 @@ if Gitlab::Metrics.enabled? GC::Profiler.enable - Gitlab::Metrics::Sampler.new.start + Gitlab::Metrics::InfluxSampler.initialize_instance.start module TrackNewRedisConnections def connect(*args) diff --git a/config/initializers/doorkeeper_openid_connect.rb b/config/initializers/doorkeeper_openid_connect.rb index 4ff9019c43c..c58f425b19b 100644 --- a/config/initializers/doorkeeper_openid_connect.rb +++ b/config/initializers/doorkeeper_openid_connect.rb @@ -29,7 +29,7 @@ Doorkeeper::OpenidConnect.configure do o.claim(:email) { |user| user.public_email } o.claim(:email_verified) { |user| true if user.public_email? } o.claim(:website) { |user| user.full_website_url if user.website_url? } - o.claim(:profile) { |user| Rails.application.routes.url_helpers.user_url user } + o.claim(:profile) { |user| Gitlab::Routing.url_helpers.user_url user } o.claim(:picture) { |user| user.avatar_url(only_path: false) } end end diff --git a/config/initializers/flipper.rb b/config/initializers/flipper.rb index 0fee832788d..8ec9613a4b7 100644 --- a/config/initializers/flipper.rb +++ b/config/initializers/flipper.rb @@ -1,4 +1,6 @@ require 'flipper/middleware/memoizer' -Rails.application.config.middleware.use Flipper::Middleware::Memoizer, - lambda { Feature.flipper } +unless Rails.env.test? + Rails.application.config.middleware.use Flipper::Middleware::Memoizer, + lambda { Feature.flipper } +end diff --git a/config/initializers/relative_naming_ci_namespace.rb b/config/initializers/relative_naming_ci_namespace.rb index 03ac55be0b6..d9d3034150f 100644 --- a/config/initializers/relative_naming_ci_namespace.rb +++ b/config/initializers/relative_naming_ci_namespace.rb @@ -4,10 +4,10 @@ # - [project.namespace, project, build] # # instead of: -# - namespace_project_job_path(project.namespace, project, build) +# - project_job_path(project, build) # # Without that, Ci:: namespace is used for resolving routes: -# - namespace_project_ci_build_path(project.namespace, project, build) +# - project_ci_build_path(project, build) module Ci def self.use_relative_model_naming? diff --git a/config/prometheus/additional_metrics.yml b/config/prometheus/additional_metrics.yml index daecde49570..d33fae4182d 100644 --- a/config/prometheus/additional_metrics.yml +++ b/config/prometheus/additional_metrics.yml @@ -1,32 +1,82 @@ -- group: Kubernetes - priority: 1 +- group: AWS Elastic Load Balancer + priority: 10 metrics: - - title: "Memory usage" - y_label: "Values" + - title: "Throughput" + y_label: "Requests / Sec" required_metrics: - - container_memory_usage_bytes + - aws_elb_request_count_sum weight: 1 queries: - - query_range: 'avg(container_memory_usage_bytes{%{environment_filter}}) / 2^20' - label: Container memory - unit: MiB - - title: "Current memory usage" + - query_range: 'sum(aws_elb_request_count_sum{%{environment_filter}}) * 60' + label: Total + unit: req / sec + - title: "Latency" + y_label: "Latency (ms)" required_metrics: - - container_memory_usage_bytes + - aws_elb_latency_average weight: 1 queries: - - query: 'avg(container_memory_usage_bytes{%{environment_filter}}) / 2^20' - display_empty: false - unit: MiB - - title: "CPU usage" + - query_range: 'avg(aws_elb_latency_average{%{environment_filter}}) * 1000' + label: Average + unit: ms + - title: "HTTP Error Rate" + y_label: "Error Rate (%)" required_metrics: - - container_cpu_usage_seconds_total + - aws_elb_request_count_sum + - aws_elb_httpcode_backend_5_xx_sum + weight: 1 + queries: + - query_range: 'sum(aws_elb_httpcode_backend_5_xx_sum{%{environment_filter}}) / sum(aws_elb_request_count_sum{%{environment_filter}})' + label: HTTP Errors + unit: "%" +- group: NGINX + priority: 10 + metrics: + - title: "Throughput" + y_label: "Requests / Sec" + required_metrics: + - nginx_requests_total + weight: 1 + queries: + - query_range: 'sum(rate(nginx_requests_total{server_zone!="*", server_zone!="_", %{environment_filter}}[2m]))' + label: Total + unit: req / sec + - title: "Latency" + y_label: "Latency (ms)" + required_metrics: + - nginx_upstream_response_msecs_avg + weight: 1 + queries: + - query_range: 'avg(nginx_upstream_response_msecs_avg{%{environment_filter}}) * 1000' + label: Upstream + unit: ms + - title: "HTTP Error Rate" + y_label: "Error Rate (%)" + required_metrics: + - nginx_responses_total + weight: 1 + queries: + - query_range: 'sum(nginx_responses_total{status_code="5xx", %{environment_filter}}) / sum(nginx_responses_total{server_zone!="*", server_zone!="_", %{environment_filter}})' + label: HTTP Errors + unit: "%" +- group: Kubernetes + priority: 5 + metrics: + - title: "Memory Usage" + y_label: "Memory Usage (MB)" + required_metrics: + - container_memory_usage_bytes weight: 1 queries: - - query_range: 'avg(rate(container_cpu_usage_seconds_total{%{environment_filter}}[2m])) * 100' - - title: "Current CPU usage" + - query_range: '(sum(container_memory_usage_bytes{container_name!="POD",%{environment_filter}}) / count(container_memory_usage_bytes{container_name!="POD",%{environment_filter}})) /1024/1024' + label: Average + unit: MB + - title: "CPU Utilization" + y_label: "CPU Utilization (%)" required_metrics: - container_cpu_usage_seconds_total weight: 1 queries: - - query: 'avg(rate(container_cpu_usage_seconds_total{%{environment_filter}}[2m])) * 100' + - query_range: 'sum(rate(container_cpu_usage_seconds_total{container_name!="POD",%{environment_filter}}[2m])) / count(container_cpu_usage_seconds_total{container_name!="POD",%{environment_filter}}) * 100' + label: Average + unit: "%" diff --git a/db/migrate/20160804142904_add_ci_config_file_to_project.rb b/db/migrate/20160804142904_add_ci_config_file_to_project.rb new file mode 100644 index 00000000000..341ae555c1b --- /dev/null +++ b/db/migrate/20160804142904_add_ci_config_file_to_project.rb @@ -0,0 +1,11 @@ +class AddCiConfigFileToProject < ActiveRecord::Migration + DOWNTIME = false + + def change + add_column :projects, :ci_config_path, :string + end + + def down + remove_column :projects, :ci_config_path + end +end diff --git a/db/migrate/20170530130129_project_foreign_keys_with_cascading_deletes.rb b/db/migrate/20170530130129_project_foreign_keys_with_cascading_deletes.rb new file mode 100644 index 00000000000..3eaafac321d --- /dev/null +++ b/db/migrate/20170530130129_project_foreign_keys_with_cascading_deletes.rb @@ -0,0 +1,187 @@ +# See http://doc.gitlab.com/ce/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class ProjectForeignKeysWithCascadingDeletes < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + CONCURRENCY = 4 + + disable_ddl_transaction! + + # The tables/columns for which to remove orphans and add foreign keys. Order + # matters as some tables/columns should be processed before others. + TABLES = [ + [:boards, :projects, :project_id], + [:lists, :labels, :label_id], + [:lists, :boards, :board_id], + [:services, :projects, :project_id], + [:forked_project_links, :projects, :forked_to_project_id], + [:merge_requests, :projects, :target_project_id], + [:labels, :projects, :project_id], + [:issues, :projects, :project_id], + [:events, :projects, :project_id], + [:milestones, :projects, :project_id], + [:notes, :projects, :project_id], + [:snippets, :projects, :project_id], + [:web_hooks, :projects, :project_id], + [:protected_branch_merge_access_levels, :protected_branches, :protected_branch_id], + [:protected_branch_push_access_levels, :protected_branches, :protected_branch_id], + [:protected_branches, :projects, :project_id], + [:protected_tags, :projects, :project_id], + [:deploy_keys_projects, :projects, :project_id], + [:users_star_projects, :projects, :project_id], + [:releases, :projects, :project_id], + [:project_group_links, :projects, :project_id], + [:pages_domains, :projects, :project_id], + [:todos, :projects, :project_id], + [:project_import_data, :projects, :project_id], + [:project_features, :projects, :project_id], + [:ci_builds, :projects, :project_id], + [:ci_pipelines, :projects, :project_id], + [:ci_runner_projects, :projects, :project_id], + [:ci_triggers, :projects, :project_id], + [:environments, :projects, :project_id], + [:deployments, :projects, :project_id] + ] + + def up + # These existing foreign keys don't have an "ON DELETE CASCADE" clause. + remove_foreign_key_without_error(:boards, :project_id) + remove_foreign_key_without_error(:lists, :label_id) + remove_foreign_key_without_error(:lists, :board_id) + remove_foreign_key_without_error(:protected_branch_merge_access_levels, + :protected_branch_id) + + remove_foreign_key_without_error(:protected_branch_push_access_levels, + :protected_branch_id) + + remove_orphaned_rows + add_foreign_keys + + # These columns are not indexed yet, meaning a cascading delete would take + # forever. + add_concurrent_index(:project_group_links, :project_id) + add_concurrent_index(:pages_domains, :project_id) + end + + def down + TABLES.each do |(source, _, column)| + remove_foreign_key_without_error(source, column) + end + + add_concurrent_foreign_key(:boards, :projects, column: :project_id) + add_concurrent_foreign_key(:lists, :labels, column: :label_id) + add_concurrent_foreign_key(:lists, :boards, column: :board_id) + + add_concurrent_foreign_key(:protected_branch_merge_access_levels, + :protected_branches, + column: :protected_branch_id) + + add_concurrent_foreign_key(:protected_branch_push_access_levels, + :protected_branches, + column: :protected_branch_id) + + remove_index_without_error(:project_group_links, :project_id) + remove_index_without_error(:pages_domains, :project_id) + end + + def add_foreign_keys + TABLES.each do |(source, target, column)| + add_concurrent_foreign_key(source, target, column: column) + end + end + + # Removes orphans from various tables concurrently. + def remove_orphaned_rows + Gitlab::Database.with_connection_pool(CONCURRENCY) do |pool| + queues = queues_for_rows(TABLES) + + threads = queues.map do |queue| + Thread.new do + pool.with_connection do |connection| + Thread.current[:foreign_key_connection] = connection + + # Disables statement timeouts for the current connection. This is + # necessary as removing of orphaned data might otherwise exceed the + # statement timeout. + disable_statement_timeout + + remove_orphans(*queue.pop) until queue.empty? + + steal_from_queues(queues - [queue]) + end + end + end + + threads.each(&:join) + end + end + + def steal_from_queues(queues) + loop do + stolen = false + + queues.each do |queue| + # Stealing is racy so it's possible a pop might be called on an + # already-empty queue. + begin + remove_orphans(*queue.pop(true)) + stolen = true + rescue ThreadError + end + end + + break unless stolen + end + end + + def remove_orphans(source, target, column) + quoted_source = quote_table_name(source) + quoted_target = quote_table_name(target) + quoted_column = quote_column_name(column) + + execute <<-EOF.strip_heredoc + DELETE FROM #{quoted_source} + WHERE NOT EXISTS ( + SELECT true + FROM #{quoted_target} + WHERE #{quoted_target}.id = #{quoted_source}.#{quoted_column} + ) + AND #{quoted_source}.#{quoted_column} IS NOT NULL + EOF + end + + def remove_foreign_key_without_error(table, column) + remove_foreign_key(table, column: column) + rescue ArgumentError + end + + def remove_index_without_error(table, column) + remove_concurrent_index(table, column) + rescue ArgumentError + end + + def connection + # Rails memoizes connection objects, but this causes them to be shared + # amongst threads; we don't want that. + Thread.current[:foreign_key_connection] || ActiveRecord::Base.connection + end + + def queues_for_rows(rows) + queues = Array.new(CONCURRENCY) { Queue.new } + slice_size = rows.length / CONCURRENCY + + # Divide all the tuples as evenly as possible amongst the queues. + rows.each_slice(slice_size).each_with_index do |slice, index| + bucket = index % CONCURRENCY + + slice.each do |row| + queues[bucket] << row + end + end + + queues + end +end diff --git a/db/migrate/20170622130029_correct_protected_branches_foreign_keys.rb b/db/migrate/20170622130029_correct_protected_branches_foreign_keys.rb new file mode 100644 index 00000000000..46497775527 --- /dev/null +++ b/db/migrate/20170622130029_correct_protected_branches_foreign_keys.rb @@ -0,0 +1,40 @@ +# See http://doc.gitlab.com/ce/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class CorrectProtectedBranchesForeignKeys < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + # Set this constant to true if this migration requires downtime. + DOWNTIME = false + + disable_ddl_transaction! + + def up + remove_foreign_key_without_error(:protected_branch_push_access_levels, + column: :protected_branch_id) + + execute <<-EOF + DELETE FROM protected_branch_push_access_levels + WHERE NOT EXISTS ( + SELECT true + FROM protected_branches + WHERE protected_branch_push_access_levels.protected_branch_id = protected_branches.id + ) + AND protected_branch_id IS NOT NULL + EOF + + add_concurrent_foreign_key(:protected_branch_push_access_levels, + :protected_branches, + column: :protected_branch_id) + end + + def down + # Previously there was a foreign key without a CASCADING DELETE, so we'll + # just leave the foreign key in place. + end + + def remove_foreign_key_without_error(*args) + remove_foreign_key(*args) + rescue ArgumentError + end +end diff --git a/db/migrate/20170622132212_add_foreign_key_for_merge_request_diffs.rb b/db/migrate/20170622132212_add_foreign_key_for_merge_request_diffs.rb new file mode 100644 index 00000000000..9f524fac8a7 --- /dev/null +++ b/db/migrate/20170622132212_add_foreign_key_for_merge_request_diffs.rb @@ -0,0 +1,30 @@ +# See http://doc.gitlab.com/ce/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class AddForeignKeyForMergeRequestDiffs < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + # Set this constant to true if this migration requires downtime. + DOWNTIME = false + + disable_ddl_transaction! + + def up + execute <<-EOF + DELETE FROM merge_request_diffs + WHERE NOT EXISTS ( + SELECT true + FROM merge_requests + WHERE merge_requests.id = merge_request_diffs.merge_request_id + ) + EOF + + add_concurrent_foreign_key(:merge_request_diffs, + :merge_requests, + column: :merge_request_id) + end + + def down + remove_foreign_key(:merge_request_diffs, column: :merge_request_id) + end +end diff --git a/db/migrate/20170622135451_rename_duplicated_variable_key.rb b/db/migrate/20170622135451_rename_duplicated_variable_key.rb new file mode 100644 index 00000000000..368718ab0ce --- /dev/null +++ b/db/migrate/20170622135451_rename_duplicated_variable_key.rb @@ -0,0 +1,38 @@ +class RenameDuplicatedVariableKey < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + disable_ddl_transaction! + + def up + execute(<<~SQL) + UPDATE ci_variables + SET #{key} = CONCAT(#{key}, #{underscore}, id) + WHERE id IN ( + SELECT * + FROM ( -- MySQL requires an extra layer + SELECT dup.id + FROM ci_variables dup + INNER JOIN (SELECT max(id) AS id, #{key}, project_id + FROM ci_variables tmp + GROUP BY #{key}, project_id) var + USING (#{key}, project_id) where dup.id <> var.id + ) dummy + ) + SQL + end + + def down + # noop + end + + def key + # key needs to be quoted in MySQL + quote_column_name('key') + end + + def underscore + quote('_') + end +end diff --git a/db/migrate/20170622135628_add_environment_scope_to_ci_variables.rb b/db/migrate/20170622135628_add_environment_scope_to_ci_variables.rb new file mode 100644 index 00000000000..17fe062d8d5 --- /dev/null +++ b/db/migrate/20170622135628_add_environment_scope_to_ci_variables.rb @@ -0,0 +1,15 @@ +class AddEnvironmentScopeToCiVariables < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + disable_ddl_transaction! + + def up + add_column_with_default(:ci_variables, :environment_scope, :string, default: '*') + end + + def down + remove_column(:ci_variables, :environment_scope) + end +end diff --git a/db/migrate/20170622135728_add_unique_constraint_to_ci_variables.rb b/db/migrate/20170622135728_add_unique_constraint_to_ci_variables.rb new file mode 100644 index 00000000000..8b2cc40ee59 --- /dev/null +++ b/db/migrate/20170622135728_add_unique_constraint_to_ci_variables.rb @@ -0,0 +1,38 @@ +class AddUniqueConstraintToCiVariables < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + disable_ddl_transaction! + + def up + unless this_index_exists? + add_concurrent_index(:ci_variables, columns, name: index_name, unique: true) + end + end + + def down + if this_index_exists? + if Gitlab::Database.mysql? && !index_exists?(:ci_variables, :project_id) + # Need to add this index for MySQL project_id foreign key constraint + add_concurrent_index(:ci_variables, :project_id) + end + + remove_concurrent_index(:ci_variables, columns, name: index_name) + end + end + + private + + def this_index_exists? + index_exists?(:ci_variables, columns, name: index_name) + end + + def columns + @columns ||= [:project_id, :key, :environment_scope] + end + + def index_name + 'index_ci_variables_on_project_id_and_key_and_environment_scope' + end +end diff --git a/db/migrate/20170623080805_remove_ci_variables_project_id_index.rb b/db/migrate/20170623080805_remove_ci_variables_project_id_index.rb new file mode 100644 index 00000000000..ddcc0292b9d --- /dev/null +++ b/db/migrate/20170623080805_remove_ci_variables_project_id_index.rb @@ -0,0 +1,19 @@ +class RemoveCiVariablesProjectIdIndex < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + disable_ddl_transaction! + + def up + if index_exists?(:ci_variables, :project_id) + remove_concurrent_index(:ci_variables, :project_id) + end + end + + def down + unless index_exists?(:ci_variables, :project_id) + add_concurrent_index(:ci_variables, :project_id) + end + end +end diff --git a/db/migrate/20170703102400_add_stage_id_foreign_key_to_builds.rb b/db/migrate/20170703102400_add_stage_id_foreign_key_to_builds.rb new file mode 100644 index 00000000000..68b947583d3 --- /dev/null +++ b/db/migrate/20170703102400_add_stage_id_foreign_key_to_builds.rb @@ -0,0 +1,35 @@ +class AddStageIdForeignKeyToBuilds < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + disable_ddl_transaction! + + def up + unless index_exists?(:ci_builds, :stage_id) + add_concurrent_index(:ci_builds, :stage_id) + end + + unless foreign_key_exists?(:ci_builds, :stage_id) + add_concurrent_foreign_key(:ci_builds, :ci_stages, column: :stage_id, on_delete: :cascade) + end + end + + def down + if foreign_key_exists?(:ci_builds, :stage_id) + remove_foreign_key(:ci_builds, column: :stage_id) + end + + if index_exists?(:ci_builds, :stage_id) + remove_concurrent_index(:ci_builds, :stage_id) + end + end + + private + + def foreign_key_exists?(table, column) + foreign_keys(:ci_builds).any? do |key| + key.options[:column] == column.to_s + end + end +end diff --git a/db/post_migrate/20170621102400_add_stage_id_index_to_builds.rb b/db/post_migrate/20170621102400_add_stage_id_index_to_builds.rb index 7d6609b18bf..ac61b5c84a8 100644 --- a/db/post_migrate/20170621102400_add_stage_id_index_to_builds.rb +++ b/db/post_migrate/20170621102400_add_stage_id_index_to_builds.rb @@ -3,19 +3,15 @@ class AddStageIdIndexToBuilds < ActiveRecord::Migration DOWNTIME = false - disable_ddl_transaction! + ## + # Improved in 20170703102400_add_stage_id_foreign_key_to_builds.rb + # def up - unless index_exists?(:ci_builds, :stage_id) - add_concurrent_foreign_key(:ci_builds, :ci_stages, column: :stage_id, on_delete: :cascade) - add_concurrent_index(:ci_builds, :stage_id) - end + # noop end def down - if index_exists?(:ci_builds, :stage_id) - remove_foreign_key(:ci_builds, column: :stage_id) - remove_concurrent_index(:ci_builds, :stage_id) - end + # noop end end diff --git a/db/schema.rb b/db/schema.rb index 8c7440ee610..f12fdf903c5 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20170622162730) do +ActiveRecord::Schema.define(version: 20170703102400) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -374,9 +374,10 @@ ActiveRecord::Schema.define(version: 20170622162730) do t.string "encrypted_value_iv" t.integer "project_id", null: false t.boolean "protected", default: false, null: false + t.string "environment_scope", default: "*", null: false end - add_index "ci_variables", ["project_id"], name: "index_ci_variables_on_project_id", using: :btree + add_index "ci_variables", ["project_id", "key", "environment_scope"], name: "index_ci_variables_on_project_id_and_key_and_environment_scope", unique: true, using: :btree create_table "container_repositories", force: :cascade do |t| t.integer "project_id", null: false @@ -970,6 +971,7 @@ ActiveRecord::Schema.define(version: 20170622162730) do end add_index "pages_domains", ["domain"], name: "index_pages_domains_on_domain", unique: true, using: :btree + add_index "pages_domains", ["project_id"], name: "index_pages_domains_on_project_id", using: :btree create_table "personal_access_tokens", force: :cascade do |t| t.integer "user_id", null: false @@ -1019,6 +1021,7 @@ ActiveRecord::Schema.define(version: 20170622162730) do end add_index "project_group_links", ["group_id"], name: "index_project_group_links_on_group_id", using: :btree + add_index "project_group_links", ["project_id"], name: "index_project_group_links_on_project_id", using: :btree create_table "project_import_data", force: :cascade do |t| t.integer "project_id" @@ -1085,6 +1088,7 @@ ActiveRecord::Schema.define(version: 20170622162730) do t.string "import_jid" t.integer "cached_markdown_version" t.datetime "last_repository_updated_at" + t.string "ci_config_path" end add_index "projects", ["ci_id"], name: "index_projects_on_ci_id", using: :btree @@ -1526,48 +1530,75 @@ ActiveRecord::Schema.define(version: 20170622162730) do add_index "web_hooks", ["project_id"], name: "index_web_hooks_on_project_id", using: :btree add_index "web_hooks", ["type"], name: "index_web_hooks_on_type", using: :btree - add_foreign_key "boards", "projects" + add_foreign_key "boards", "projects", name: "fk_f15266b5f9", on_delete: :cascade add_foreign_key "chat_teams", "namespaces", on_delete: :cascade add_foreign_key "ci_builds", "ci_pipelines", column: "auto_canceled_by_id", name: "fk_a2141b1522", on_delete: :nullify add_foreign_key "ci_builds", "ci_stages", column: "stage_id", name: "fk_3a9eaa254d", on_delete: :cascade + add_foreign_key "ci_builds", "projects", name: "fk_befce0568a", on_delete: :cascade add_foreign_key "ci_pipeline_schedules", "projects", name: "fk_8ead60fcc4", on_delete: :cascade add_foreign_key "ci_pipeline_schedules", "users", column: "owner_id", name: "fk_9ea99f58d2", on_delete: :nullify add_foreign_key "ci_pipelines", "ci_pipeline_schedules", column: "pipeline_schedule_id", name: "fk_3d34ab2e06", on_delete: :nullify add_foreign_key "ci_pipelines", "ci_pipelines", column: "auto_canceled_by_id", name: "fk_262d4c2d19", on_delete: :nullify + add_foreign_key "ci_pipelines", "projects", name: "fk_86635dbd80", on_delete: :cascade + add_foreign_key "ci_runner_projects", "projects", name: "fk_4478a6f1e4", on_delete: :cascade add_foreign_key "ci_stages", "ci_pipelines", column: "pipeline_id", name: "fk_fb57e6cc56", on_delete: :cascade add_foreign_key "ci_stages", "projects", name: "fk_2360681d1d", on_delete: :cascade add_foreign_key "ci_trigger_requests", "ci_triggers", column: "trigger_id", name: "fk_b8ec8b7245", on_delete: :cascade + add_foreign_key "ci_triggers", "projects", name: "fk_e3e63f966e", on_delete: :cascade add_foreign_key "ci_triggers", "users", column: "owner_id", name: "fk_e8e10d1964", on_delete: :cascade add_foreign_key "ci_variables", "projects", name: "fk_ada5eb64b3", on_delete: :cascade add_foreign_key "container_repositories", "projects" + add_foreign_key "deploy_keys_projects", "projects", name: "fk_58a901ca7e", on_delete: :cascade + add_foreign_key "deployments", "projects", name: "fk_b9a3851b82", on_delete: :cascade + add_foreign_key "environments", "projects", name: "fk_d1c8c1da6a", on_delete: :cascade + add_foreign_key "events", "projects", name: "fk_0434b48643", on_delete: :cascade + add_foreign_key "forked_project_links", "projects", column: "forked_to_project_id", name: "fk_434510edb0", on_delete: :cascade add_foreign_key "issue_assignees", "issues", name: "fk_b7d881734a", on_delete: :cascade add_foreign_key "issue_assignees", "users", name: "fk_5e0c8d9154", on_delete: :cascade add_foreign_key "issue_metrics", "issues", on_delete: :cascade + add_foreign_key "issues", "projects", name: "fk_899c8f3231", on_delete: :cascade add_foreign_key "label_priorities", "labels", on_delete: :cascade add_foreign_key "label_priorities", "projects", on_delete: :cascade add_foreign_key "labels", "namespaces", column: "group_id", on_delete: :cascade - add_foreign_key "lists", "boards" - add_foreign_key "lists", "labels" + add_foreign_key "labels", "projects", name: "fk_7de4989a69", on_delete: :cascade + add_foreign_key "lists", "boards", name: "fk_0d3f677137", on_delete: :cascade + add_foreign_key "lists", "labels", name: "fk_7a5553d60f", on_delete: :cascade add_foreign_key "merge_request_diff_files", "merge_request_diffs", on_delete: :cascade + add_foreign_key "merge_request_diffs", "merge_requests", name: "fk_8483f3258f", on_delete: :cascade add_foreign_key "merge_request_metrics", "ci_pipelines", column: "pipeline_id", on_delete: :cascade add_foreign_key "merge_request_metrics", "merge_requests", on_delete: :cascade + add_foreign_key "merge_requests", "projects", column: "target_project_id", name: "fk_a6963e8447", on_delete: :cascade add_foreign_key "merge_requests_closing_issues", "issues", on_delete: :cascade add_foreign_key "merge_requests_closing_issues", "merge_requests", on_delete: :cascade + add_foreign_key "milestones", "projects", name: "fk_9bd0a0c791", on_delete: :cascade + add_foreign_key "notes", "projects", name: "fk_99e097b079", on_delete: :cascade add_foreign_key "oauth_openid_requests", "oauth_access_grants", column: "access_grant_id", name: "fk_oauth_openid_requests_oauth_access_grants_access_grant_id" + add_foreign_key "pages_domains", "projects", name: "fk_ea2f6dfc6f", on_delete: :cascade add_foreign_key "personal_access_tokens", "users" add_foreign_key "project_authorizations", "projects", on_delete: :cascade add_foreign_key "project_authorizations", "users", on_delete: :cascade + add_foreign_key "project_features", "projects", name: "fk_18513d9b92", on_delete: :cascade + add_foreign_key "project_group_links", "projects", name: "fk_daa8cee94c", on_delete: :cascade + add_foreign_key "project_import_data", "projects", name: "fk_ffb9ee3a10", on_delete: :cascade add_foreign_key "project_statistics", "projects", on_delete: :cascade - add_foreign_key "protected_branch_merge_access_levels", "protected_branches" - add_foreign_key "protected_branch_push_access_levels", "protected_branches" + add_foreign_key "protected_branch_merge_access_levels", "protected_branches", name: "fk_8a3072ccb3", on_delete: :cascade + add_foreign_key "protected_branch_push_access_levels", "protected_branches", name: "fk_9ffc86a3d9", on_delete: :cascade + add_foreign_key "protected_branches", "projects", name: "fk_7a9c6d93e7", on_delete: :cascade add_foreign_key "protected_tag_create_access_levels", "namespaces", column: "group_id" add_foreign_key "protected_tag_create_access_levels", "protected_tags" add_foreign_key "protected_tag_create_access_levels", "users" + add_foreign_key "protected_tags", "projects", name: "fk_8e4af87648", on_delete: :cascade + add_foreign_key "releases", "projects", name: "fk_47fe2a0596", on_delete: :cascade + add_foreign_key "services", "projects", name: "fk_71cce407f9", on_delete: :cascade + add_foreign_key "snippets", "projects", name: "fk_be41fd4bb7", on_delete: :cascade add_foreign_key "subscriptions", "projects", on_delete: :cascade add_foreign_key "system_note_metadata", "notes", name: "fk_d83a918cb1", on_delete: :cascade add_foreign_key "timelogs", "issues", name: "fk_timelogs_issues_issue_id", on_delete: :cascade add_foreign_key "timelogs", "merge_requests", name: "fk_timelogs_merge_requests_merge_request_id", on_delete: :cascade + add_foreign_key "todos", "projects", name: "fk_45054f9c45", on_delete: :cascade add_foreign_key "trending_projects", "projects", on_delete: :cascade add_foreign_key "u2f_registrations", "users" + add_foreign_key "users_star_projects", "projects", name: "fk_22cd27ddfc", on_delete: :cascade add_foreign_key "web_hook_logs", "web_hooks", on_delete: :cascade + add_foreign_key "web_hooks", "projects", name: "fk_0c8ca6d9d1", on_delete: :cascade end diff --git a/doc/api/projects.md b/doc/api/projects.md index cc1bb3911c8..0d892c74d00 100644 --- a/doc/api/projects.md +++ b/doc/api/projects.md @@ -173,6 +173,164 @@ Parameters: ] ``` +### List a user's projects + +Get a list of visible projects for the given user. When accessed without authentication, only public projects are returned. + +``` +GET /users/:user_id/projects +``` + +Parameters: + +| Attribute | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `user_id` | string | yes | The ID or username of the user | +| `archived` | boolean | no | Limit by archived status | +| `visibility` | string | no | Limit by visibility `public`, `internal`, or `private` | +| `order_by` | string | no | Return projects ordered by `id`, `name`, `path`, `created_at`, `updated_at`, or `last_activity_at` fields. Default is `created_at` | +| `sort` | string | no | Return projects sorted in `asc` or `desc` order. Default is `desc` | +| `search` | string | no | Return list of projects matching the search criteria | +| `simple` | boolean | no | Return only the ID, URL, name, and path of each project | +| `owned` | boolean | no | Limit by projects owned by the current user | +| `membership` | boolean | no | Limit by projects that the current user is a member of | +| `starred` | boolean | no | Limit by projects starred by the current user | +| `statistics` | boolean | no | Include project statistics | +| `with_issues_enabled` | boolean | no | Limit by enabled issues feature | +| `with_merge_requests_enabled` | boolean | no | Limit by enabled merge requests feature | + +```json +[ + { + "id": 4, + "description": null, + "default_branch": "master", + "visibility": "private", + "ssh_url_to_repo": "git@example.com:diaspora/diaspora-client.git", + "http_url_to_repo": "http://example.com/diaspora/diaspora-client.git", + "web_url": "http://example.com/diaspora/diaspora-client", + "tag_list": [ + "example", + "disapora client" + ], + "owner": { + "id": 3, + "name": "Diaspora", + "created_at": "2013-09-30T13:46:02Z" + }, + "name": "Diaspora Client", + "name_with_namespace": "Diaspora / Diaspora Client", + "path": "diaspora-client", + "path_with_namespace": "diaspora/diaspora-client", + "issues_enabled": true, + "open_issues_count": 1, + "merge_requests_enabled": true, + "jobs_enabled": true, + "wiki_enabled": true, + "snippets_enabled": false, + "container_registry_enabled": false, + "created_at": "2013-09-30T13:46:02Z", + "last_activity_at": "2013-09-30T13:46:02Z", + "creator_id": 3, + "namespace": { + "id": 3, + "name": "Diaspora", + "path": "diaspora", + "kind": "group", + "full_path": "diaspora" + }, + "import_status": "none", + "archived": false, + "avatar_url": "http://example.com/uploads/project/avatar/4/uploads/avatar.png", + "shared_runners_enabled": true, + "forks_count": 0, + "star_count": 0, + "runners_token": "b8547b1dc37721d05889db52fa2f02", + "public_jobs": true, + "shared_with_groups": [], + "only_allow_merge_if_pipeline_succeeds": false, + "only_allow_merge_if_all_discussions_are_resolved": false, + "request_access_enabled": false, + "statistics": { + "commit_count": 37, + "storage_size": 1038090, + "repository_size": 1038090, + "lfs_objects_size": 0, + "job_artifacts_size": 0 + } + }, + { + "id": 6, + "description": null, + "default_branch": "master", + "visibility": "private", + "ssh_url_to_repo": "git@example.com:brightbox/puppet.git", + "http_url_to_repo": "http://example.com/brightbox/puppet.git", + "web_url": "http://example.com/brightbox/puppet", + "tag_list": [ + "example", + "puppet" + ], + "owner": { + "id": 4, + "name": "Brightbox", + "created_at": "2013-09-30T13:46:02Z" + }, + "name": "Puppet", + "name_with_namespace": "Brightbox / Puppet", + "path": "puppet", + "path_with_namespace": "brightbox/puppet", + "issues_enabled": true, + "open_issues_count": 1, + "merge_requests_enabled": true, + "jobs_enabled": true, + "wiki_enabled": true, + "snippets_enabled": false, + "container_registry_enabled": false, + "created_at": "2013-09-30T13:46:02Z", + "last_activity_at": "2013-09-30T13:46:02Z", + "creator_id": 3, + "namespace": { + "id": 4, + "name": "Brightbox", + "path": "brightbox", + "kind": "group", + "full_path": "brightbox" + }, + "import_status": "none", + "import_error": null, + "permissions": { + "project_access": { + "access_level": 10, + "notification_level": 3 + }, + "group_access": { + "access_level": 50, + "notification_level": 3 + } + }, + "archived": false, + "avatar_url": null, + "shared_runners_enabled": true, + "forks_count": 0, + "star_count": 0, + "runners_token": "b8547b1dc37721d05889db52fa2f02", + "public_jobs": true, + "shared_with_groups": [], + "only_allow_merge_if_pipeline_succeeds": false, + "only_allow_merge_if_all_discussions_are_resolved": false, + "request_access_enabled": false, + "statistics": { + "commit_count": 12, + "storage_size": 2066080, + "repository_size": 2066080, + "lfs_objects_size": 0, + "job_artifacts_size": 0 + } + } +] +``` + ### Get single project Get a specific project. This endpoint can be accessed without authentication if @@ -336,7 +494,7 @@ Parameters: | `snippets_enabled` | boolean | no | Enable snippets for this project | | `container_registry_enabled` | boolean | no | Enable container registry for this project | | `shared_runners_enabled` | boolean | no | Enable shared runners for this project | -| `visibility` | String | no | See [project visibility level](#project-visibility-level) | +| `visibility` | string | no | See [project visibility level](#project-visibility-level) | | `import_url` | string | no | URL to import repository from | | `public_jobs` | boolean | no | If `true`, jobs can be viewed by non-project-members | | `only_allow_merge_if_pipeline_succeeds` | boolean | no | Set whether merge requests can only be merged with successful jobs | @@ -346,6 +504,7 @@ Parameters: | `tag_list` | array | no | The list of tags for a project; put array of tags, that should be finally assigned to a project | | `avatar` | mixed | no | Image file for avatar of the project | | `printing_merge_request_link_enabled` | boolean | no | Show link to create/view merge request when pushing from the command line | +| `ci_config_path` | string | no | The path to CI config file | ### Create project for user @@ -382,6 +541,7 @@ Parameters: | `tag_list` | array | no | The list of tags for a project; put array of tags, that should be finally assigned to a project | | `avatar` | mixed | no | Image file for avatar of the project | | `printing_merge_request_link_enabled` | boolean | no | Show link to create/view merge request when pushing from the command line | +| `ci_config_path` | string | no | The path to CI config file | ### Edit project @@ -416,6 +576,7 @@ Parameters: | `request_access_enabled` | boolean | no | Allow users to request member access | | `tag_list` | array | no | The list of tags for a project; put array of tags, that should be finally assigned to a project | | `avatar` | mixed | no | Image file for avatar of the project | +| `ci_config_path` | string | no | The path to CI config file | ### Fork project diff --git a/doc/api/repository_files.md b/doc/api/repository_files.md index 18ceb8f779e..1fc577561a0 100644 --- a/doc/api/repository_files.md +++ b/doc/api/repository_files.md @@ -61,7 +61,7 @@ POST /projects/:id/repository/files/:file_path ``` ```bash -curl --request POST --header 'PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK' 'https://gitlab.example.com/api/v4/projects/13083/repository/app%2Fprojectrb%2E?branch=master&author_email=author%40example.com&author_name=Firstname%20Lastname&content=some%20content&commit_message=create%20a%20new%20file' +curl --request POST --header 'PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK' 'https://gitlab.example.com/api/v4/projects/13083/repository/files/app%2Fprojectrb%2E?branch=master&author_email=author%40example.com&author_name=Firstname%20Lastname&content=some%20content&commit_message=create%20a%20new%20file' ``` Example response: @@ -90,7 +90,7 @@ PUT /projects/:id/repository/files/:file_path ``` ```bash -curl --request PUT --header 'PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK' 'https://gitlab.example.com/api/v4/projects/13083/repository/app%2Fproject%2Erb?branch=master&author_email=author%40example.com&author_name=Firstname%20Lastname&content=some%20other%20content&commit_message=update%20file' +curl --request PUT --header 'PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK' 'https://gitlab.example.com/api/v4/projects/13083/repository/files/app%2Fproject%2Erb?branch=master&author_email=author%40example.com&author_name=Firstname%20Lastname&content=some%20other%20content&commit_message=update%20file' ``` Example response: @@ -129,7 +129,7 @@ DELETE /projects/:id/repository/files/:file_path ``` ```bash -curl --request DELETE --header 'PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK' 'https://gitlab.example.com/api/v4/projects/13083/repository/app%2Fproject%2Erb?branch=master&author_email=author%40example.com&author_name=Firstname%20Lastname&commit_message=delete%20file' +curl --request DELETE --header 'PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK' 'https://gitlab.example.com/api/v4/projects/13083/repository/files/app%2Fproject%2Erb?branch=master&author_email=author%40example.com&author_name=Firstname%20Lastname&commit_message=delete%20file' ``` Example response: diff --git a/doc/ci/docker/using_docker_images.md b/doc/ci/docker/using_docker_images.md index be4dea55c20..d3433594eb7 100644 --- a/doc/ci/docker/using_docker_images.md +++ b/doc/ci/docker/using_docker_images.md @@ -1,4 +1,4 @@ -# Using Docker Images +# Using Docker images GitLab CI in conjunction with [GitLab Runner](../runners/README.md) can use [Docker Engine](https://www.docker.com/) to test and build any application. @@ -17,14 +17,16 @@ can also run on your workstation. The added benefit is that you can test all the commands that we will explore later from your shell, rather than having to test them on a dedicated CI server. -## Register docker runner +## Register Docker Runner -To use GitLab Runner with docker you need to register a new runner to use the -`docker` executor: +To use GitLab Runner with Docker you need to [register a new Runner][register] +to use the `docker` executor. + +A one-line example can be seen below: ```bash -gitlab-ci-multi-runner register \ - --url "https://gitlab.com/" \ +sudo gitlab-runner register \ + --url "https://gitlab.example.com/" \ --registration-token "PROJECT_REGISTRATION_TOKEN" \ --description "docker-ruby-2.1" \ --executor "docker" \ @@ -33,26 +35,26 @@ gitlab-ci-multi-runner register \ --docker-mysql latest ``` -The registered runner will use the `ruby:2.1` docker image and will run two +The registered runner will use the `ruby:2.1` Docker image and will run two services, `postgres:latest` and `mysql:latest`, both of which will be accessible during the build process. ## What is an image -The `image` keyword is the name of the docker image the docker executor -will run to perform the CI tasks. +The `image` keyword is the name of the Docker image the Docker executor +will run to perform the CI tasks. -By default the executor will only pull images from [Docker Hub][hub], +By default, the executor will only pull images from [Docker Hub][hub], but this can be configured in the `gitlab-runner/config.toml` by setting -the [docker pull policy][] to allow using local images. +the [Docker pull policy][] to allow using local images. For more information about images and Docker Hub please read the [Docker Fundamentals][] documentation. ## What is a service -The `services` keyword defines just another docker image that is run during -your job and is linked to the docker image that the `image` keyword defines. +The `services` keyword defines just another Docker image that is run during +your job and is linked to the Docker image that the `image` keyword defines. This allows you to access the service image during build time. The service image can run any application, but the most common use case is to @@ -60,6 +62,11 @@ run a database container, eg. `mysql`. It's easier and faster to use an existing image and run it as an additional container than install `mysql` every time the project is built. +You are not limited to have only database services. You can add as many +services you need to `.gitlab-ci.yml` or manually modify `config.toml`. +Any image found at [Docker Hub][hub] or your private Container Registry can be +used as a service. + You can see some widely used services examples in the relevant documentation of [CI services examples](../services/README.md). @@ -73,22 +80,49 @@ then be used to create a container that is linked to the job container. The service container for MySQL will be accessible under the hostname `mysql`. So, in order to access your database service you have to connect to the host -named `mysql` instead of a socket or `localhost`. +named `mysql` instead of a socket or `localhost`. Read more in [accessing the +services](#accessing-the-services). -## Overwrite image and services +### Accessing the services -See [How to use other images as services](#how-to-use-other-images-as-services). +Let's say that you need a Wordpress instance to test some API integration with +your application. -## How to use other images as services +You can then use for example the [tutum/wordpress][] image in your +`.gitlab-ci.yml`: -You are not limited to have only database services. You can add as many -services you need to `.gitlab-ci.yml` or manually modify `config.toml`. -Any image found at [Docker Hub][hub] can be used as a service. +```yaml +services: +- tutum/wordpress:latest +``` + +If you don't [specify a service alias](#available-settings-for-services-entry), +when the job is run, `tutum/wordpress` will be started and you will have +access to it from your build container under two hostnames to choose from: -## Define image and services from `.gitlab-ci.yml` +- `tutum-wordpress` +- `tutum__wordpress` + +>**Note:** +Hostnames with underscores are not RFC valid and may cause problems in 3rd party +applications. + +The default aliases for the service's hostname are created from its image name +following these rules: + +- Everything after the colon (`:`) is stripped +- Slash (`/`) is replaced with double underscores (`__`) and the primary alias + is created +- Slash (`/`) is replaced with a single dash (`-`) and the secondary alias is + created (requires GitLab Runner v1.1.0 or higher) + +To override the default behavior, you can +[specify a service alias](#available-settings-for-services-entry). + +## Define `image` and `services` from `.gitlab-ci.yml` You can simply define an image that will be used for all jobs and a list of -services that you want to use during build time. +services that you want to use during build time: ```yaml image: ruby:2.2 @@ -125,6 +159,203 @@ test:2.2: - bundle exec rake spec ``` +Or you can pass some [extended configuration options](#extended-docker-configuration-options) +for `image` and `services`: + +```yaml +image: + name: ruby:2.2 + entrypoint: ["/bin/bash"] + +services: +- name: my-postgres:9.4 + alias: db-postgres + entrypoint: ["/usr/local/bin/db-postgres"] + command: ["start"] + +before_script: +- bundle install + +test: + script: + - bundle exec rake spec +``` + +## Extended Docker configuration options + +> **Note:** +This feature requires GitLab 9.4 and GitLab Runner 9.4 or higher. + +When configuring the `image` or `services` entries, you can use a string or a map as +options: + +- when using a string as an option, it must be the full name of the image to use + (including the Registry part if you want to download the image from a Registry + other than Docker Hub) +- when using a map as an option, then it must contain at least the `name` + option, which is the same name of the image as used for the string setting + +For example, the following two definitions are equal: + +1. Using a string as an option to `image` and `services`: + + ```yaml + image: "registry.example.com/my/image:latest" + + services: + - postgresql:9.4 + - redis:latest + ``` + +1. Using a map as an option to `image` and `services`. The use of `image:name` is + required: + + ```yaml + image: + name: "registry.example.com/my/image:latest" + + services: + - name: postgresql:9.4 + - name: redis:latest + ``` + +### Available settings for `image` + +> **Note:** +This feature requires GitLab 9.4 and GitLab Runner 9.4 or higher. + +| Setting | Required | Description | +|------------|----------|-------------| +| `name` | yes, when used with any other option | Full name of the image that should be used. It should contain the Registry part if needed. | +| `entrypoint` | no | Command or script that should be executed as the container's entrypoint. It will be translated to Docker's `--entrypoint` option while creating the container. The syntax is similar to [`Dockerfile`'s `ENTRYPOINT`][entrypoint] directive, where each shell token is a separate string in the array. | + +### Available settings for `services` + +> **Note:** +This feature requires GitLab 9.4 and GitLab Runner 9.4 or higher. + +| Setting | Required | Description | +|------------|----------|-------------| +| `name` | yes, when used with any other option | Full name of the image that should be used. It should contain the Registry part if needed. | +| `entrypoint` | no | Command or script that should be executed as the container's entrypoint. It will be translated to Docker's `--entrypoint` option while creating the container. The syntax is similar to [`Dockerfile`'s `ENTRYPOINT`][entrypoint] directive, where each shell token is a separate string in the array. | +| `command` | no | Command or script that should be used as the container's command. It will be translated to arguments passed to Docker after the image's name. The syntax is similar to [`Dockerfile`'s `CMD`][cmd] directive, where each shell token is a separate string in the array. | +| `alias` | no | Additional alias that can be used to access the service from the job's container. Read [Accessing the services](#accessing-the-services) for more information. | + +### Starting multiple services from the same image + +Before the new extended Docker configuration options, the following configuration +would not work properly: + +```yaml +services: +- mysql:latest +- mysql:latest +``` + +The Runner would start two containers using the `mysql:latest` image, but both +of them would be added to the job's container with the `mysql` alias based on +the [default hostname naming](#accessing-the-services). This would end with one +of the services not being accessible. + +After the new extended Docker configuration options, the above example would +look like: + +```yaml +services: +- name: mysql:latest + alias: mysql-1 +- name: mysql:latest + alias: mysql-2 +``` + +The Runner will still start two containers using the `mysql:latest` image, +but now each of them will also be accessible with the alias configured +in `.gitlab-ci.yml` file. + +### Setting a command for the service + +Let's assume you have a `super/sql:latest` image with some SQL database +inside it and you would like to use it as a service for your job. Let's also +assume that this image doesn't start the database process while starting +the container and the user needs to manually use `/usr/bin/super-sql run` as +a command to start the database. + +Before the new extended Docker configuration options, you would need to create +your own image based on the `super/sql:latest` image, add the default command, +and then use it in job's configuration, like: + +```Dockerfile +# my-super-sql:latest image's Dockerfile + +FROM super/sql:latest +CMD ["/usr/bin/super-sql", "run"] +``` + +```yaml +# .gitlab-ci.yml + +services: +- my-super-sql:latest +``` + +After the new extended Docker configuration options, you can now simply +set a `command` in `.gitlab-ci.yml`, like: + +```yaml +# .gitlab-ci.yml + +services: +- name: super/sql:latest + command: ["/usr/bin/super-sql", "run"] +``` + +As you can see, the syntax of `command` is similar to [Dockerfile's `CMD`][cmd]. + +### Overriding the entrypoint of an image + +Let's assume you have a `super/sql:experimental` image with some SQL database +inside it and you would like to use it as a base image for your job because you +want to execute some tests with this database binary. Let's also assume that +this image is configured with `/usr/bin/super-sql run` as an entrypoint. That +means, that when starting the container without additional options, it will run +the database's process, while Runner expects that the image will have no +entrypoint or at least will start with a shell as its entrypoint. + +Previously we would need to create our own image based on the +`super/sql:experimental` image, set the entrypoint to a shell, and then use +it in job's configuration, e.g.: + +Before the new extended Docker configuration options, you would need to create +your own image based on the `super/sql:experimental` image, set the entrypoint +to a shell and then use it in job's configuration, like: + +```Dockerfile +# my-super-sql:experimental image's Dockerfile + +FROM super/sql:experimental +ENTRYPOINT ["/bin/sh"] +``` + +```yaml +# .gitlab-ci.yml + +image: my-super-sql:experimental +``` + +After the new extended Docker configuration options, you can now simply +set an `entrypoint` in `.gitlab-ci.yml`, like: + +```yaml +# .gitlab-ci.yml + +image: + name: super/sql:experimental + entrypoint: ["/bin/sh"] +``` + +As you can see the syntax of `entrypoint` is similar to +[Dockerfile's `ENTRYPOINT`][entrypoint]. + ## Define image and services in `config.toml` Look for the `[runners.docker]` section: @@ -138,7 +369,7 @@ Look for the `[runners.docker]` section: The image and services defined this way will be added to all job run by that runner. -## Define an image from a private Docker registry +## Define an image from a private Container Registry > **Notes:** - This feature requires GitLab Runner **1.8** or higher @@ -193,44 +424,6 @@ To configure access for `registry.example.com`, follow these steps: You can add configuration for as many registries as you want, adding more registries to the `"auths"` hash as described above. -## Accessing the services - -Let's say that you need a Wordpress instance to test some API integration with -your application. - -You can then use for example the [tutum/wordpress][] image in your -`.gitlab-ci.yml`: - -```yaml -services: -- tutum/wordpress:latest -``` - -When the job is run, `tutum/wordpress` will be started and you will have -access to it from your build container under the hostnames `tutum-wordpress` -(requires GitLab Runner v1.1.0 or newer) and `tutum__wordpress`. - -When using a private registry, the image name also includes a hostname and port -of the registry. - -```yaml -services: -- docker.example.com:5000/wordpress:latest -``` - -The service hostname will also include the registry hostname. Service will be -available under hostnames `docker.example.com-wordpress` (requires GitLab Runner v1.1.0 or newer) -and `docker.example.com__wordpress`. - -*Note: hostname with underscores is not RFC valid and may cause problems in 3rd party applications.* - -The alias hostnames for the service are made from the image name following these -rules: - -1. Everything after `:` is stripped -2. Slash (`/`) is replaced with double underscores (`__`) - primary alias -3. Slash (`/`) is replaced with dash (`-`) - secondary alias, requires GitLab Runner v1.1.0 or newer - ## Configuring services Many services accept environment variables which allow you to easily change @@ -257,7 +450,7 @@ See the specific documentation for ## How Docker integration works -Below is a high level overview of the steps performed by docker during job +Below is a high level overview of the steps performed by Docker during job time. 1. Create any service container: `mysql`, `postgresql`, `mongodb`, `redis`. @@ -274,7 +467,7 @@ time. ## How to debug a job locally *Note: The following commands are run without root privileges. You should be -able to run docker with your regular user account.* +able to run Docker with your regular user account.* First start with creating a file named `build_script`: @@ -334,3 +527,6 @@ creation. [mysql-hub]: https://hub.docker.com/r/_/mysql/ [runner-priv-reg]: http://docs.gitlab.com/runner/configuration/advanced-configuration.html#using-a-private-container-registry [secret variable]: ../variables/README.md#secret-variables +[entrypoint]: https://docs.docker.com/engine/reference/builder/#entrypoint +[cmd]: https://docs.docker.com/engine/reference/builder/#cmd +[register]: https://docs.gitlab.com/runner/register/ diff --git a/doc/ci/variables/README.md b/doc/ci/variables/README.md index d1f9881e51b..3501aae75ec 100644 --- a/doc/ci/variables/README.md +++ b/doc/ci/variables/README.md @@ -37,9 +37,10 @@ future GitLab releases.** |-------------------------------- |--------|--------|-------------| | **CI** | all | 0.4 | Mark that job is executed in CI environment | | **CI_COMMIT_REF_NAME** | 9.0 | all | The branch or tag name for which project is built | -| **CI_COMMIT_REF_SLUG** | 9.0 | all | `$CI_COMMIT_REF_NAME` lowercased, shortened to 63 bytes, and with everything except `0-9` and `a-z` replaced with `-`. Use in URLs and domain names. | +| **CI_COMMIT_REF_SLUG** | 9.0 | all | `$CI_COMMIT_REF_NAME` lowercased, shortened to 63 bytes, and with everything except `0-9` and `a-z` replaced with `-`. No leading / trailing `-`. Use in URLs, host names and domain names. | | **CI_COMMIT_SHA** | 9.0 | all | The commit revision for which project is built | | **CI_COMMIT_TAG** | 9.0 | 0.5 | The commit tag name. Present only when building tags. | +| **CI_CONFIG_PATH** | 9.4 | 0.5 | The path to CI config file. Defaults to `.gitlab-ci.yml` | | **CI_DEBUG_TRACE** | all | 1.7 | Whether [debug tracing](#debug-tracing) is enabled | | **CI_ENVIRONMENT_NAME** | 8.15 | all | The name of the environment for this job | | **CI_ENVIRONMENT_SLUG** | 8.15 | all | A simplified version of the environment name, suitable for inclusion in DNS, URLs, Kubernetes labels, etc. | @@ -159,7 +160,7 @@ Secret variables can be added by going to your project's Once you set them, they will be available for all subsequent pipelines. -## Protected secret variables +### Protected secret variables >**Notes:** This feature requires GitLab 9.3 or higher. @@ -425,10 +426,11 @@ export CI_REGISTRY_PASSWORD="longalfanumstring" ``` [ce-13784]: https://gitlab.com/gitlab-org/gitlab-ce/issues/13784 -[runner]: https://docs.gitlab.com/runner/ -[triggered]: ../triggers/README.md -[triggers]: ../triggers/README.md#pass-job-variables-to-a-trigger +[eep]: https://about.gitlab.com/gitlab-ee/ "Available only in GitLab Enterprise Edition Premium" +[envs]: ../environments.md [protected branches]: ../../user/project/protected_branches.md [protected tags]: ../../user/project/protected_tags.md +[runner]: https://docs.gitlab.com/runner/ [shellexecutors]: https://docs.gitlab.com/runner/executors/ -[eep]: https://about.gitlab.com/gitlab-ee/ "Available only in GitLab Enterprise Edition Premium" +[triggered]: ../triggers/README.md +[triggers]: ../triggers/README.md#pass-job-variables-to-a-trigger diff --git a/doc/ci/yaml/README.md b/doc/ci/yaml/README.md index 8a0662db6fd..724843a4d56 100644 --- a/doc/ci/yaml/README.md +++ b/doc/ci/yaml/README.md @@ -306,6 +306,53 @@ cache: untracked: true ``` +### cache:policy + +> Introduced in GitLab 9.4. + +The default behaviour of a caching job is to download the files at the start of +execution, and to re-upload them at the end. This allows any changes made by the +job to be persisted for future runs, and is known as the `pull-push` cache +policy. + +If you know the job doesn't alter the cached files, you can skip the upload step +by setting `policy: pull` in the job specification. Typically, this would be +twinned with an ordinary cache job at an earlier stage to ensure the cache +is updated from time to time: + +```yaml +stages: + - setup + - test + +prepare: + stage: setup + cache: + key: gems + paths: + - vendor/bundle + script: + - bundle install --deployment + +rspec: + stage: test + cache: + key: gems + paths: + - vendor/bundle + policy: pull + script: + - bundle exec rspec ... +``` + +This helps to speed up job execution and reduce load on the cache server, +especially when you have a large number of cache-using jobs executing in +parallel. + +Additionally, if you have a job that unconditionally recreates the cache without +reference to its previous contents, you can use `policy: push` in that job to +skip the download step. + ## Jobs `.gitlab-ci.yml` allows you to specify an unlimited number of jobs. Each job diff --git a/doc/downgrade_ee_to_ce/README.md b/doc/downgrade_ee_to_ce/README.md index fe4b6d73771..75bae324585 100644 --- a/doc/downgrade_ee_to_ce/README.md +++ b/doc/downgrade_ee_to_ce/README.md @@ -46,6 +46,19 @@ $ sudo gitlab-rails runner "Service.where(type: ['JenkinsService', 'JenkinsDepre $ bundle exec rails runner "Service.where(type: ['JenkinsService', 'JenkinsDeprecatedService']).delete_all" production ``` +### Secret variables environment scopes + +If you're using this feature and there are variables sharing the same +key, but they have different scopes in a project, then you might want to +revisit the environment scope setting for those variables. + +In CE, environment scopes are completely ignored, therefore you could +accidentally get a variable which you're not expecting for a particular +environment. Make sure that you have the right variables in this case. + +Data is completely preserved, so you could always upgrade back to EE and +restore the behavior if you leave it alone. + ## Downgrade to CE After performing the above mentioned steps, you are now ready to downgrade your diff --git a/doc/install/database_mysql.md b/doc/install/database_mysql.md index 9a171d34671..37e9b3101ca 100644 --- a/doc/install/database_mysql.md +++ b/doc/install/database_mysql.md @@ -43,7 +43,7 @@ mysql> SET GLOBAL innodb_file_per_table=1, innodb_file_format=Barracuda, innodb_ mysql> CREATE DATABASE IF NOT EXISTS `gitlabhq_production` DEFAULT CHARACTER SET `utf8` COLLATE `utf8_general_ci`; # Grant the GitLab user necessary permissions on the database -mysql> GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, CREATE TEMPORARY TABLES, DROP, INDEX, ALTER, LOCK TABLES, REFERENCES ON `gitlabhq_production`.* TO 'git'@'localhost'; +mysql> GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, CREATE TEMPORARY TABLES, DROP, INDEX, ALTER, LOCK TABLES, REFERENCES, TRIGGER ON `gitlabhq_production`.* TO 'git'@'localhost'; # Quit the database session mysql> \q diff --git a/doc/update/8.9-to-8.10.md b/doc/update/8.9-to-8.10.md index d6b2f11d49a..42132f690d8 100644 --- a/doc/update/8.9-to-8.10.md +++ b/doc/update/8.9-to-8.10.md @@ -156,7 +156,7 @@ See [smtp_settings.rb.sample] as an example. Ensure you're still up-to-date with the latest init script changes: sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab - + For Ubuntu 16.04.1 LTS: sudo systemctl daemon-reload diff --git a/doc/update/9.1-to-9.2.md b/doc/update/9.1-to-9.2.md index e7d97fde14e..225a4dcc924 100644 --- a/doc/update/9.1-to-9.2.md +++ b/doc/update/9.1-to-9.2.md @@ -70,7 +70,27 @@ curl --location https://yarnpkg.com/install.sh | bash - More information can be found on the [yarn website](https://yarnpkg.com/en/docs/install). -### 5. Get latest code +### 5. Update Go + +NOTE: GitLab 9.2 and higher only supports Go 1.8.3 and dropped support for Go +1.5.x through 1.7.x. Be sure to upgrade your installation if necessary. + +You can check which version you are running with `go version`. + +Download and install Go: + +```bash +# Remove former Go installation folder +sudo rm -rf /usr/local/go + +curl --remote-name --progress https://storage.googleapis.com/golang/go1.8.3.linux-amd64.tar.gz +echo '1862f4c3d3907e59b04a757cfda0ea7aa9ef39274af99a784f5be843c80c6772 go1.8.3.linux-amd64.tar.gz' | shasum -a256 -c - && \ + sudo tar -C /usr/local -xzf go1.8.3.linux-amd64.tar.gz +sudo ln -sf /usr/local/go/bin/{go,godoc,gofmt} /usr/local/bin/ +rm go1.8.3.linux-amd64.tar.gz +``` + +### 6. Get latest code ```bash cd /home/git/gitlab @@ -97,7 +117,7 @@ cd /home/git/gitlab sudo -u git -H git checkout 9-2-stable-ee ``` -### 6. Update gitlab-shell +### 7. Update gitlab-shell ```bash cd /home/git/gitlab-shell @@ -107,11 +127,10 @@ sudo -u git -H git checkout v$(</home/git/gitlab/GITLAB_SHELL_VERSION) sudo -u git -H bin/compile ``` -### 7. Update gitlab-workhorse +### 8. Update gitlab-workhorse -Install and compile gitlab-workhorse. This requires -[Go 1.8](https://golang.org/dl). Go (at least 1.5) should already be on your system from -GitLab 8.1 and shall be upgraded if necessary. Please note that starting in Gitlab 9.3, only Go 1.8.3 and above will be supported. GitLab-Workhorse uses [GNU Make](https://www.gnu.org/software/make/). +Install and compile gitlab-workhorse. GitLab-Workhorse uses +[GNU Make](https://www.gnu.org/software/make/). If you are not using Linux you may have to run `gmake` instead of `make` below. @@ -123,7 +142,7 @@ sudo -u git -H git checkout v$(</home/git/gitlab/GITLAB_WORKHORSE_VERSION) sudo -u git -H make ``` -### 8. Update configuration files +### 9. Update configuration files #### New configuration options for `gitlab.yml` @@ -197,7 +216,7 @@ For Ubuntu 16.04.1 LTS: sudo systemctl daemon-reload ``` -### 9. Install libs, migrations, etc. +### 10. Install libs, migrations, etc. ```bash cd /home/git/gitlab @@ -223,7 +242,7 @@ sudo -u git -H bundle exec rake cache:clear RAILS_ENV=production **MySQL installations**: Run through the `MySQL strings limits` and `Tables and data conversion to utf8mb4` [tasks](../install/database_mysql.md). -### 10. Optional: install Gitaly +### 11. Optional: install Gitaly Gitaly is still an optional component of GitLab. If you want to save time during your 9.2 upgrade **you can skip this step**. @@ -240,14 +259,14 @@ sudo -u git -H git checkout v$(</home/git/gitlab/GITALY_SERVER_VERSION) sudo -u git -H make ``` -### 11. Start application +### 12. Start application ```bash sudo service gitlab start sudo service nginx restart ``` -### 12. Check application status +### 13. Check application status Check if GitLab and its environment are configured correctly: diff --git a/doc/update/9.2-to-9.3.md b/doc/update/9.2-to-9.3.md index 8fbcc892fd5..097b996ec31 100644 --- a/doc/update/9.2-to-9.3.md +++ b/doc/update/9.2-to-9.3.md @@ -72,8 +72,8 @@ More information can be found on the [yarn website](https://yarnpkg.com/en/docs/ ### 5. Update Go -NOTE: GitLab 9.3 and higher only supports Go 1.8.3 and dropped support for Go 1.5.x through 1.7.x. Be -sure to upgrade your installation if necessary +NOTE: GitLab 9.2 and higher only supports Go 1.8.3 and dropped support for Go +1.5.x through 1.7.x. Be sure to upgrade your installation if necessary. You can check which version you are running with `go version`. @@ -129,9 +129,8 @@ sudo -u git -H bin/compile ### 8. Update gitlab-workhorse -Install and compile gitlab-workhorse. This requires -[Go 1.5](https://golang.org/dl) which should already be on your system from -GitLab 8.1. GitLab-Workhorse uses [GNU Make](https://www.gnu.org/software/make/). +Install and compile gitlab-workhorse. GitLab-Workhorse uses +[GNU Make](https://www.gnu.org/software/make/). If you are not using Linux you may have to run `gmake` instead of `make` below. @@ -157,7 +156,16 @@ sudo -u git -H git checkout v$(</home/git/gitlab/GITALY_SERVER_VERSION) sudo -u git -H make ``` -### 10. Update configuration files +### 10. Update MySQL permissions + +If you are using MySQL you need to grant the GitLab user the necessary +permissions on the database: + +```bash +mysql -u root -p -e "GRANT TRIGGER ON \`gitlabhq_production\`.* TO 'git'@'localhost';" +``` + +### 11. Update configuration files #### New configuration options for `gitlab.yml` @@ -231,7 +239,7 @@ For Ubuntu 16.04.1 LTS: sudo systemctl daemon-reload ``` -### 11. Install libs, migrations, etc. +### 12. Install libs, migrations, etc. ```bash cd /home/git/gitlab @@ -257,14 +265,14 @@ sudo -u git -H bundle exec rake cache:clear RAILS_ENV=production **MySQL installations**: Run through the `MySQL strings limits` and `Tables and data conversion to utf8mb4` [tasks](../install/database_mysql.md). -### 12. Start application +### 13. Start application ```bash sudo service gitlab start sudo service nginx restart ``` -### 13. Check application status +### 14. Check application status Check if GitLab and its environment are configured correctly: diff --git a/doc/user/project/img/issue_board_move_issue_card_list.png b/doc/user/project/img/issue_board_move_issue_card_list.png Binary files differnew file mode 100644 index 00000000000..c6b17ada40e --- /dev/null +++ b/doc/user/project/img/issue_board_move_issue_card_list.png diff --git a/doc/user/project/integrations/kubernetes.md b/doc/user/project/integrations/kubernetes.md index 73fa83d72a8..bfe2672e098 100644 --- a/doc/user/project/integrations/kubernetes.md +++ b/doc/user/project/integrations/kubernetes.md @@ -55,6 +55,7 @@ GitLab CI build environment: - `KUBE_CA_PEM_FILE` - only present if a custom CA bundle was specified. Path to a file containing PEM data. - `KUBE_CA_PEM` (deprecated)- only if a custom CA bundle was specified. Raw PEM data. +- `KUBECONFIG` - Path to a file containing kubeconfig for this deployment. CA bundle would be embedded if specified. ## Web terminals diff --git a/doc/user/project/issue_board.md b/doc/user/project/issue_board.md index ebea7062ecb..e2cc67726e0 100644 --- a/doc/user/project/issue_board.md +++ b/doc/user/project/issue_board.md @@ -1,8 +1,7 @@ -# Issue board +# Issue Board ->**Notes:** -- [Introduced][ce-5554] in GitLab 8.11. -- The Backlog column was replaced by the **Add issues** button in GitLab 8.17. +>**Note:** +[Introduced][ce-5554] in [GitLab 8.11](https://about.gitlab.com/2016/08/22/gitlab-8-11-released/#issue-board). The GitLab Issue Board is a software project management tool used to plan, organize, and visualize a workflow for a feature or product release. @@ -15,12 +14,65 @@ Other interesting links: ## Overview -The Issue Board builds on GitLab's existing issue tracking functionality and +The Issue Board builds on GitLab's existing +[issue tracking functionality](issues/index.md#issue-tracker) and leverages the power of [labels] by utilizing them as lists of the scrum board. -With the Issue Board you can have a different view of your issues while also +With the Issue Board you can have a different view of your issues while maintaining the same filtering and sorting abilities you see across the -issue tracker. +issue tracker. An Issue Board is based on its project's label structure, therefore, it +applies the same descriptive labels to indicate placement on the board, keeping +consistency throughout the entire development lifecycle. + +An Issue Board shows you what issues your team is working on, who is assigned to each, +and where in the workflow those issues are. + +You create issues, host code, perform reviews, build, test, +and deploy from one single platform. Issue Boards help you to visualize +and manage the entire process _in_ GitLab. + +With [Multiple Issue Boards](https://docs.gitlab.com/ee/user/project/issue_board.html#multiple-issue-boards), available +only in [GitLab Enterprise Edition](https://about.gitlab.com/gitlab-ee/), +you go even further, as you can not only keep yourself and your project +organized from a broader perspective with one Issue Board per project, +but also allow your team members to organize their own workflow by creating +multiple Issue Boards within the same project. + +## Use cases + +GitLab Workflow allows you to discuss proposals in issues, categorize them +with labels, and from there organize and prioritize them with Issue Boards. + +For example, let's consider this simplified development workflow: + +1. You have a repository hosting your app's codebase +and your team actively contributing to code +1. Your **backend** team starts working a new +implementation, gathers feedback and approval, and pass it over to **frontend** +1. When frontend is complete, the new feature is deployed to **staging** to be tested +1. When successful, it is deployed to **production** + +If we have the labels "**backend**", "**frontend**", "**staging**", and +"**production**", and an Issue Board with a list for each, we can: + +- Visualize the entire flow of implementations since the +beginning of the development lifecycle until deployed to production +- Prioritize the issues in a list by moving them vertically +- Move issues between lists to organize them according to the labels you've set +- Add multiple issues to lists in the board by selecting one or more existing issues + +![issue card moving](img/issue_board_move_issue_card_list.png) + +> **Notes:** +> +>- For a broader use case, please check the blog post +[GitLab Workflow, an Overview](https://about.gitlab.com/2016/10/25/gitlab-workflow-an-overview/#gitlab-workflow-use-case-scenario). +> +>- For a real use case, please check why +[Codepen decided to adopt Issue Boards](https://about.gitlab.com/2017/01/27/codepen-welcome-to-gitlab/#project-management-everything-in-one-place) +to improve their workflow with [multiple boards](https://docs.gitlab.com/ee/user/project/issue_board.html#multiple-issue-boards). + +## Issue Board terminology Below is a table of the definitions used for GitLab's Issue Board. @@ -57,7 +109,7 @@ In short, here's a list of actions you can take in an Issue Board: If you are not able to perform one or more of the things above, make sure you have the right [permissions](#permissions). -## First time using the issue board +## First time using the Issue Board The first time you navigate to your Issue Board, you will be presented with a default list (**Done**) and a welcoming message that gives @@ -98,7 +150,7 @@ list view that is removed. You can always add it back later if you need. ## Adding issues to a list You can add issues to a list by clicking the **Add issues** button that is -present in the upper right corner of the issue board. This will open up a modal +present in the upper right corner of the Issue Board. This will open up a modal window where you can see all the issues that do not belong to any list. Select one or more issues by clicking on the cards and then click **Add issues** diff --git a/doc/user/project/issues/index.md b/doc/user/project/issues/index.md index fe87e6f9495..e55e2aea023 100644 --- a/doc/user/project/issues/index.md +++ b/doc/user/project/issues/index.md @@ -1,4 +1,4 @@ -# Issues documentation +# Issues The GitLab Issue Tracker is an advanced and complete tool for tracking the evolution of a new idea or the process diff --git a/doc/user/project/pipelines/settings.md b/doc/user/project/pipelines/settings.md index a992a348c0f..3ff5a08d72c 100644 --- a/doc/user/project/pipelines/settings.md +++ b/doc/user/project/pipelines/settings.md @@ -27,6 +27,22 @@ The default value is 60 minutes. Decrease the time limit if you want to impose a hard limit on your jobs' running time or increase it otherwise. In any case, if the job surpasses the threshold, it is marked as failed. +## Custom CI config path + +> - [Introduced][ce-12509] in GitLab 9.4. + +By default we look for the `.gitlab-ci.yml` file in the project's root +directory. If you require a different location **within** the repository, +you can set a custom filepath that will be used to lookup the config file, +this filepath should be **relative** to the root. + +Here are some valid examples: + +> * .gitlab-ci.yml +> * .my-custom-file.yml +> * my/path/.gitlab-ci.yml +> * my/path/.my-custom-file.yml + ## Test coverage parsing If you use test coverage in your code, GitLab can capture its output in the @@ -59,8 +75,8 @@ pipelines** checkbox and save the changes. > [Introduced][ce-9362] in GitLab 9.1. -If you want to auto-cancel all pending non-HEAD pipelines on branch, when -new pipeline will be created (after your git push or manually from UI), +If you want to auto-cancel all pending non-HEAD pipelines on branch, when +new pipeline will be created (after your git push or manually from UI), check **Auto-cancel pending pipelines** checkbox and save the changes. ## Badges @@ -115,3 +131,4 @@ into your `README.md`: [var]: ../../../ci/yaml/README.md#git-strategy [coverage report]: #test-coverage-parsing [ce-9362]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9362 +[ce-12509]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/12509 diff --git a/doc/workflow/gitlab_flow.md b/doc/workflow/gitlab_flow.md index e10ccc4fc46..ea28968fbb2 100644 --- a/doc/workflow/gitlab_flow.md +++ b/doc/workflow/gitlab_flow.md @@ -300,7 +300,7 @@ If there are no merge conflicts and the feature branches are short lived the ris If there are merge conflicts you merge the master branch into the feature branch and the CI server will rerun the tests. If you have long lived feature branches that last for more than a few days you should make your issues smaller. -## Working wih feature branches +## Working with feature branches ![Shell output showing git pull output](git_pull.png) diff --git a/features/dashboard/new_project.feature b/features/dashboard/new_project.feature deleted file mode 100644 index 046e2815d4e..00000000000 --- a/features/dashboard/new_project.feature +++ /dev/null @@ -1,30 +0,0 @@ -@dashboard -Feature: New Project -Background: - Given I sign in as a user - And I own project "Shop" - And I visit dashboard page - And I click "New project" link - - @javascript - Scenario: I should see New Projects page - Then I see "New Project" page - Then I see all possible import options - - @javascript - Scenario: I should see instructions on how to import from Git URL - Given I see "New Project" page - When I click on "Repo by URL" - Then I see instructions on how to import from Git URL - - @javascript - Scenario: I should see instructions on how to import from GitHub - Given I see "New Project" page - When I click on "Import project from GitHub" - Then I am redirected to the GitHub import page - - @javascript - Scenario: I should see Google Code import page - Given I see "New Project" page - When I click on "Google Code" - Then I redirected to Google Code import page diff --git a/features/project/source/browse_files.feature b/features/project/source/browse_files.feature index 472ec9544f3..59a625056d6 100644 --- a/features/project/source/browse_files.feature +++ b/features/project/source/browse_files.feature @@ -131,16 +131,6 @@ Feature: Project Source Browse Files Then I can see the new text file @javascript - Scenario: If I enter an illegal file name I see an error message - Given I click on "New file" link in repo - And I fill the new file name with an illegal name - And I edit code - And I fill the commit message - And I click on "Commit changes" - Then I am on the new file page - And I see "Path can contain only..." - - @javascript Scenario: I can create file with a directory name Given I click on "New file" link in repo And I fill the new file name with a new directory diff --git a/features/snippets/snippets.feature b/features/snippets/snippets.feature deleted file mode 100644 index 1ad02780229..00000000000 --- a/features/snippets/snippets.feature +++ /dev/null @@ -1,40 +0,0 @@ -@snippets -Feature: Snippets - Background: - Given I sign in as a user - And I have public "Personal snippet one" snippet - And I have private "Personal snippet private" snippet - - @javascript - Scenario: I create new snippet - Given I visit new snippet page - And I submit new snippet "Personal snippet three" - Then I should see snippet "Personal snippet three" - - Scenario: I update "Personal snippet one" - Given I visit snippet page "Personal snippet one" - And I click link "Edit" - And I submit new title "Personal snippet new title" - Then I should see "Personal snippet new title" - - Scenario: Set "Personal snippet one" public - Given I visit snippet page "Personal snippet one" - And I click link "Edit" - And I uncheck "Private" checkbox - Then I should see "Personal snippet one" public - - Scenario: I destroy "Personal snippet one" - Given I visit snippet page "Personal snippet one" - And I click link "Delete" - Then I should not see "Personal snippet one" in snippets - - Scenario: I create new internal snippet - Given I logout directly - And I sign in as an admin - Then I visit new snippet page - And I submit new internal snippet - Then I visit snippet page "Internal personal snippet one" - And I logout directly - Then I sign in as a user - Given I visit new snippet page - Then I visit snippet page "Internal personal snippet one" diff --git a/features/steps/dashboard/dashboard.rb b/features/steps/dashboard/dashboard.rb index 3c06b188f3e..0960f49aad3 100644 --- a/features/steps/dashboard/dashboard.rb +++ b/features/steps/dashboard/dashboard.rb @@ -27,7 +27,7 @@ class Spinach::Features::Dashboard < Spinach::FeatureSteps step 'I see prefilled new Merge Request page' do expect(page).to have_selector('.merge-request-form') - expect(current_path).to eq namespace_project_new_merge_request_path(@project.namespace, @project) + expect(current_path).to eq project_new_merge_request_path(@project) expect(find("#merge_request_target_project_id").value).to eq @project.id.to_s expect(find("input#merge_request_source_branch").value).to eq "fix" expect(find("input#merge_request_target_branch").value).to eq "master" diff --git a/features/steps/dashboard/new_project.rb b/features/steps/dashboard/new_project.rb deleted file mode 100644 index 530fd6f7bdb..00000000000 --- a/features/steps/dashboard/new_project.rb +++ /dev/null @@ -1,59 +0,0 @@ -class Spinach::Features::NewProject < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedProject - - step 'I click "New project" link' do - page.within '#content-body' do - click_link "New project" - end - end - - step 'I click "New project" in top right menu' do - page.within '.header-content' do - click_link "New project" - end - end - - step 'I see "New Project" page' do - expect(page).to have_content('Project path') - expect(page).to have_content('Project name') - end - - step 'I see all possible import options' do - expect(page).to have_link('GitHub') - expect(page).to have_link('Bitbucket') - expect(page).to have_link('GitLab.com') - expect(page).to have_link('Google Code') - expect(page).to have_button('Repo by URL') - expect(page).to have_link('GitLab export') - end - - step 'I click on "Import project from GitHub"' do - first('.import_github').click - end - - step 'I am redirected to the GitHub import page' do - expect(page).to have_content('Import Projects from GitHub') - expect(current_path).to eq new_import_github_path - end - - step 'I click on "Repo by URL"' do - first('.import_git').click - end - - step 'I see instructions on how to import from Git URL' do - git_import_instructions = first('.js-toggle-content') - expect(git_import_instructions).to be_visible - expect(git_import_instructions).to have_content "Git repository URL" - end - - step 'I click on "Google Code"' do - first('.import_google_code').click - end - - step 'I redirected to Google Code import page' do - expect(page).to have_content('Import projects from Google Code') - expect(current_path).to eq new_import_google_code_path - end -end diff --git a/features/steps/dashboard/starred_projects.rb b/features/steps/dashboard/starred_projects.rb deleted file mode 100644 index c33813e550b..00000000000 --- a/features/steps/dashboard/starred_projects.rb +++ /dev/null @@ -1,15 +0,0 @@ -class Spinach::Features::DashboardStarredProjects < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedProject - - step 'I starred project "Community"' do - current_user.toggle_star(Project.find_by(name: 'Community')) - end - - step 'I should not see project "Shop"' do - page.within '.projects-list' do - expect(page).not_to have_content('Shop') - end - end -end diff --git a/features/steps/explore/projects.rb b/features/steps/explore/projects.rb index 1a55f40abb9..f1288c15084 100644 --- a/features/steps/explore/projects.rb +++ b/features/steps/explore/projects.rb @@ -66,7 +66,7 @@ class Spinach::Features::ExploreProjects < Spinach::FeatureSteps title: "New feature", project: public_project ) - visit namespace_project_issues_path(public_project.namespace, public_project) + visit project_issues_path(public_project) end step 'I should see list of issues for "Community" project' do @@ -84,7 +84,7 @@ class Spinach::Features::ExploreProjects < Spinach::FeatureSteps title: "New internal feature", project: internal_project ) - visit namespace_project_issues_path(internal_project.namespace, internal_project) + visit project_issues_path(internal_project) end step 'I should see list of issues for "Internal" project' do @@ -94,7 +94,7 @@ class Spinach::Features::ExploreProjects < Spinach::FeatureSteps end step 'I visit "Community" merge requests page' do - visit namespace_project_merge_requests_path(public_project.namespace, public_project) + visit project_merge_requests_path(public_project) end step 'project "Community" has "Bug fix" open merge request' do @@ -111,7 +111,7 @@ class Spinach::Features::ExploreProjects < Spinach::FeatureSteps end step 'I visit "Internal" merge requests page' do - visit namespace_project_merge_requests_path(internal_project.namespace, internal_project) + visit project_merge_requests_path(internal_project) end step 'project "Internal" has "Feature implemented" open merge request' do diff --git a/features/steps/group/milestones.rb b/features/steps/group/milestones.rb index 0542b06c0ab..7288dc87005 100644 --- a/features/steps/group/milestones.rb +++ b/features/steps/group/milestones.rb @@ -39,7 +39,7 @@ class Spinach::Features::GroupMilestones < Spinach::FeatureSteps expect(page).to have_content('Milestone GL-113') expect(page).to have_content('Issues 3 Open: 3 Closed: 0') issue = Milestone.find_by(name: 'GL-113').issues.first - expect(page).to have_link(issue.title, href: namespace_project_issue_path(issue.project.namespace, issue.project, issue)) + expect(page).to have_link(issue.title, href: project_issue_path(issue.project, issue)) end step 'I fill milestone name' do diff --git a/features/steps/project/archived.rb b/features/steps/project/archived.rb index b6f1d417e21..e4847180be9 100644 --- a/features/steps/project/archived.rb +++ b/features/steps/project/archived.rb @@ -15,7 +15,7 @@ class Spinach::Features::ProjectArchived < Spinach::FeatureSteps When 'I visit project "Forum" page' do project = Project.find_by(name: "Forum") - visit namespace_project_path(project.namespace, project) + visit project_path(project) end step 'I should not see "Archived"' do diff --git a/features/steps/project/badges/build.rb b/features/steps/project/badges/build.rb index 96c59322f9b..5a9094ee9d3 100644 --- a/features/steps/project/badges/build.rb +++ b/features/steps/project/badges/build.rb @@ -5,7 +5,7 @@ class Spinach::Features::ProjectBadgesBuild < Spinach::FeatureSteps include RepoHelpers step 'I display builds badge for a master branch' do - visit build_namespace_project_badges_path(@project.namespace, @project, ref: :master, format: :svg) + visit build_project_badges_path(@project, ref: :master, format: :svg) end step 'I should see a build success badge' do diff --git a/features/steps/project/commits/commits.rb b/features/steps/project/commits/commits.rb index f19fa1c7600..305fff37c41 100644 --- a/features/steps/project/commits/commits.rb +++ b/features/steps/project/commits/commits.rb @@ -33,7 +33,7 @@ class Spinach::Features::ProjectCommits < Spinach::FeatureSteps end step 'I click on commit link' do - visit namespace_project_commit_path(@project.namespace, @project, sample_commit.id) + visit project_commit_path(@project, sample_commit.id) end step 'I see commit info' do @@ -73,7 +73,7 @@ class Spinach::Features::ProjectCommits < Spinach::FeatureSteps end step 'I visit commits list page for feature branch' do - visit namespace_project_commits_path(@project.namespace, @project, 'feature', { limit: 5 }) + visit project_commits_path(@project, 'feature', { limit: 5 }) end step 'I see feature branch commits' do @@ -119,7 +119,7 @@ class Spinach::Features::ProjectCommits < Spinach::FeatureSteps step 'I should see button to the merge request' do merge_request = MergeRequest.find_by(title: 'Feature') - expect(page).to have_link "View open merge request", href: namespace_project_merge_request_path(@project.namespace, @project, merge_request) + expect(page).to have_link "View open merge request", href: project_merge_request_path(@project, merge_request) end step 'I see breadcrumb links' do @@ -135,7 +135,7 @@ class Spinach::Features::ProjectCommits < Spinach::FeatureSteps end step 'I visit a commit with an image that changed' do - visit namespace_project_commit_path(@project.namespace, @project, sample_image_commit.id) + visit project_commit_path(@project, sample_image_commit.id) end step 'The diff links to both the previous and current image' do diff --git a/features/steps/project/commits/revert.rb b/features/steps/project/commits/revert.rb index 114de129d19..ebfa7a878bb 100644 --- a/features/steps/project/commits/revert.rb +++ b/features/steps/project/commits/revert.rb @@ -6,7 +6,7 @@ class Spinach::Features::RevertCommits < Spinach::FeatureSteps include RepoHelpers step 'I click on commit link' do - visit namespace_project_commit_path(@project.namespace, @project, sample_commit.id) + visit project_commit_path(@project, sample_commit.id) end step 'I click on the revert button' do diff --git a/features/steps/project/commits/user_lookup.rb b/features/steps/project/commits/user_lookup.rb index 2d43be5a386..4599e0d032a 100644 --- a/features/steps/project/commits/user_lookup.rb +++ b/features/steps/project/commits/user_lookup.rb @@ -4,11 +4,11 @@ class Spinach::Features::ProjectCommitsUserLookup < Spinach::FeatureSteps include SharedPaths step 'I click on commit link' do - visit namespace_project_commit_path(@project.namespace, @project, sample_commit.id) + visit project_commit_path(@project, sample_commit.id) end step 'I click on another commit link' do - visit namespace_project_commit_path(@project.namespace, @project, sample_commit.parent_id) + visit project_commit_path(@project, sample_commit.parent_id) end step 'I have user with primary email' do diff --git a/features/steps/project/create.rb b/features/steps/project/create.rb index 28be9c6df5b..60fa232672e 100644 --- a/features/steps/project/create.rb +++ b/features/steps/project/create.rb @@ -7,12 +7,12 @@ class Spinach::Features::ProjectCreate < Spinach::FeatureSteps fill_in 'project_path', with: 'Empty' page.within '#content-body' do click_button "Create project" - end + end end step 'I should see project page' do expect(page).to have_content "Empty" - expect(current_path).to eq namespace_project_path(Project.last.namespace, Project.last) + expect(current_path).to eq project_path(Project.last) end step 'I should see empty project instructions' do diff --git a/features/steps/project/deploy_keys.rb b/features/steps/project/deploy_keys.rb index 8ad9d4a4741..b58d595c7c6 100644 --- a/features/steps/project/deploy_keys.rb +++ b/features/steps/project/deploy_keys.rb @@ -36,7 +36,7 @@ class Spinach::Features::ProjectDeployKeys < Spinach::FeatureSteps end step 'I should be on deploy keys page' do - expect(current_path).to eq namespace_project_settings_repository_path(@project.namespace, @project) + expect(current_path).to eq project_settings_repository_path(@project) end step 'I should see newly created deploy key' do diff --git a/features/steps/project/fork.rb b/features/steps/project/fork.rb index 35df403a85f..dd4dff7f7a9 100644 --- a/features/steps/project/fork.rb +++ b/features/steps/project/fork.rb @@ -53,7 +53,7 @@ class Spinach::Features::ProjectFork < Spinach::FeatureSteps step 'I visit the forks page of the "Shop" project' do @project = Project.where(name: 'Shop').last - visit namespace_project_forks_path(@project.namespace, @project) + visit project_forks_path(@project) end step 'I should see my fork on the list' do diff --git a/features/steps/project/forked_merge_requests.rb b/features/steps/project/forked_merge_requests.rb index 2d9d3efd9d4..c6cabace25b 100644 --- a/features/steps/project/forked_merge_requests.rb +++ b/features/steps/project/forked_merge_requests.rb @@ -25,7 +25,7 @@ class Spinach::Features::ProjectForkedMergeRequests < Spinach::FeatureSteps step 'I should see merge request "Merge Request On Forked Project"' do expect(@project.merge_requests.size).to be >= 1 @merge_request = @project.merge_requests.last - expect(current_path).to eq namespace_project_merge_request_path(@project.namespace, @project, @merge_request) + expect(current_path).to eq project_merge_request_path(@project, @merge_request) expect(@merge_request.title).to eq "Merge Request On Forked Project" expect(@merge_request.source_project).to eq @forked_project expect(@merge_request.source_branch).to eq "fix" @@ -77,7 +77,7 @@ class Spinach::Features::ProjectForkedMergeRequests < Spinach::FeatureSteps expect(page).to have_content "An Edited Forked Merge Request" expect(@project.merge_requests.size).to be >= 1 @merge_request = @project.merge_requests.last - expect(current_path).to eq namespace_project_merge_request_path(@project.namespace, @project, @merge_request) + expect(current_path).to eq project_merge_request_path(@project, @merge_request) expect(@merge_request.source_project).to eq @forked_project expect(@merge_request.source_branch).to eq "fix" expect(@merge_request.target_branch).to eq "master" @@ -97,7 +97,7 @@ class Spinach::Features::ProjectForkedMergeRequests < Spinach::FeatureSteps end step 'I see the edit page prefilled for "Merge Request On Forked Project"' do - expect(current_path).to eq edit_namespace_project_merge_request_path(@project.namespace, @project, @merge_request) + expect(current_path).to eq edit_project_merge_request_path(@project, @merge_request) expect(page).to have_content "Edit merge request #{@merge_request.to_reference}" expect(find("#merge_request_title").value).to eq "Merge Request On Forked Project" end diff --git a/features/steps/project/graph.rb b/features/steps/project/graph.rb index 176d04d721c..e78e25318a6 100644 --- a/features/steps/project/graph.rb +++ b/features/steps/project/graph.rb @@ -7,19 +7,19 @@ class Spinach::Features::ProjectGraph < Spinach::FeatureSteps end When 'I visit project "Shop" graph page' do - visit namespace_project_graph_path(project.namespace, project, "master") + visit project_graph_path(project, "master") end step 'I visit project "Shop" commits graph page' do - visit commits_namespace_project_graph_path(project.namespace, project, "master") + visit commits_project_graph_path(project, "master") end step 'I visit project "Shop" languages graph page' do - visit languages_namespace_project_graph_path(project.namespace, project, "master") + visit languages_project_graph_path(project, "master") end step 'I visit project "Shop" chart page' do - visit charts_namespace_project_graph_path(project.namespace, project, "master") + visit charts_project_graph_path(project, "master") end step 'page should have languages graphs' do @@ -33,7 +33,7 @@ class Spinach::Features::ProjectGraph < Spinach::FeatureSteps end step 'I visit project "Shop" CI graph page' do - visit ci_namespace_project_graph_path(project.namespace, project, 'master') + visit ci_project_graph_path(project, 'master') end step 'page should have CI graphs' do diff --git a/features/steps/project/issues/award_emoji.rb b/features/steps/project/issues/award_emoji.rb index 2324edda975..bbd284b4633 100644 --- a/features/steps/project/issues/award_emoji.rb +++ b/features/steps/project/issues/award_emoji.rb @@ -5,7 +5,7 @@ class Spinach::Features::AwardEmoji < Spinach::FeatureSteps include Select2Helper step 'I visit "Bugfix" issue page' do - visit namespace_project_issue_path(@project.namespace, @project, @issue) + visit project_issue_path(@project, @issue) end step 'I click the thumbsup award Emoji' do diff --git a/features/steps/project/issues/issues.rb b/features/steps/project/issues/issues.rb index e4a559d8ff5..2deef9036d3 100644 --- a/features/steps/project/issues/issues.rb +++ b/features/steps/project/issues/issues.rb @@ -247,7 +247,7 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps When 'I visit empty project page' do project = Project.find_by(name: 'Empty Project') - visit namespace_project_path(project.namespace, project) + visit project_path(project) end step 'I see empty project details with ssh clone info' do @@ -259,12 +259,12 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps When "I visit project \"Community\" issues page" do project = Project.find_by(name: 'Community') - visit namespace_project_issues_path(project.namespace, project) + visit project_issues_path(project) end When "I visit empty project's issues page" do project = Project.find_by(name: 'Empty Project') - visit namespace_project_issues_path(project.namespace, project) + visit project_issues_path(project) end step 'I leave a comment with code block' do diff --git a/features/steps/project/issues/labels.rb b/features/steps/project/issues/labels.rb index 2828e41f731..dac18c537ac 100644 --- a/features/steps/project/issues/labels.rb +++ b/features/steps/project/issues/labels.rb @@ -4,7 +4,7 @@ class Spinach::Features::ProjectIssuesLabels < Spinach::FeatureSteps include SharedPaths step 'I visit \'bug\' label edit page' do - visit edit_namespace_project_label_path(project.namespace, project, bug_label) + visit edit_project_label_path(project, bug_label) end step 'I remove label \'bug\'' do diff --git a/features/steps/project/merge_requests.rb b/features/steps/project/merge_requests.rb index dceeed5aafe..810cd75591b 100644 --- a/features/steps/project/merge_requests.rb +++ b/features/steps/project/merge_requests.rb @@ -256,7 +256,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps end step 'I switch to the merge request\'s comments tab' do - visit namespace_project_merge_request_path(project.namespace, project, merge_request) + visit project_merge_request_path(project, merge_request) end step 'I click on the commit in the merge request' do diff --git a/features/steps/project/merge_requests/acceptance.rb b/features/steps/project/merge_requests/acceptance.rb index 870dc862992..3c640e3512a 100644 --- a/features/steps/project/merge_requests/acceptance.rb +++ b/features/steps/project/merge_requests/acceptance.rb @@ -1,6 +1,5 @@ class Spinach::Features::ProjectMergeRequestsAcceptance < Spinach::FeatureSteps include LoginHelpers - include GitlabRoutingHelper include WaitForRequests step 'I am on the Merge Request detail page' do diff --git a/features/steps/project/merge_requests/revert.rb b/features/steps/project/merge_requests/revert.rb index 98d990f112f..25ccf5ab180 100644 --- a/features/steps/project/merge_requests/revert.rb +++ b/features/steps/project/merge_requests/revert.rb @@ -1,6 +1,5 @@ class Spinach::Features::RevertMergeRequests < Spinach::FeatureSteps include LoginHelpers - include GitlabRoutingHelper include WaitForRequests step 'I click on the revert button' do diff --git a/features/steps/project/network_graph.rb b/features/steps/project/network_graph.rb index 370e46265c7..ba98d861e7b 100644 --- a/features/steps/project/network_graph.rb +++ b/features/steps/project/network_graph.rb @@ -12,11 +12,11 @@ class Spinach::Features::ProjectNetworkGraph < Spinach::FeatureSteps Network::Graph.stub(max_count: 10) @project = Project.find_by(name: "Shop") - visit namespace_project_network_path(@project.namespace, @project, "master") + visit project_network_path(@project, "master") end step "I visit project network page on branch 'test'" do - visit namespace_project_network_path(@project.namespace, @project, "'test'") + visit project_network_path(@project, "'test'") end step 'page should select "master" in select box' do diff --git a/features/steps/project/pages.rb b/features/steps/project/pages.rb index 4e6830f738b..275fb4fc010 100644 --- a/features/steps/project/pages.rb +++ b/features/steps/project/pages.rb @@ -15,7 +15,7 @@ class Spinach::Features::ProjectPages < Spinach::FeatureSteps end step 'I visit the Project Pages' do - visit namespace_project_pages_path(@project.namespace, @project) + visit project_pages_path(@project) end step 'I should see the usage of GitLab Pages' do @@ -75,7 +75,7 @@ class Spinach::Features::ProjectPages < Spinach::FeatureSteps end step 'I visit add a new Pages Domain' do - visit new_namespace_project_pages_domain_path(@project.namespace, @project) + visit new_project_pages_domain_path(@project) end step 'I fill the domain' do diff --git a/features/steps/project/project_group_links.rb b/features/steps/project/project_group_links.rb index 5280a38ce81..47ee31786a6 100644 --- a/features/steps/project/project_group_links.rb +++ b/features/steps/project/project_group_links.rb @@ -42,7 +42,7 @@ class Spinach::Features::ProjectGroupLinks < Spinach::FeatureSteps end step 'I visit project group links page' do - visit namespace_project_group_links_path(project.namespace, project) + visit project_group_links_path(project) end def project diff --git a/features/steps/project/redirects.rb b/features/steps/project/redirects.rb index 92936f27c20..b2ceb8dd9a8 100644 --- a/features/steps/project/redirects.rb +++ b/features/steps/project/redirects.rb @@ -13,7 +13,7 @@ class Spinach::Features::ProjectRedirects < Spinach::FeatureSteps step 'I visit project "Community" page' do project = Project.find_by(name: 'Community') - visit namespace_project_path(project.namespace, project) + visit project_path(project) end step 'I should see project "Community" home page' do @@ -25,12 +25,12 @@ class Spinach::Features::ProjectRedirects < Spinach::FeatureSteps step 'I visit project "Enterprise" page' do project = Project.find_by(name: 'Enterprise') - visit namespace_project_path(project.namespace, project) + visit project_path(project) end step 'I visit project "CommunityDoesNotExist" page' do project = Project.find_by(name: 'Community') - visit namespace_project_path(project.namespace, project) + 'DoesNotExist' + visit project_path(project) + 'DoesNotExist' end step 'I click on "Sign In"' do diff --git a/features/steps/project/services.rb b/features/steps/project/services.rb index 6bac4df16f8..906a81b29b3 100644 --- a/features/steps/project/services.rb +++ b/features/steps/project/services.rb @@ -4,7 +4,7 @@ class Spinach::Features::ProjectServices < Spinach::FeatureSteps include SharedPaths step 'I visit project "Shop" services page' do - visit namespace_project_settings_integrations_path(@project.namespace, @project) + visit project_settings_integrations_path(@project) end step 'I should see list of available services' do diff --git a/features/steps/project/snippets.rb b/features/steps/project/snippets.rb index dd49701a3d9..b0407d3f07d 100644 --- a/features/steps/project/snippets.rb +++ b/features/steps/project/snippets.rb @@ -91,7 +91,7 @@ class Spinach::Features::ProjectSnippets < Spinach::FeatureSteps end step 'I visit snippet page "Snippet one"' do - visit namespace_project_snippet_path(project.namespace, project, project_snippet) + visit project_snippet_path(project, project_snippet) end def project_snippet diff --git a/features/steps/project/source/browse_files.rb b/features/steps/project/source/browse_files.rb index 02434319a08..621cae5d80d 100644 --- a/features/steps/project/source/browse_files.rb +++ b/features/steps/project/source/browse_files.rb @@ -9,7 +9,7 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps step "I don't have write access" do @project = create(:project, :repository, name: "Other Project", path: "other-project") @project.team << [@user, :reporter] - visit namespace_project_tree_path(@project.namespace, @project, root_ref) + visit project_tree_path(@project, root_ref) end step 'I should see files from repository' do @@ -19,7 +19,7 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps end step 'I should see files from repository for "6d39438"' do - expect(current_path).to eq namespace_project_tree_path(@project.namespace, @project, "6d39438") + expect(current_path).to eq project_tree_path(@project, "6d39438") expect(page).to have_content ".gitignore" expect(page).to have_content "LICENSE" end @@ -92,10 +92,6 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps fill_in :branch_name, with: 'new_branch_name', visible: true end - step 'I fill the new file name with an illegal name' do - fill_in :file_name, with: 'Spaces Not Allowed' - end - step 'I fill the new file name with a new directory' do fill_in :file_name, with: new_file_name_with_directory end @@ -240,16 +236,16 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps end step 'I am redirected to the files URL' do - expect(current_path).to eq namespace_project_tree_path(@project.namespace, @project, 'master') + expect(current_path).to eq project_tree_path(@project, 'master') end step 'I am redirected to the ".gitignore"' do - expect(current_path).to eq(namespace_project_blob_path(@project.namespace, @project, 'master/.gitignore')) + expect(current_path).to eq(project_blob_path(@project, 'master/.gitignore')) end step 'I am redirected to the permalink URL' do expect(current_path).to( - eq(namespace_project_blob_path(@project.namespace, @project, + eq(project_blob_path(@project, @project.repository.commit.sha + '/.gitignore')) ) @@ -257,26 +253,26 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps step 'I am redirected to the new file' do expect(current_path).to eq( - namespace_project_blob_path(@project.namespace, @project, 'master/' + new_file_name)) + project_blob_path(@project, 'master/' + new_file_name)) end step 'I am redirected to the new file with directory' do expect(current_path).to eq( - namespace_project_blob_path(@project.namespace, @project, 'master/' + new_file_name_with_directory)) + project_blob_path(@project, 'master/' + new_file_name_with_directory)) end step 'I am redirected to the new merge request page' do - expect(current_path).to eq(namespace_project_new_merge_request_path(@project.namespace, @project)) + expect(current_path).to eq(project_new_merge_request_path(@project)) end step "I am redirected to the fork's new merge request page" do fork = @user.fork_of(@project) - expect(current_path).to eq(namespace_project_new_merge_request_path(fork.namespace, fork)) + expect(current_path).to eq(project_new_merge_request_path(fork)) end step 'I am redirected to the root directory' do expect(current_path).to eq( - namespace_project_tree_path(@project.namespace, @project, 'master')) + project_tree_path(@project, 'master')) end step "I don't see the permalink link" do @@ -327,11 +323,11 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps end step "I visit the 'test' tree" do - visit namespace_project_tree_path(@project.namespace, @project, "'test'") + visit project_tree_path(@project, "'test'") end step "I visit the fix tree" do - visit namespace_project_tree_path(@project.namespace, @project, "fix/.testdir") + visit project_tree_path(@project, "fix/.testdir") end step 'I see the commit data' do @@ -346,7 +342,7 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps step 'I click on "files/lfs/lfs_object.iso" file in repo' do allow_any_instance_of(Project).to receive(:lfs_enabled?).and_return(true) - visit namespace_project_tree_path(@project.namespace, @project, "lfs") + visit project_tree_path(@project, "lfs") click_link 'files' click_link "lfs" click_link "lfs_object.iso" @@ -389,7 +385,7 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps end step 'I visit the SVG file' do - visit namespace_project_blob_path(@project.namespace, @project, 'new_branch_name/logo_sample.svg') + visit project_blob_path(@project, 'new_branch_name/logo_sample.svg') end step 'I can see the new rendered SVG image' do diff --git a/features/steps/project/source/markdown_render.rb b/features/steps/project/source/markdown_render.rb index cf31e61437e..243a0f54f7f 100644 --- a/features/steps/project/source/markdown_render.rb +++ b/features/steps/project/source/markdown_render.rb @@ -14,7 +14,7 @@ class Spinach::Features::ProjectSourceMarkdownRender < Spinach::FeatureSteps end step 'I should see files from repository in markdown' do - expect(current_path).to eq namespace_project_tree_path(@project.namespace, @project, "markdown") + expect(current_path).to eq project_tree_path(@project, "markdown") expect(page).to have_content "README.md" expect(page).to have_content "CHANGELOG" end @@ -34,7 +34,7 @@ class Spinach::Features::ProjectSourceMarkdownRender < Spinach::FeatureSteps end step 'I should see correct document rendered' do - expect(current_path).to eq namespace_project_blob_path(@project.namespace, @project, "markdown/doc/api/README.md") + expect(current_path).to eq project_blob_path(@project, "markdown/doc/api/README.md") wait_for_requests expect(page).to have_content "All API requests require authentication" end @@ -44,7 +44,7 @@ class Spinach::Features::ProjectSourceMarkdownRender < Spinach::FeatureSteps end step 'I should see correct directory rendered' do - expect(current_path).to eq namespace_project_tree_path(@project.namespace, @project, "markdown/doc/raketasks") + expect(current_path).to eq project_tree_path(@project, "markdown/doc/raketasks") expect(page).to have_content "backup_restore.md" expect(page).to have_content "maintenance.md" end @@ -54,7 +54,7 @@ class Spinach::Features::ProjectSourceMarkdownRender < Spinach::FeatureSteps end step 'I should see correct doc/api directory rendered' do - expect(current_path).to eq namespace_project_tree_path(@project.namespace, @project, "markdown/doc/api") + expect(current_path).to eq project_tree_path(@project, "markdown/doc/api") expect(page).to have_content "README.md" expect(page).to have_content "users.md" end @@ -64,7 +64,7 @@ class Spinach::Features::ProjectSourceMarkdownRender < Spinach::FeatureSteps end step 'I should see correct maintenance file rendered' do - expect(current_path).to eq namespace_project_blob_path(@project.namespace, @project, "markdown/doc/raketasks/maintenance.md") + expect(current_path).to eq project_blob_path(@project, "markdown/doc/raketasks/maintenance.md") wait_for_requests expect(page).to have_content "bundle exec rake gitlab:env:info RAILS_ENV=production" end @@ -98,7 +98,7 @@ class Spinach::Features::ProjectSourceMarkdownRender < Spinach::FeatureSteps end step 'I see correct file rendered' do - expect(current_path).to eq namespace_project_blob_path(@project.namespace, @project, "markdown/doc/api/README.md") + expect(current_path).to eq project_blob_path(@project, "markdown/doc/api/README.md") wait_for_requests expect(page).to have_content "Contents" expect(page).to have_link "Users" @@ -110,7 +110,7 @@ class Spinach::Features::ProjectSourceMarkdownRender < Spinach::FeatureSteps end step 'I should see the correct document file' do - expect(current_path).to eq namespace_project_blob_path(@project.namespace, @project, "markdown/doc/api/users.md") + expect(current_path).to eq project_blob_path(@project, "markdown/doc/api/users.md") expect(page).to have_content "Get a list of users." end @@ -121,30 +121,30 @@ class Spinach::Features::ProjectSourceMarkdownRender < Spinach::FeatureSteps # Markdown branch When 'I visit markdown branch' do - visit namespace_project_tree_path(@project.namespace, @project, "markdown") + visit project_tree_path(@project, "markdown") wait_for_requests end When 'I visit markdown branch "README.md" blob' do - visit namespace_project_blob_path(@project.namespace, @project, "markdown/README.md") + visit project_blob_path(@project, "markdown/README.md") end When 'I visit markdown branch "d" tree' do - visit namespace_project_tree_path(@project.namespace, @project, "markdown/d") + visit project_tree_path(@project, "markdown/d") end When 'I visit markdown branch "d/README.md" blob' do - visit namespace_project_blob_path(@project.namespace, @project, "markdown/d/README.md") + visit project_blob_path(@project, "markdown/d/README.md") end step 'I should see files from repository in markdown branch' do - expect(current_path).to eq namespace_project_tree_path(@project.namespace, @project, "markdown") + expect(current_path).to eq project_tree_path(@project, "markdown") expect(page).to have_content "README.md" expect(page).to have_content "CHANGELOG" end step 'I see correct file rendered in markdown branch' do - expect(current_path).to eq namespace_project_blob_path(@project.namespace, @project, "markdown/doc/api/README.md") + expect(current_path).to eq project_blob_path(@project, "markdown/doc/api/README.md") wait_for_requests expect(page).to have_content "Contents" expect(page).to have_link "Users" @@ -152,19 +152,19 @@ class Spinach::Features::ProjectSourceMarkdownRender < Spinach::FeatureSteps end step 'I should see correct document rendered for markdown branch' do - expect(current_path).to eq namespace_project_blob_path(@project.namespace, @project, "markdown/doc/api/README.md") + expect(current_path).to eq project_blob_path(@project, "markdown/doc/api/README.md") wait_for_requests expect(page).to have_content "All API requests require authentication" end step 'I should see correct directory rendered for markdown branch' do - expect(current_path).to eq namespace_project_tree_path(@project.namespace, @project, "markdown/doc/raketasks") + expect(current_path).to eq project_tree_path(@project, "markdown/doc/raketasks") expect(page).to have_content "backup_restore.md" expect(page).to have_content "maintenance.md" end step 'I should see the users document file in markdown branch' do - expect(current_path).to eq namespace_project_blob_path(@project.namespace, @project, "markdown/doc/api/users.md") + expect(current_path).to eq project_blob_path(@project, "markdown/doc/api/users.md") expect(page).to have_content "Get a list of users." end @@ -172,54 +172,54 @@ class Spinach::Features::ProjectSourceMarkdownRender < Spinach::FeatureSteps step 'The link with text "empty" should have url "tree/markdown"' do wait_for_requests - find('a', text: /^empty$/)['href'] == current_host + namespace_project_tree_path(@project.namespace, @project, "markdown") + find('a', text: /^empty$/)['href'] == current_host + project_tree_path(@project, "markdown") end step 'The link with text "empty" should have url "blob/markdown/README.md"' do - find('a', text: /^empty$/)['href'] == current_host + namespace_project_blob_path(@project.namespace, @project, "markdown/README.md") + find('a', text: /^empty$/)['href'] == current_host + project_blob_path(@project, "markdown/README.md") end step 'The link with text "empty" should have url "tree/markdown/d"' do - find('a', text: /^empty$/)['href'] == current_host + namespace_project_tree_path(@project.namespace, @project, "markdown/d") + find('a', text: /^empty$/)['href'] == current_host + project_tree_path(@project, "markdown/d") end step 'The link with text "empty" should have '\ 'url "blob/markdown/d/README.md"' do - find('a', text: /^empty$/)['href'] == current_host + namespace_project_blob_path(@project.namespace, @project, "markdown/d/README.md") + find('a', text: /^empty$/)['href'] == current_host + project_blob_path(@project, "markdown/d/README.md") end step 'The link with text "ID" should have url "tree/markdownID"' do - find('a', text: /^#id$/)['href'] == current_host + namespace_project_tree_path(@project.namespace, @project, "markdown") + '#id' + find('a', text: /^#id$/)['href'] == current_host + project_tree_path(@project, "markdown") + '#id' end step 'The link with text "/ID" should have url "tree/markdownID"' do - find('a', text: /^\/#id$/)['href'] == current_host + namespace_project_tree_path(@project.namespace, @project, "markdown") + '#id' + find('a', text: /^\/#id$/)['href'] == current_host + project_tree_path(@project, "markdown") + '#id' end step 'The link with text "README.mdID" '\ 'should have url "blob/markdown/README.mdID"' do - find('a', text: /^README.md#id$/)['href'] == current_host + namespace_project_blob_path(@project.namespace, @project, "markdown/README.md") + '#id' + find('a', text: /^README.md#id$/)['href'] == current_host + project_blob_path(@project, "markdown/README.md") + '#id' end step 'The link with text "d/README.mdID" should have '\ 'url "blob/markdown/d/README.mdID"' do - find('a', text: /^d\/README.md#id$/)['href'] == current_host + namespace_project_blob_path(@project.namespace, @project, "d/markdown/README.md") + '#id' + find('a', text: /^d\/README.md#id$/)['href'] == current_host + project_blob_path(@project, "d/markdown/README.md") + '#id' end step 'The link with text "ID" should have url "blob/markdown/README.mdID"' do wait_for_requests - find('a', text: /^#id$/)['href'] == current_host + namespace_project_blob_path(@project.namespace, @project, "markdown/README.md") + '#id' + find('a', text: /^#id$/)['href'] == current_host + project_blob_path(@project, "markdown/README.md") + '#id' end step 'The link with text "/ID" should have url "blob/markdown/README.mdID"' do - find('a', text: /^\/#id$/)['href'] == current_host + namespace_project_blob_path(@project.namespace, @project, "markdown/README.md") + '#id' + find('a', text: /^\/#id$/)['href'] == current_host + project_blob_path(@project, "markdown/README.md") + '#id' end # Wiki step 'I go to wiki page' do click_link "Wiki" - expect(current_path).to eq namespace_project_wiki_path(@project.namespace, @project, "home") + expect(current_path).to eq project_wiki_path(@project, "home") end step 'I add various links to the wiki page' do @@ -231,7 +231,7 @@ class Spinach::Features::ProjectSourceMarkdownRender < Spinach::FeatureSteps end step 'Wiki page should have added links' do - expect(current_path).to eq namespace_project_wiki_path(@project.namespace, @project, "home") + expect(current_path).to eq project_wiki_path(@project, "home") expect(page).to have_content "test GitLab API doc Rake tasks" end @@ -252,7 +252,7 @@ class Spinach::Features::ProjectSourceMarkdownRender < Spinach::FeatureSteps end step 'I see new wiki page named test' do - expect(current_path).to eq namespace_project_wiki_path(@project.namespace, @project, "test") + expect(current_path).to eq project_wiki_path(@project, "test") page.within(:css, ".nav-text") do expect(page).to have_content "Test" @@ -261,8 +261,8 @@ class Spinach::Features::ProjectSourceMarkdownRender < Spinach::FeatureSteps end When 'I go back to wiki page home' do - visit namespace_project_wiki_path(@project.namespace, @project, "home") - expect(current_path).to eq namespace_project_wiki_path(@project.namespace, @project, "home") + visit project_wiki_path(@project, "home") + expect(current_path).to eq project_wiki_path(@project, "home") end step 'I click on GitLab API doc link' do @@ -270,7 +270,7 @@ class Spinach::Features::ProjectSourceMarkdownRender < Spinach::FeatureSteps end step 'I see Gitlab API document' do - expect(current_path).to eq namespace_project_wiki_path(@project.namespace, @project, "api") + expect(current_path).to eq project_wiki_path(@project, "api") page.within(:css, ".nav-text") do expect(page).to have_content "Create" @@ -283,7 +283,7 @@ class Spinach::Features::ProjectSourceMarkdownRender < Spinach::FeatureSteps end step 'I see Rake tasks directory' do - expect(current_path).to eq namespace_project_wiki_path(@project.namespace, @project, "raketasks") + expect(current_path).to eq project_wiki_path(@project, "raketasks") page.within(:css, ".nav-text") do expect(page).to have_content "Create" @@ -292,8 +292,8 @@ class Spinach::Features::ProjectSourceMarkdownRender < Spinach::FeatureSteps end step 'I go directory which contains README file' do - visit namespace_project_tree_path(@project.namespace, @project, "markdown/doc/api") - expect(current_path).to eq namespace_project_tree_path(@project.namespace, @project, "markdown/doc/api") + visit project_tree_path(@project, "markdown/doc/api") + expect(current_path).to eq project_tree_path(@project, "markdown/doc/api") end step 'I click on a relative link in README' do @@ -301,7 +301,7 @@ class Spinach::Features::ProjectSourceMarkdownRender < Spinach::FeatureSteps end step 'I should see the correct markdown' do - expect(current_path).to eq namespace_project_blob_path(@project.namespace, @project, "markdown/doc/api/users.md") + expect(current_path).to eq project_blob_path(@project, "markdown/doc/api/users.md") wait_for_requests expect(page).to have_content "List users" end diff --git a/features/steps/project/wiki.rb b/features/steps/project/wiki.rb index 517c257d892..a2f5d2e1515 100644 --- a/features/steps/project/wiki.rb +++ b/features/steps/project/wiki.rb @@ -11,7 +11,7 @@ class Spinach::Features::ProjectWiki < Spinach::FeatureSteps end step 'I should be redirected back to the Edit Home Wiki page' do - expect(current_path).to eq namespace_project_wiki_path(project.namespace, project, :home) + expect(current_path).to eq project_wiki_path(project, :home) end step 'I create the Wiki Home page' do @@ -42,7 +42,7 @@ class Spinach::Features::ProjectWiki < Spinach::FeatureSteps end step 'I browse to that Wiki page' do - visit namespace_project_wiki_path(project.namespace, project, @page) + visit project_wiki_path(project, @page) end step 'I click on the Edit button' do @@ -59,7 +59,7 @@ class Spinach::Features::ProjectWiki < Spinach::FeatureSteps end step 'I should be redirected back to that Wiki page' do - expect(current_path).to eq namespace_project_wiki_path(project.namespace, project, @page) + expect(current_path).to eq project_wiki_path(project, @page) end step 'That page has two revisions' do @@ -95,7 +95,7 @@ class Spinach::Features::ProjectWiki < Spinach::FeatureSteps end step 'I browse to wiki page with images' do - visit namespace_project_wiki_path(project.namespace, project, @wiki_page) + visit project_wiki_path(project, @wiki_page) end step 'I click on existing image link' do diff --git a/features/steps/shared/builds.rb b/features/steps/shared/builds.rb index 624f1a7858b..3b4c98ec00d 100644 --- a/features/steps/shared/builds.rb +++ b/features/steps/shared/builds.rb @@ -27,11 +27,11 @@ module SharedBuilds end step 'I visit recent build details page' do - visit namespace_project_job_path(@project.namespace, @project, @build) + visit project_job_path(@project, @build) end step 'I visit project builds page' do - visit namespace_project_jobs_path(@project.namespace, @project) + visit project_jobs_path(@project) end step 'recent build has artifacts available' do @@ -56,7 +56,7 @@ module SharedBuilds end step 'I access artifacts download page' do - visit download_namespace_project_job_artifacts_path(@project.namespace, @project, @build) + visit download_project_job_artifacts_path(@project, @build) end step 'I see details of a build' do diff --git a/features/steps/shared/issuable.rb b/features/steps/shared/issuable.rb index 3d9cedf5c2d..7c842ba88fb 100644 --- a/features/steps/shared/issuable.rb +++ b/features/steps/shared/issuable.rb @@ -51,22 +51,22 @@ module SharedIssuable step 'I visit issue page "Enterprise issue"' do issue = Issue.find_by(title: 'Enterprise issue') - visit namespace_project_issue_path(issue.project.namespace, issue.project, issue) + visit project_issue_path(issue.project, issue) end step 'I visit merge request page "Enterprise fix"' do mr = MergeRequest.find_by(title: 'Enterprise fix') - visit namespace_project_merge_request_path(mr.target_project.namespace, mr.target_project, mr) + visit project_merge_request_path(mr.target_project, mr) end step 'I visit issue page "Community issue"' do issue = Issue.find_by(title: 'Community issue') - visit namespace_project_issue_path(issue.project.namespace, issue.project, issue) + visit project_issue_path(issue.project, issue) end step 'I visit issue page "Community fix"' do mr = MergeRequest.find_by(title: 'Community fix') - visit namespace_project_merge_request_path(mr.target_project.namespace, mr.target_project, mr) + visit project_merge_request_path(mr.target_project, mr) end step 'I should not see any related merge requests' do diff --git a/features/steps/shared/paths.rb b/features/steps/shared/paths.rb index 8a5b4112ffe..830263fd038 100644 --- a/features/steps/shared/paths.rb +++ b/features/steps/shared/paths.rb @@ -201,67 +201,67 @@ module SharedPaths # ---------------------------------------- step "I visit my project's home page" do - visit namespace_project_path(@project.namespace, @project) + visit project_path(@project) end step "I visit my project's settings page" do - visit edit_namespace_project_path(@project.namespace, @project) + visit edit_project_path(@project) end step "I visit my project's files page" do - visit namespace_project_tree_path(@project.namespace, @project, root_ref) + visit project_tree_path(@project, root_ref) end step 'I visit a binary file in the repo' do - visit namespace_project_blob_path(@project.namespace, @project, + visit project_blob_path(@project, File.join(root_ref, 'files/images/logo-black.png')) end step "I visit my project's commits page" do - visit namespace_project_commits_path(@project.namespace, @project, root_ref, { limit: 5 }) + visit project_commits_path(@project, root_ref, { limit: 5 }) end step "I visit my project's commits page for a specific path" do - visit namespace_project_commits_path(@project.namespace, @project, root_ref + "/app/models/project.rb", { limit: 5 }) + visit project_commits_path(@project, root_ref + "/app/models/project.rb", { limit: 5 }) end step 'I visit my project\'s commits stats page' do - visit stats_namespace_project_repository_path(@project.namespace, @project) + visit stats_project_repository_path(@project) end step "I visit my project's graph page" do # Stub Graph max_size to speed up test (10 commits vs. 650) Network::Graph.stub(max_count: 10) - visit namespace_project_network_path(@project.namespace, @project, root_ref) + visit project_network_path(@project, root_ref) end step "I visit my project's issues page" do - visit namespace_project_issues_path(@project.namespace, @project) + visit project_issues_path(@project) end step "I visit my project's merge requests page" do - visit namespace_project_merge_requests_path(@project.namespace, @project) + visit project_merge_requests_path(@project) end step "I visit my project's members page" do - visit namespace_project_project_members_path(@project.namespace, @project) + visit project_project_members_path(@project) end step "I visit my project's wiki page" do - visit namespace_project_wiki_path(@project.namespace, @project, :home) + visit project_wiki_path(@project, :home) end step 'I visit project hooks page' do - visit namespace_project_settings_integrations_path(@project.namespace, @project) + visit project_settings_integrations_path(@project) end step 'I visit project deploy keys page' do - visit namespace_project_deploy_keys_path(@project.namespace, @project) + visit project_deploy_keys_path(@project) end step 'I visit project find file page' do - visit namespace_project_find_file_path(@project.namespace, @project, root_ref) + visit project_find_file_path(@project, root_ref) end # ---------------------------------------- @@ -269,107 +269,107 @@ module SharedPaths # ---------------------------------------- step 'I visit project "Shop" page' do - visit namespace_project_path(project.namespace, project) + visit project_path(project) end step 'I visit project "Shop" activity page' do - visit activity_namespace_project_path(project.namespace, project) + visit activity_project_path(project) end step 'I visit project "Forked Shop" merge requests page' do - visit namespace_project_merge_requests_path(@forked_project.namespace, @forked_project) + visit project_merge_requests_path(@forked_project) end step 'I visit edit project "Shop" page' do - visit edit_namespace_project_path(project.namespace, project) + visit edit_project_path(project) end step 'I visit project branches page' do - visit namespace_project_branches_path(@project.namespace, @project) + visit project_branches_path(@project) end step 'I visit project protected branches page' do - visit namespace_project_protected_branches_path(@project.namespace, @project) + visit project_protected_branches_path(@project) end step 'I visit compare refs page' do - visit namespace_project_compare_index_path(@project.namespace, @project) + visit project_compare_index_path(@project) end step 'I visit project commits page' do - visit namespace_project_commits_path(@project.namespace, @project, root_ref, { limit: 5 }) + visit project_commits_path(@project, root_ref, { limit: 5 }) end step 'I visit project commits page for stable branch' do - visit namespace_project_commits_path(@project.namespace, @project, 'stable', { limit: 5 }) + visit project_commits_path(@project, 'stable', { limit: 5 }) end step 'I visit project source page' do - visit namespace_project_tree_path(@project.namespace, @project, root_ref) + visit project_tree_path(@project, root_ref) end step 'I visit blob file from repo' do - visit namespace_project_blob_path(@project.namespace, @project, File.join(sample_commit.id, sample_blob.path)) + visit project_blob_path(@project, File.join(sample_commit.id, sample_blob.path)) end step 'I visit ".gitignore" file in repo' do - visit namespace_project_blob_path(@project.namespace, @project, File.join(root_ref, '.gitignore')) + visit project_blob_path(@project, File.join(root_ref, '.gitignore')) end step 'I am on the new file page' do - expect(current_path).to eq(namespace_project_create_blob_path(@project.namespace, @project, root_ref)) + expect(current_path).to eq(project_create_blob_path(@project, root_ref)) end step 'I am on the ".gitignore" edit file page' do expect(current_path).to eq( - namespace_project_edit_blob_path(@project.namespace, @project, File.join(root_ref, '.gitignore'))) + project_edit_blob_path(@project, File.join(root_ref, '.gitignore'))) end step 'I visit project source page for "6d39438"' do - visit namespace_project_tree_path(@project.namespace, @project, "6d39438") + visit project_tree_path(@project, "6d39438") end step 'I visit project source page for' \ ' "6d394385cf567f80a8fd85055db1ab4c5295806f"' do - visit namespace_project_tree_path(@project.namespace, @project, + visit project_tree_path(@project, '6d394385cf567f80a8fd85055db1ab4c5295806f') end step 'I visit project tags page' do - visit namespace_project_tags_path(@project.namespace, @project) + visit project_tags_path(@project) end step 'I visit project commit page' do - visit namespace_project_commit_path(@project.namespace, @project, sample_commit.id) + visit project_commit_path(@project, sample_commit.id) end step 'I visit project "Shop" issues page' do - visit namespace_project_issues_path(project.namespace, project) + visit project_issues_path(project) end step 'I visit issue page "Release 0.4"' do issue = Issue.find_by(title: "Release 0.4") - visit namespace_project_issue_path(issue.project.namespace, issue.project, issue) + visit project_issue_path(issue.project, issue) end step 'I visit project "Shop" labels page' do project = Project.find_by(name: 'Shop') - visit namespace_project_labels_path(project.namespace, project) + visit project_labels_path(project) end step 'I visit project "Forum" labels page' do project = Project.find_by(name: 'Forum') - visit namespace_project_labels_path(project.namespace, project) + visit project_labels_path(project) end step 'I visit project "Shop" new label page' do project = Project.find_by(name: 'Shop') - visit new_namespace_project_label_path(project.namespace, project) + visit new_project_label_path(project) end step 'I visit project "Forum" new label page' do project = Project.find_by(name: 'Forum') - visit new_namespace_project_label_path(project.namespace, project) + visit new_project_label_path(project) end step 'I visit merge request page "Bug NS-04"' do @@ -394,28 +394,28 @@ module SharedPaths step 'I visit merge request page "Bug CO-01"' do mr = MergeRequest.find_by(title: "Bug CO-01") - visit namespace_project_merge_request_path(mr.target_project.namespace, mr.target_project, mr) + visit project_merge_request_path(mr.target_project, mr) wait_for_requests end step 'I visit project "Shop" merge requests page' do - visit namespace_project_merge_requests_path(project.namespace, project) + visit project_merge_requests_path(project) end step 'I visit forked project "Shop" merge requests page' do - visit namespace_project_merge_requests_path(project.namespace, project) + visit project_merge_requests_path(project) end step 'I visit project "Shop" milestones page' do - visit namespace_project_milestones_path(project.namespace, project) + visit project_milestones_path(project) end step 'I visit project "Shop" team page' do - visit namespace_project_project_members_path(project.namespace, project) + visit project_project_members_path(project) end step 'I visit project wiki page' do - visit namespace_project_wiki_path(@project.namespace, @project, :home) + visit project_wiki_path(@project, :home) end # ---------------------------------------- @@ -424,22 +424,22 @@ module SharedPaths step 'I visit project "Community" page' do project = Project.find_by(name: "Community") - visit namespace_project_path(project.namespace, project) + visit project_path(project) end step 'I visit project "Community" source page' do project = Project.find_by(name: 'Community') - visit namespace_project_tree_path(project.namespace, project, root_ref) + visit project_tree_path(project, root_ref) end step 'I visit project "Internal" page' do project = Project.find_by(name: "Internal") - visit namespace_project_path(project.namespace, project) + visit project_path(project) end step 'I visit project "Enterprise" page' do project = Project.find_by(name: "Enterprise") - visit namespace_project_path(project.namespace, project) + visit project_path(project) end # ---------------------------------------- @@ -448,7 +448,7 @@ module SharedPaths step "I visit empty project page" do project = Project.find_by(name: "Empty Public Project") - visit namespace_project_path(project.namespace, project) + visit project_path(project) end step "I should not see command line instructions" do @@ -480,17 +480,13 @@ module SharedPaths # ---------------------------------------- step 'I visit project "Shop" snippets page' do - visit namespace_project_snippets_path(project.namespace, project) + visit project_snippets_path(project) end step 'I visit snippets page' do visit explore_snippets_path end - step 'I visit new snippet page' do - visit new_snippet_path - end - def root_ref @project.repository.root_ref end @@ -501,7 +497,7 @@ module SharedPaths def merge_request_path(title) mr = MergeRequest.find_by(title: title) - namespace_project_merge_request_path(mr.target_project.namespace, mr.target_project, mr) + project_merge_request_path(mr.target_project, mr) end # ---------------------------------------- diff --git a/features/steps/shared/project.rb b/features/steps/shared/project.rb index c4f1c57836f..729e2b8982c 100644 --- a/features/steps/shared/project.rb +++ b/features/steps/shared/project.rb @@ -61,12 +61,12 @@ module SharedProject step 'I visit my empty project page' do project = Project.find_by(name: 'Empty Project') - visit namespace_project_path(project.namespace, project) + visit project_path(project) end step 'I visit project "Shop" activity page' do project = Project.find_by(name: 'Shop') - visit namespace_project_path(project.namespace, project) + visit project_path(project) end step 'project "Shop" has push event' do @@ -101,7 +101,7 @@ module SharedProject end step 'I should see project settings' do - expect(current_path).to eq edit_namespace_project_path(@project.namespace, @project) + expect(current_path).to eq edit_project_path(@project) expect(page).to have_content("Project name") expect(page).to have_content("Sharing & Permissions") end diff --git a/features/steps/shared/snippet.rb b/features/steps/shared/snippet.rb deleted file mode 100644 index bb596c1620a..00000000000 --- a/features/steps/shared/snippet.rb +++ /dev/null @@ -1,63 +0,0 @@ -module SharedSnippet - include Spinach::DSL - - step 'I have public "Personal snippet one" snippet' do - create(:personal_snippet, - title: "Personal snippet one", - content: "Test content", - file_name: "snippet.rb", - visibility_level: Snippet::PUBLIC, - author: current_user) - end - - step 'I have private "Personal snippet private" snippet' do - create(:personal_snippet, - title: "Personal snippet private", - content: "Provate content", - file_name: "private_snippet.rb", - visibility_level: Snippet::PRIVATE, - author: current_user) - end - - step 'I have internal "Personal snippet internal" snippet' do - create(:personal_snippet, - title: "Personal snippet internal", - content: "Provate content", - file_name: "internal_snippet.rb", - visibility_level: Snippet::INTERNAL, - author: current_user) - end - - step 'I have a public many lined snippet' do - create(:personal_snippet, - title: 'Many lined snippet', - content: <<-END.gsub(/^\s+\|/, ''), - |line one - |line two - |line three - |line four - |line five - |line six - |line seven - |line eight - |line nine - |line ten - |line eleven - |line twelve - |line thirteen - |line fourteen - END - file_name: 'many_lined_snippet.rb', - visibility_level: Snippet::PUBLIC, - author: current_user) - end - - step 'There is public "Personal snippet one" snippet' do - create(:personal_snippet, - title: "Personal snippet one", - content: "Test content", - file_name: "snippet.rb", - visibility_level: Snippet::PUBLIC, - author: create(:user)) - end -end diff --git a/features/steps/snippets/snippets.rb b/features/steps/snippets/snippets.rb deleted file mode 100644 index a4fc77746ee..00000000000 --- a/features/steps/snippets/snippets.rb +++ /dev/null @@ -1,86 +0,0 @@ -class Spinach::Features::Snippets < Spinach::FeatureSteps - include SharedAuthentication - include SharedPaths - include SharedProject - include SharedSnippet - include WaitForRequests - - step 'I click link "Personal snippet one"' do - click_link "Personal snippet one" - end - - step 'I should not see "Personal snippet one" in snippets' do - expect(page).not_to have_content "Personal snippet one" - end - - step 'I click link "Edit"' do - page.within ".detail-page-header" do - first(:link, "Edit").click - end - end - - step 'I click link "Delete"' do - first(:link, "Delete").click - end - - step 'I submit new snippet "Personal snippet three"' do - fill_in "personal_snippet_title", with: "Personal snippet three" - fill_in "personal_snippet_file_name", with: "my_snippet.rb" - page.within('.file-editor') do - find('.ace_editor').native.send_keys 'Content of snippet three' - end - click_button "Create snippet" - wait_for_requests - end - - step 'I submit new internal snippet' do - fill_in "personal_snippet_title", with: "Internal personal snippet one" - fill_in "personal_snippet_file_name", with: "my_snippet.rb" - choose 'personal_snippet_visibility_level_10' - - page.within('.file-editor') do - find(:xpath, "//input[@id='personal_snippet_content']").set 'Content of internal snippet' - end - - click_button "Create snippet" - end - - step 'I should see snippet "Personal snippet three"' do - expect(page).to have_content "Personal snippet three" - expect(page).to have_content "Content of snippet three" - end - - step 'I submit new title "Personal snippet new title"' do - fill_in "personal_snippet_title", with: "Personal snippet new title" - click_button "Save" - end - - step 'I should see "Personal snippet new title"' do - expect(page).to have_content "Personal snippet new title" - end - - step 'I uncheck "Private" checkbox' do - choose "Internal" - click_button "Save" - end - - step 'I should see "Personal snippet one" public' do - expect(page).to have_no_xpath("//i[@class='public-snippet']") - end - - step 'I visit snippet page "Personal snippet one"' do - visit snippet_path(snippet) - end - - step 'I visit snippet page "Internal personal snippet one"' do - visit snippet_path(internal_snippet) - end - - def snippet - @snippet ||= PersonalSnippet.find_by!(title: "Personal snippet one") - end - - def internal_snippet - @snippet ||= PersonalSnippet.find_by!(title: "Internal personal snippet one") - end -end diff --git a/features/support/env.rb b/features/support/env.rb index 1690465d9b2..608d988755c 100644 --- a/features/support/env.rb +++ b/features/support/env.rb @@ -28,6 +28,7 @@ Spinach.hooks.before_run do TestEnv.disable_pre_receive include FactoryGirl::Syntax::Methods + include GitlabRoutingHelper end Spinach.hooks.after_scenario do |scenario_data, step_definitions| diff --git a/lib/api/api.rb b/lib/api/api.rb index d767af36e8e..efcf0976a81 100644 --- a/lib/api/api.rb +++ b/lib/api/api.rb @@ -2,6 +2,8 @@ module API class API < Grape::API include APIGuard + allow_access_with_scope :api + version %w(v3 v4), using: :path version 'v3', using: :path do @@ -44,7 +46,6 @@ module API mount ::API::V3::Variables end - before { allow_access_with_scope :api } before { header['X-Frame-Options'] = 'SAMEORIGIN' } before { Gitlab::I18n.locale = current_user&.preferred_language } diff --git a/lib/api/api_guard.rb b/lib/api/api_guard.rb index 9fcf04efa38..0d2d71e336a 100644 --- a/lib/api/api_guard.rb +++ b/lib/api/api_guard.rb @@ -23,6 +23,23 @@ module API install_error_responders(base) end + class_methods do + # Set the authorization scope(s) allowed for an API endpoint. + # + # A call to this method maps the given scope(s) to the current API + # endpoint class. If this method is called multiple times on the same class, + # the scopes are all aggregated. + def allow_access_with_scope(scopes, options = {}) + Array(scopes).each do |scope| + allowed_scopes << Scope.new(scope, options) + end + end + + def allowed_scopes + @scopes ||= [] + end + end + # Helper Methods for Grape Endpoint module HelperMethods # Invokes the doorkeeper guard. @@ -47,7 +64,7 @@ module API access_token = find_access_token return nil unless access_token - case AccessTokenValidationService.new(access_token).validate(scopes: scopes) + case AccessTokenValidationService.new(access_token, request: request).validate(scopes: scopes) when AccessTokenValidationService::INSUFFICIENT_SCOPE raise InsufficientScopeError.new(scopes) @@ -74,18 +91,6 @@ module API @current_user end - # Set the authorization scope(s) allowed for the current request. - # - # Note: A call to this method adds to any previous scopes in place. This is done because - # `Grape` callbacks run from the outside-in: the top-level callback (API::API) runs first, then - # the next-level callback (API::API::Users, for example) runs. All these scopes are valid for the - # given endpoint (GET `/api/users` is accessible by the `api` and `read_user` scopes), and so they - # need to be stored. - def allow_access_with_scope(*scopes) - @scopes ||= [] - @scopes.concat(scopes.map(&:to_s)) - end - private def find_user_by_authentication_token(token_string) @@ -96,7 +101,7 @@ module API access_token = PersonalAccessToken.active.find_by_token(token_string) return unless access_token - if AccessTokenValidationService.new(access_token).include_any_scope?(scopes) + if AccessTokenValidationService.new(access_token, request: request).include_any_scope?(scopes) User.find(access_token.user_id) end end diff --git a/lib/api/commits.rb b/lib/api/commits.rb index c6fc17cc391..bcb842b9211 100644 --- a/lib/api/commits.rb +++ b/lib/api/commits.rb @@ -67,7 +67,7 @@ module API result = ::Files::MultiService.new(user_project, current_user, attrs).execute if result[:status] == :success - commit_detail = user_project.repository.commits(result[:result], limit: 1).first + commit_detail = user_project.repository.commit(result[:result]) present commit_detail, with: Entities::RepoCommitDetail else render_api_error!(result[:message], 400) diff --git a/lib/api/entities.rb b/lib/api/entities.rb index cef5a0abe12..99eda3b0c4b 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -112,6 +112,7 @@ module API expose :open_issues_count, if: lambda { |project, options| project.feature_available?(:issues, options[:current_user]) && project.default_issues_tracker? } expose :runners_token, if: lambda { |_project, options| options[:user_can_admin_project] } expose :public_builds, as: :public_jobs + expose :ci_config_path expose :shared_with_groups do |project, options| SharedGroup.represent(project.project_group_links.all, options) end @@ -434,7 +435,7 @@ module API target_url = "namespace_project_#{target_type}_url" target_anchor = "note_#{todo.note_id}" if todo.note_id? - Gitlab::Application.routes.url_helpers.public_send(target_url, + Gitlab::Routing.url_helpers.public_send(target_url, todo.project.namespace, todo.project, todo.target, anchor: target_anchor) end @@ -831,7 +832,7 @@ module API end class Cache < Grape::Entity - expose :key, :untracked, :paths + expose :key, :untracked, :paths, :policy end class Credentials < Grape::Entity diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb index 2c73a6fdc4e..0f4791841d2 100644 --- a/lib/api/helpers.rb +++ b/lib/api/helpers.rb @@ -268,6 +268,7 @@ module API finder_params[:visibility_level] = Gitlab::VisibilityLevel.level_value(params[:visibility]) if params[:visibility] finder_params[:archived] = params[:archived] finder_params[:search] = params[:search] if params[:search] + finder_params[:user] = params.delete(:user) if params[:user] finder_params end @@ -313,7 +314,7 @@ module API def present_artifacts!(artifacts_file) return not_found! unless artifacts_file.exists? - + if artifacts_file.file_storage? present_file!(artifacts_file.path, artifacts_file.filename) else @@ -342,8 +343,8 @@ module API def initial_current_user return @initial_current_user if defined?(@initial_current_user) Gitlab::Auth::UniqueIpsLimiter.limit_user! do - @initial_current_user ||= find_user_by_private_token(scopes: @scopes) - @initial_current_user ||= doorkeeper_guard(scopes: @scopes) + @initial_current_user ||= find_user_by_private_token(scopes: scopes_registered_for_endpoint) + @initial_current_user ||= doorkeeper_guard(scopes: scopes_registered_for_endpoint) @initial_current_user ||= find_user_from_warden unless @initial_current_user && Gitlab::UserAccess.new(@initial_current_user).allowed? @@ -407,5 +408,22 @@ module API exception.status == 500 end + + # An array of scopes that were registered (using `allow_access_with_scope`) + # for the current endpoint class. It also returns scopes registered on + # `API::API`, since these are meant to apply to all API routes. + def scopes_registered_for_endpoint + @scopes_registered_for_endpoint ||= + begin + endpoint_classes = [options[:for].presence, ::API::API].compact + endpoint_classes.reduce([]) do |memo, endpoint| + if endpoint.respond_to?(:allowed_scopes) + memo.concat(endpoint.allowed_scopes) + else + memo + end + end + end + end end end diff --git a/lib/api/projects.rb b/lib/api/projects.rb index d0bd64b2972..27d49eae844 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -10,6 +10,7 @@ module API helpers do params :optional_params_ce do optional :description, type: String, desc: 'The description of the project' + optional :ci_config_path, type: String, desc: 'The path to CI config file. Defaults to `.gitlab-ci.yml`' optional :issues_enabled, type: Boolean, desc: 'Flag indication if the issue tracker is enabled' optional :merge_requests_enabled, type: Boolean, desc: 'Flag indication if merge requests are enabled' optional :wiki_enabled, type: Boolean, desc: 'Flag indication if the wiki is enabled' @@ -35,61 +36,78 @@ module API params :statistics_params do optional :statistics, type: Boolean, default: false, desc: 'Include project statistics' end - end - resource :projects do - helpers do - params :collection_params do - use :sort_params - use :filter_params - use :pagination - - optional :simple, type: Boolean, default: false, - desc: 'Return only the ID, URL, name, and path of each project' - end + params :collection_params do + use :sort_params + use :filter_params + use :pagination - params :sort_params do - optional :order_by, type: String, values: %w[id name path created_at updated_at last_activity_at], - default: 'created_at', desc: 'Return projects ordered by field' - optional :sort, type: String, values: %w[asc desc], default: 'desc', - desc: 'Return projects sorted in ascending and descending order' - end + optional :simple, type: Boolean, default: false, + desc: 'Return only the ID, URL, name, and path of each project' + end - params :filter_params do - optional :archived, type: Boolean, default: false, desc: 'Limit by archived status' - optional :visibility, type: String, values: Gitlab::VisibilityLevel.string_values, - desc: 'Limit by visibility' - optional :search, type: String, desc: 'Return list of projects matching the search criteria' - optional :owned, type: Boolean, default: false, desc: 'Limit by owned by authenticated user' - optional :starred, type: Boolean, default: false, desc: 'Limit by starred status' - optional :membership, type: Boolean, default: false, desc: 'Limit by projects that the current user is a member of' - optional :with_issues_enabled, type: Boolean, default: false, desc: 'Limit by enabled issues feature' - optional :with_merge_requests_enabled, type: Boolean, default: false, desc: 'Limit by enabled merge requests feature' - end + params :sort_params do + optional :order_by, type: String, values: %w[id name path created_at updated_at last_activity_at], + default: 'created_at', desc: 'Return projects ordered by field' + optional :sort, type: String, values: %w[asc desc], default: 'desc', + desc: 'Return projects sorted in ascending and descending order' + end - params :create_params do - optional :namespace_id, type: Integer, desc: 'Namespace ID for the new project. Default to the user namespace.' - optional :import_url, type: String, desc: 'URL from which the project is imported' - end + params :filter_params do + optional :archived, type: Boolean, default: false, desc: 'Limit by archived status' + optional :visibility, type: String, values: Gitlab::VisibilityLevel.string_values, + desc: 'Limit by visibility' + optional :search, type: String, desc: 'Return list of projects matching the search criteria' + optional :owned, type: Boolean, default: false, desc: 'Limit by owned by authenticated user' + optional :starred, type: Boolean, default: false, desc: 'Limit by starred status' + optional :membership, type: Boolean, default: false, desc: 'Limit by projects that the current user is a member of' + optional :with_issues_enabled, type: Boolean, default: false, desc: 'Limit by enabled issues feature' + optional :with_merge_requests_enabled, type: Boolean, default: false, desc: 'Limit by enabled merge requests feature' + end - def present_projects(options = {}) - projects = ProjectsFinder.new(current_user: current_user, params: project_finder_params).execute - projects = reorder_projects(projects) - projects = projects.with_statistics if params[:statistics] - projects = projects.with_issues_enabled if params[:with_issues_enabled] - projects = projects.with_merge_requests_enabled if params[:with_merge_requests_enabled] - - options = options.reverse_merge( - with: current_user ? Entities::ProjectWithAccess : Entities::BasicProjectDetails, - statistics: params[:statistics], - current_user: current_user - ) - options[:with] = Entities::BasicProjectDetails if params[:simple] - - present paginate(projects), options - end + params :create_params do + optional :namespace_id, type: Integer, desc: 'Namespace ID for the new project. Default to the user namespace.' + optional :import_url, type: String, desc: 'URL from which the project is imported' + end + + def present_projects(options = {}) + projects = ProjectsFinder.new(current_user: current_user, params: project_finder_params).execute + projects = reorder_projects(projects) + projects = projects.with_statistics if params[:statistics] + projects = projects.with_issues_enabled if params[:with_issues_enabled] + projects = projects.with_merge_requests_enabled if params[:with_merge_requests_enabled] + + options = options.reverse_merge( + with: current_user ? Entities::ProjectWithAccess : Entities::BasicProjectDetails, + statistics: params[:statistics], + current_user: current_user + ) + options[:with] = Entities::BasicProjectDetails if params[:simple] + + present paginate(projects), options end + end + resource :users, requirements: { user_id: %r{[^/]+} } do + desc 'Get a user projects' do + success Entities::BasicProjectDetails + end + params do + requires :user_id, type: String, desc: 'The ID or username of the user' + use :collection_params + use :statistics_params + end + get ":user_id/projects" do + user = find_user(params[:user_id]) + not_found!('User') unless user + + params[:user] = user + + present_projects + end + end + + resource :projects do desc 'Get a list of visible projects for authenticated user' do success Entities::BasicProjectDetails end diff --git a/lib/api/scope.rb b/lib/api/scope.rb new file mode 100644 index 00000000000..d5165b2e482 --- /dev/null +++ b/lib/api/scope.rb @@ -0,0 +1,23 @@ +# Encapsulate a scope used for authorization, such as `api`, or `read_user` +module API + class Scope + attr_reader :name, :if + + def initialize(name, options = {}) + @name = name.to_sym + @if = options[:if] + end + + # Are the `scopes` passed in sufficient to adequately authorize the passed + # request for the scope represented by the current instance of this class? + def sufficient?(scopes, request) + scopes.include?(self.name) && verify_if_condition(request) + end + + private + + def verify_if_condition(request) + self.if.nil? || self.if.call(request) + end + end +end diff --git a/lib/api/users.rb b/lib/api/users.rb index f9555842daf..88bca235692 100644 --- a/lib/api/users.rb +++ b/lib/api/users.rb @@ -1,13 +1,15 @@ module API class Users < Grape::API include PaginationParams + include APIGuard - before do - allow_access_with_scope :read_user if request.get? - authenticate! - end + allow_access_with_scope :read_user, if: -> (request) { request.get? } resource :users, requirements: { uid: /[0-9]*/, id: /[0-9]*/ } do + before do + authenticate_non_get! + end + helpers do def find_user(params) id = params[:user_id] || params[:id] @@ -51,15 +53,22 @@ module API use :pagination end get do - unless can?(current_user, :read_users_list) - render_api_error!("Not authorized.", 403) - end - authenticated_as_admin! if params[:external].present? || (params[:extern_uid].present? && params[:provider].present?) users = UsersFinder.new(current_user, params).execute - entity = current_user.admin? ? Entities::UserWithAdmin : Entities::UserBasic + authorized = can?(current_user, :read_users_list) + + # When `current_user` is not present, require that the `username` + # parameter is passed, to prevent an unauthenticated user from accessing + # a list of all the users on the GitLab instance. `UsersFinder` performs + # an exact match on the `username` parameter, so we are guaranteed to + # get either 0 or 1 `users` here. + authorized &&= params[:username].present? if current_user.blank? + + forbidden!("Not authorized to access /api/v4/users") unless authorized + + entity = current_user&.admin? ? Entities::UserWithAdmin : Entities::UserBasic present paginate(users), with: entity end @@ -398,6 +407,10 @@ module API end resource :user do + before do + authenticate! + end + desc 'Get the currently authenticated user' do success Entities::UserPublic end diff --git a/lib/api/v3/users.rb b/lib/api/v3/users.rb index 37020019e07..cf106f2552d 100644 --- a/lib/api/v3/users.rb +++ b/lib/api/v3/users.rb @@ -2,9 +2,11 @@ module API module V3 class Users < Grape::API include PaginationParams + include APIGuard + + allow_access_with_scope :read_user, if: -> (request) { request.get? } before do - allow_access_with_scope :read_user if request.get? authenticate! end diff --git a/lib/api/variables.rb b/lib/api/variables.rb index 10374995497..7fa528fb2d3 100644 --- a/lib/api/variables.rb +++ b/lib/api/variables.rb @@ -45,7 +45,9 @@ module API optional :protected, type: String, desc: 'Whether the variable is protected' end post ':id/variables' do - variable = user_project.variables.create(declared_params(include_missing: false)) + variable_params = declared_params(include_missing: false) + + variable = user_project.variables.create(variable_params) if variable.valid? present variable, with: Entities::Variable @@ -67,7 +69,9 @@ module API return not_found!('Variable') unless variable - if variable.update(declared_params(include_missing: false).except(:key)) + variable_params = declared_params(include_missing: false).except(:key) + + if variable.update(variable_params) present variable, with: Entities::Variable else render_validation_error!(variable) diff --git a/lib/banzai/filter/commit_range_reference_filter.rb b/lib/banzai/filter/commit_range_reference_filter.rb index eaacb9591b1..21bcb1c5ca8 100644 --- a/lib/banzai/filter/commit_range_reference_filter.rb +++ b/lib/banzai/filter/commit_range_reference_filter.rb @@ -30,7 +30,7 @@ module Banzai def url_for_object(range, project) h = Gitlab::Routing.url_helpers - h.namespace_project_compare_url(project.namespace, project, + h.project_compare_url(project, range.to_param.merge(only_path: context[:only_path])) end diff --git a/lib/banzai/filter/commit_reference_filter.rb b/lib/banzai/filter/commit_reference_filter.rb index 69c06117eda..714e0319025 100644 --- a/lib/banzai/filter/commit_reference_filter.rb +++ b/lib/banzai/filter/commit_reference_filter.rb @@ -24,7 +24,7 @@ module Banzai def url_for_object(commit, project) h = Gitlab::Routing.url_helpers - h.namespace_project_commit_url(project.namespace, project, commit, + h.project_commit_url(project, commit, only_path: context[:only_path]) end diff --git a/lib/banzai/filter/label_reference_filter.rb b/lib/banzai/filter/label_reference_filter.rb index a605dea149e..5364984c9d3 100644 --- a/lib/banzai/filter/label_reference_filter.rb +++ b/lib/banzai/filter/label_reference_filter.rb @@ -61,8 +61,7 @@ module Banzai def url_for_object(label, project) h = Gitlab::Routing.url_helpers - h.namespace_project_issues_url(project.namespace, project, label_name: label.name, - only_path: context[:only_path]) + h.project_issues_url(project, label_name: label.name, only_path: context[:only_path]) end def object_link_text(object, matches) diff --git a/lib/banzai/filter/merge_request_reference_filter.rb b/lib/banzai/filter/merge_request_reference_filter.rb index 3888acf935e..0eab865ac04 100644 --- a/lib/banzai/filter/merge_request_reference_filter.rb +++ b/lib/banzai/filter/merge_request_reference_filter.rb @@ -17,7 +17,7 @@ module Banzai def url_for_object(mr, project) h = Gitlab::Routing.url_helpers - h.namespace_project_merge_request_url(project.namespace, project, mr, + h.project_merge_request_url(project, mr, only_path: context[:only_path]) end diff --git a/lib/banzai/filter/milestone_reference_filter.rb b/lib/banzai/filter/milestone_reference_filter.rb index f12014e191f..45c033d32a8 100644 --- a/lib/banzai/filter/milestone_reference_filter.rb +++ b/lib/banzai/filter/milestone_reference_filter.rb @@ -49,7 +49,7 @@ module Banzai def url_for_object(milestone, project) h = Gitlab::Routing.url_helpers - h.namespace_project_milestone_url(project.namespace, project, milestone, + h.project_milestone_url(project, milestone, only_path: context[:only_path]) end diff --git a/lib/banzai/filter/snippet_reference_filter.rb b/lib/banzai/filter/snippet_reference_filter.rb index 212a0bbf2a0..134a192c22b 100644 --- a/lib/banzai/filter/snippet_reference_filter.rb +++ b/lib/banzai/filter/snippet_reference_filter.rb @@ -17,7 +17,7 @@ module Banzai def url_for_object(snippet, project) h = Gitlab::Routing.url_helpers - h.namespace_project_snippet_url(project.namespace, project, snippet, + h.project_snippet_url(project, snippet, only_path: context[:only_path]) end end diff --git a/lib/banzai/filter/user_reference_filter.rb b/lib/banzai/filter/user_reference_filter.rb index a798927823f..f3356d6c51e 100644 --- a/lib/banzai/filter/user_reference_filter.rb +++ b/lib/banzai/filter/user_reference_filter.rb @@ -107,7 +107,7 @@ module Banzai if author && !project.team.member?(author) link_content else - url = urls.namespace_project_url(project.namespace, project, + url = urls.project_url(project, only_path: context[:only_path]) data = data_attribute(project: project.id, author: author.try(:id)) diff --git a/lib/extracts_path.rb b/lib/extracts_path.rb index dd864eea3fa..721ed97bb6b 100644 --- a/lib/extracts_path.rb +++ b/lib/extracts_path.rb @@ -126,8 +126,7 @@ module ExtractsPath raise InvalidPathError unless @commit @hex_path = Digest::SHA1.hexdigest(@path) - @logs_path = logs_file_namespace_project_ref_path(@project.namespace, - @project, @ref, @path) + @logs_path = logs_file_project_ref_path(@project, @ref, @path) rescue RuntimeError, NoMethodError, InvalidPathError render_404 diff --git a/lib/gitlab/auth.rb b/lib/gitlab/auth.rb index 3933c3b04dd..ccb5d886bab 100644 --- a/lib/gitlab/auth.rb +++ b/lib/gitlab/auth.rb @@ -130,13 +130,13 @@ module Gitlab token = PersonalAccessTokensFinder.new(state: 'active').find_by(token: password) - if token && valid_scoped_token?(token, AVAILABLE_SCOPES.map(&:to_s)) + if token && valid_scoped_token?(token, AVAILABLE_SCOPES) Gitlab::Auth::Result.new(token.user, nil, :personal_token, abilities_for_scope(token.scopes)) end end def valid_oauth_token?(token) - token && token.accessible? && valid_scoped_token?(token, ["api"]) + token && token.accessible? && valid_scoped_token?(token, [:api]) end def valid_scoped_token?(token, scopes) diff --git a/lib/gitlab/badge/build/metadata.rb b/lib/gitlab/badge/build/metadata.rb index f87a7b7942e..2ee35a0d4c1 100644 --- a/lib/gitlab/badge/build/metadata.rb +++ b/lib/gitlab/badge/build/metadata.rb @@ -15,12 +15,11 @@ module Gitlab end def image_url - build_namespace_project_badges_url(@project.namespace, - @project, @ref, format: :svg) + build_project_badges_url(@project, @ref, format: :svg) end def link_url - namespace_project_commits_url(@project.namespace, @project, id: @ref) + project_commits_url(@project, id: @ref) end end end diff --git a/lib/gitlab/badge/coverage/metadata.rb b/lib/gitlab/badge/coverage/metadata.rb index 53588185622..e898f5d790e 100644 --- a/lib/gitlab/badge/coverage/metadata.rb +++ b/lib/gitlab/badge/coverage/metadata.rb @@ -16,13 +16,11 @@ module Gitlab end def image_url - coverage_namespace_project_badges_url(@project.namespace, - @project, @ref, - format: :svg) + coverage_project_badges_url(@project, @ref, format: :svg) end def link_url - namespace_project_commits_url(@project.namespace, @project, id: @ref) + project_commits_url(@project, @ref) end end end diff --git a/lib/gitlab/badge/metadata.rb b/lib/gitlab/badge/metadata.rb index 4a049ef758d..86c193650fb 100644 --- a/lib/gitlab/badge/metadata.rb +++ b/lib/gitlab/badge/metadata.rb @@ -4,7 +4,7 @@ module Gitlab # Abstract class for badge metadata # class Metadata - include Gitlab::Application.routes.url_helpers + include Gitlab::Routing.url_helpers include ActionView::Helpers::AssetTagHelper include ActionView::Helpers::UrlHelper diff --git a/lib/gitlab/ci/config/entry/cache.rb b/lib/gitlab/ci/config/entry/cache.rb index f074df9c7a1..d7e09acbbf3 100644 --- a/lib/gitlab/ci/config/entry/cache.rb +++ b/lib/gitlab/ci/config/entry/cache.rb @@ -7,11 +7,14 @@ module Gitlab # class Cache < Node include Configurable + include Attributable - ALLOWED_KEYS = %i[key untracked paths].freeze + ALLOWED_KEYS = %i[key untracked paths policy].freeze + DEFAULT_POLICY = 'pull-push'.freeze validations do validates :config, allowed_keys: ALLOWED_KEYS + validates :policy, inclusion: { in: %w[pull-push push pull], message: 'should be pull-push, push, or pull' }, allow_blank: true end entry :key, Entry::Key, @@ -25,8 +28,15 @@ module Gitlab helpers :key + attributes :policy + def value - super.merge(key: key_value) + result = super + + result[:key] = key_value + result[:policy] = policy || DEFAULT_POLICY + + result end end end diff --git a/lib/gitlab/ci/status/build/cancelable.rb b/lib/gitlab/ci/status/build/cancelable.rb index 439ef0ce015..8ad3e57e59d 100644 --- a/lib/gitlab/ci/status/build/cancelable.rb +++ b/lib/gitlab/ci/status/build/cancelable.rb @@ -12,9 +12,7 @@ module Gitlab end def action_path - cancel_namespace_project_job_path(subject.project.namespace, - subject.project, - subject) + cancel_project_job_path(subject.project, subject) end def action_method diff --git a/lib/gitlab/ci/status/build/common.rb b/lib/gitlab/ci/status/build/common.rb index b173c23fba4..c0c7c7f5b5d 100644 --- a/lib/gitlab/ci/status/build/common.rb +++ b/lib/gitlab/ci/status/build/common.rb @@ -8,9 +8,7 @@ module Gitlab end def details_path - namespace_project_job_path(subject.project.namespace, - subject.project, - subject) + project_job_path(subject.project, subject) end end end diff --git a/lib/gitlab/ci/status/build/play.rb b/lib/gitlab/ci/status/build/play.rb index e80f3263794..c7726543599 100644 --- a/lib/gitlab/ci/status/build/play.rb +++ b/lib/gitlab/ci/status/build/play.rb @@ -20,9 +20,7 @@ module Gitlab end def action_path - play_namespace_project_job_path(subject.project.namespace, - subject.project, - subject) + play_project_job_path(subject.project, subject) end def action_method diff --git a/lib/gitlab/ci/status/build/retryable.rb b/lib/gitlab/ci/status/build/retryable.rb index 56303e4cb17..8c8fdc56d75 100644 --- a/lib/gitlab/ci/status/build/retryable.rb +++ b/lib/gitlab/ci/status/build/retryable.rb @@ -16,9 +16,7 @@ module Gitlab end def action_path - retry_namespace_project_job_path(subject.project.namespace, - subject.project, - subject) + retry_project_job_path(subject.project, subject) end def action_method diff --git a/lib/gitlab/ci/status/build/stop.rb b/lib/gitlab/ci/status/build/stop.rb index 2778d6f3b52..d464738deaf 100644 --- a/lib/gitlab/ci/status/build/stop.rb +++ b/lib/gitlab/ci/status/build/stop.rb @@ -20,9 +20,7 @@ module Gitlab end def action_path - play_namespace_project_job_path(subject.project.namespace, - subject.project, - subject) + play_project_job_path(subject.project, subject) end def action_method diff --git a/lib/gitlab/ci/status/pipeline/common.rb b/lib/gitlab/ci/status/pipeline/common.rb index 76bfd18bf40..61bb07beb0f 100644 --- a/lib/gitlab/ci/status/pipeline/common.rb +++ b/lib/gitlab/ci/status/pipeline/common.rb @@ -8,9 +8,7 @@ module Gitlab end def details_path - namespace_project_pipeline_path(subject.project.namespace, - subject.project, - subject) + project_pipeline_path(subject.project, subject) end def has_action? diff --git a/lib/gitlab/ci/status/stage/common.rb b/lib/gitlab/ci/status/stage/common.rb index 7852f492e1d..bc99d925347 100644 --- a/lib/gitlab/ci/status/stage/common.rb +++ b/lib/gitlab/ci/status/stage/common.rb @@ -8,10 +8,7 @@ module Gitlab end def details_path - namespace_project_pipeline_path(subject.project.namespace, - subject.project, - subject.pipeline, - anchor: subject.name) + project_pipeline_path(subject.project, subject.pipeline, anchor: subject.name) end def has_action? diff --git a/lib/gitlab/conflict/file.rb b/lib/gitlab/conflict/file.rb index 75a213ef752..d2b4e6e209e 100644 --- a/lib/gitlab/conflict/file.rb +++ b/lib/gitlab/conflict/file.rb @@ -205,9 +205,7 @@ module Gitlab old_path: their_path, new_path: our_path, blob_icon: file_type_icon_class('file', our_mode, our_path), - blob_path: namespace_project_blob_path(merge_request.project.namespace, - merge_request.project, - ::File.join(merge_request.diff_refs.head_sha, our_path)) + blob_path: project_blob_path(merge_request.project, ::File.join(merge_request.diff_refs.head_sha, our_path)) } json_hash.tap do |json_hash| @@ -223,11 +221,10 @@ module Gitlab end def content_path - conflict_for_path_namespace_project_merge_request_path(merge_request.project.namespace, - merge_request.project, - merge_request, - old_path: their_path, - new_path: our_path) + conflict_for_path_project_merge_request_path(merge_request.project, + merge_request, + old_path: their_path, + new_path: our_path) end # Don't try to print merge_request or repository. diff --git a/lib/gitlab/email/message/repository_push.rb b/lib/gitlab/email/message/repository_push.rb index ea035e33eff..42fc2a4ea19 100644 --- a/lib/gitlab/email/message/repository_push.rb +++ b/lib/gitlab/email/message/repository_push.rb @@ -96,20 +96,13 @@ module Gitlab def target_url if @action == :push && commits if commits.length > 1 - namespace_project_compare_url(project_namespace, - project, - from: compare.start_commit, - to: compare.head_commit) + project_compare_url(project, from: compare.start_commit, to: compare.head_commit) else - namespace_project_commit_url(project_namespace, - project, - commits.first) + project_commit_url(project, commits.first) end else unless @action == :delete - namespace_project_tree_url(project_namespace, - project, - ref_name) + project_tree_url(project, ref_name) end end end diff --git a/lib/gitlab/git/blob.rb b/lib/gitlab/git/blob.rb index a7aceab4c14..ffe4f3ca95f 100644 --- a/lib/gitlab/git/blob.rb +++ b/lib/gitlab/git/blob.rb @@ -175,6 +175,10 @@ module Gitlab encode! @name end + def path + encode! @path + end + def truncated? size && (size > loaded_size) end diff --git a/lib/gitlab/git/index.rb b/lib/gitlab/git/index.rb index 1add037fa5f..666743006e5 100644 --- a/lib/gitlab/git/index.rb +++ b/lib/gitlab/git/index.rb @@ -110,10 +110,6 @@ module Gitlab if segment == '..' raise IndexError, 'Path cannot include directory traversal' end - - unless segment =~ Gitlab::Regex.file_name_regex - raise IndexError, "Path #{Gitlab::Regex.file_name_regex_message}" - end end pathname.to_s diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb index 23d0c8a9bdb..dd5a4d5ad55 100644 --- a/lib/gitlab/git/repository.rb +++ b/lib/gitlab/git/repository.rb @@ -554,11 +554,14 @@ module Gitlab # # => git@localhost:rack.git # def submodule_url_for(ref, path) - if submodules(ref).any? - submodule = submodules(ref)[path] - - if submodule - submodule['url'] + Gitlab::GitalyClient.migrate(:submodule_url_for) do |is_enabled| + if is_enabled + gitaly_submodule_url_for(ref, path) + else + if submodules(ref).any? + submodule = submodules(ref)[path] + submodule['url'] if submodule + end end end end @@ -915,6 +918,18 @@ module Gitlab fill_submodule_ids(commit, parser.parse) end + def gitaly_submodule_url_for(ref, path) + # We don't care about the contents so 1 byte is enough. Can't request 0 bytes, 0 means unlimited. + commit_object = gitaly_commit_client.tree_entry(ref, path, 1) + + return unless commit_object && commit_object.type == :COMMIT + + gitmodules = gitaly_commit_client.tree_entry(ref, '.gitmodules', Blob::MAX_DATA_DISPLAY_SIZE) + found_module = GitmodulesParser.new(gitmodules.data).parse[path] + + found_module && found_module['url'] + end + def alternate_object_directories Gitlab::Git::Env.all.values_at(*ALLOWED_OBJECT_DIRECTORIES_VARIABLES).compact end diff --git a/lib/gitlab/git/tree.rb b/lib/gitlab/git/tree.rb index b9afa05c819..b6d4e6cfe46 100644 --- a/lib/gitlab/git/tree.rb +++ b/lib/gitlab/git/tree.rb @@ -80,6 +80,10 @@ module Gitlab encode! @name end + def path + encode! @path + end + def dir? type == :tree end diff --git a/lib/gitlab/gitaly_client/ref.rb b/lib/gitlab/gitaly_client/ref.rb index 2d61992f595..6edc69de078 100644 --- a/lib/gitlab/gitaly_client/ref.rb +++ b/lib/gitlab/gitaly_client/ref.rb @@ -34,7 +34,7 @@ module Gitlab commit_id: commit_id, prefix: ref_prefix ) - GitalyClient.call(@storage, :ref, :find_ref_name, request).name + encode!(GitalyClient.call(@storage, :ref, :find_ref_name, request).name.dup) end def count_tag_names diff --git a/lib/gitlab/health_checks/fs_shards_check.rb b/lib/gitlab/health_checks/fs_shards_check.rb index e78b7f22e03..70da4080cae 100644 --- a/lib/gitlab/health_checks/fs_shards_check.rb +++ b/lib/gitlab/health_checks/fs_shards_check.rb @@ -52,7 +52,7 @@ module Gitlab ] end rescue RuntimeError => ex - Rails.logger("unexpected error #{ex} when checking #{ok_metric}") + Rails.logger.error("unexpected error #{ex} when checking #{ok_metric}") [metric(ok_metric, 0, **labels)] end diff --git a/lib/gitlab/i18n.rb b/lib/gitlab/i18n.rb index db7cdf4b5c7..f3d489aad0d 100644 --- a/lib/gitlab/i18n.rb +++ b/lib/gitlab/i18n.rb @@ -12,7 +12,8 @@ module Gitlab 'zh_HK' => 'ç¹é«”ä¸æ–‡(香港)', 'zh_TW' => 'ç¹é«”ä¸æ–‡(臺ç£)', 'bg' => 'българÑки', - 'eo' => 'Esperanto' + 'eo' => 'Esperanto', + 'it' => 'Italiano' }.freeze def available_locales diff --git a/lib/gitlab/kubernetes.rb b/lib/gitlab/kubernetes.rb index c56c1a4322f..cdbdfa10d0e 100644 --- a/lib/gitlab/kubernetes.rb +++ b/lib/gitlab/kubernetes.rb @@ -76,5 +76,44 @@ module Gitlab url.to_s end + + def to_kubeconfig(url:, namespace:, token:, ca_pem: nil) + config = { + apiVersion: 'v1', + clusters: [ + name: 'gitlab-deploy', + cluster: { + server: url + } + ], + contexts: [ + name: 'gitlab-deploy', + context: { + cluster: 'gitlab-deploy', + namespace: namespace, + user: 'gitlab-deploy' + } + ], + 'current-context': 'gitlab-deploy', + kind: 'Config', + users: [ + { + name: 'gitlab-deploy', + user: { token: token } + } + ] + } + + kubeconfig_embed_ca_pem(config, ca_pem) if ca_pem + + config.deep_stringify_keys + end + + private + + def kubeconfig_embed_ca_pem(config, ca_pem) + cluster = config.dig(:clusters, 0, :cluster) + cluster[:'certificate-authority-data'] = Base64.encode64(ca_pem) + end end end diff --git a/lib/gitlab/metrics/base_sampler.rb b/lib/gitlab/metrics/base_sampler.rb new file mode 100644 index 00000000000..219accfc029 --- /dev/null +++ b/lib/gitlab/metrics/base_sampler.rb @@ -0,0 +1,94 @@ +require 'logger' +module Gitlab + module Metrics + class BaseSampler + def self.initialize_instance(*args) + raise "#{name} singleton instance already initialized" if @instance + @instance = new(*args) + at_exit(&@instance.method(:stop)) + @instance + end + + def self.instance + @instance + end + + attr_reader :running + + # interval - The sampling interval in seconds. + def initialize(interval) + interval_half = interval.to_f / 2 + + @interval = interval + @interval_steps = (-interval_half..interval_half).step(0.1).to_a + + @mutex = Mutex.new + end + + def enabled? + true + end + + def start + return unless enabled? + + @mutex.synchronize do + return if running + @running = true + + @thread = Thread.new do + sleep(sleep_interval) + + while running + safe_sample + + sleep(sleep_interval) + end + end + end + end + + def stop + @mutex.synchronize do + return unless running + + @running = false + + if @thread + @thread.wakeup if @thread.alive? + @thread.join + @thread = nil + end + end + end + + def safe_sample + sample + rescue => e + Rails.logger.warn("#{self.class}: #{e}, stopping") + stop + end + + def sample + raise NotImplementedError + end + + # Returns the sleep interval with a random adjustment. + # + # The random adjustment is put in place to ensure we: + # + # 1. Don't generate samples at the exact same interval every time (thus + # potentially missing anything that happens in between samples). + # 2. Don't sample data at the same interval two times in a row. + def sleep_interval + while step = @interval_steps.sample + if step != @last_step + @last_step = step + + return @interval + @last_step + end + end + end + end + end +end diff --git a/lib/gitlab/metrics/connection_rack_middleware.rb b/lib/gitlab/metrics/connection_rack_middleware.rb new file mode 100644 index 00000000000..b3da360be8f --- /dev/null +++ b/lib/gitlab/metrics/connection_rack_middleware.rb @@ -0,0 +1,45 @@ +module Gitlab + module Metrics + class ConnectionRackMiddleware + def initialize(app) + @app = app + end + + def self.rack_request_count + @rack_request_count ||= Gitlab::Metrics.counter(:rack_request, 'Rack request count') + end + + def self.rack_response_count + @rack_response_count ||= Gitlab::Metrics.counter(:rack_response, 'Rack response count') + end + + def self.rack_uncaught_errors_count + @rack_uncaught_errors_count ||= Gitlab::Metrics.counter(:rack_uncaught_errors, 'Rack connections handling uncaught errors count') + end + + def self.rack_execution_time + @rack_execution_time ||= Gitlab::Metrics.histogram(:rack_execution_time, 'Rack connection handling execution time', + {}, [0.05, 0.1, 0.25, 0.5, 0.7, 1, 1.5, 2, 2.5, 3, 5, 7, 10]) + end + + def call(env) + method = env['REQUEST_METHOD'].downcase + started = Time.now.to_f + begin + ConnectionRackMiddleware.rack_request_count.increment(method: method) + + status, headers, body = @app.call(env) + + ConnectionRackMiddleware.rack_response_count.increment(method: method, status: status) + [status, headers, body] + rescue + ConnectionRackMiddleware.rack_uncaught_errors_count.increment + raise + ensure + elapsed = Time.now.to_f - started + ConnectionRackMiddleware.rack_execution_time.observe({}, elapsed) + end + end + end + end +end diff --git a/lib/gitlab/metrics/sampler.rb b/lib/gitlab/metrics/influx_sampler.rb index 0000450d9bb..6db1dd755b7 100644 --- a/lib/gitlab/metrics/sampler.rb +++ b/lib/gitlab/metrics/influx_sampler.rb @@ -5,14 +5,11 @@ module Gitlab # This class is used to gather statistics that can't be directly associated # with a transaction such as system memory usage, garbage collection # statistics, etc. - class Sampler + class InfluxSampler < BaseSampler # interval - The sampling interval in seconds. def initialize(interval = Metrics.settings[:sample_interval]) - interval_half = interval.to_f / 2 - - @interval = interval - @interval_steps = (-interval_half..interval_half).step(0.1).to_a - @last_step = nil + super(interval) + @last_step = nil @metrics = [] @@ -26,18 +23,6 @@ module Gitlab end end - def start - Thread.new do - Thread.current.abort_on_exception = true - - loop do - sleep(sleep_interval) - - sample - end - end - end - def sample sample_memory_usage sample_file_descriptors @@ -86,7 +71,7 @@ module Gitlab end def sample_gc - time = GC::Profiler.total_time * 1000.0 + time = GC::Profiler.total_time * 1000.0 stats = GC.stat.merge(total_time: time) # We want the difference of GC runs compared to the last sample, not the @@ -111,23 +96,6 @@ module Gitlab def sidekiq? Sidekiq.server? end - - # Returns the sleep interval with a random adjustment. - # - # The random adjustment is put in place to ensure we: - # - # 1. Don't generate samples at the exact same interval every time (thus - # potentially missing anything that happens in between samples). - # 2. Don't sample data at the same interval two times in a row. - def sleep_interval - while step = @interval_steps.sample - if step != @last_step - @last_step = step - - return @interval + @last_step - end - end - end end end end diff --git a/lib/gitlab/metrics/prometheus.rb b/lib/gitlab/metrics/prometheus.rb index 9d314a56e58..fb7bbc7cfc7 100644 --- a/lib/gitlab/metrics/prometheus.rb +++ b/lib/gitlab/metrics/prometheus.rb @@ -29,8 +29,8 @@ module Gitlab provide_metric(name) || registry.summary(name, docstring, base_labels) end - def gauge(name, docstring, base_labels = {}) - provide_metric(name) || registry.gauge(name, docstring, base_labels) + def gauge(name, docstring, base_labels = {}, multiprocess_mode = :all) + provide_metric(name) || registry.gauge(name, docstring, base_labels, multiprocess_mode) end def histogram(name, docstring, base_labels = {}, buckets = ::Prometheus::Client::Histogram::DEFAULT_BUCKETS) diff --git a/lib/gitlab/metrics/unicorn_sampler.rb b/lib/gitlab/metrics/unicorn_sampler.rb new file mode 100644 index 00000000000..f6987252039 --- /dev/null +++ b/lib/gitlab/metrics/unicorn_sampler.rb @@ -0,0 +1,48 @@ +module Gitlab + module Metrics + class UnicornSampler < BaseSampler + def initialize(interval) + super(interval) + end + + def unicorn_active_connections + @unicorn_active_connections ||= Gitlab::Metrics.gauge(:unicorn_active_connections, 'Unicorn active connections', {}, :max) + end + + def unicorn_queued_connections + @unicorn_queued_connections ||= Gitlab::Metrics.gauge(:unicorn_queued_connections, 'Unicorn queued connections', {}, :max) + end + + def enabled? + # Raindrops::Linux.tcp_listener_stats is only present on Linux + unicorn_with_listeners? && Raindrops::Linux.respond_to?(:tcp_listener_stats) + end + + def sample + Raindrops::Linux.tcp_listener_stats(tcp_listeners).each do |addr, stats| + unicorn_active_connections.set({ type: 'tcp', address: addr }, stats.active) + unicorn_queued_connections.set({ type: 'tcp', address: addr }, stats.queued) + end + + Raindrops::Linux.unix_listener_stats(unix_listeners).each do |addr, stats| + unicorn_active_connections.set({ type: 'unix', address: addr }, stats.active) + unicorn_queued_connections.set({ type: 'unix', address: addr }, stats.queued) + end + end + + private + + def tcp_listeners + @tcp_listeners ||= Unicorn.listener_names.grep(%r{\A[^/]+:\d+\z}) + end + + def unix_listeners + @unix_listeners ||= Unicorn.listener_names - tcp_listeners + end + + def unicorn_with_listeners? + defined?(Unicorn) && Unicorn.listener_names.any? + end + end + end +end diff --git a/lib/gitlab/regex.rb b/lib/gitlab/regex.rb index b706434217d..c1ee20b6977 100644 --- a/lib/gitlab/regex.rb +++ b/lib/gitlab/regex.rb @@ -19,14 +19,6 @@ module Gitlab "It must start with letter, digit, emoji or '_'." end - def file_name_regex - @file_name_regex ||= /\A[[[:alnum:]]_\-\.\@\+]*\z/.freeze - end - - def file_name_regex_message - "can contain only letters, digits, '_', '-', '@', '+' and '.'." - end - def container_registry_reference_regex Gitlab::PathRegex.git_reference_regex end @@ -38,8 +30,12 @@ module Gitlab @container_repository_regex ||= %r{\A[a-z0-9]+(?:[-._/][a-z0-9]+)*\Z} end + def environment_name_regex_chars + 'a-zA-Z0-9_/\\$\\{\\}\\. -' + end + def environment_name_regex - @environment_name_regex ||= /\A[a-zA-Z0-9_\\\/\${}. -]+\z/.freeze + @environment_name_regex ||= /\A[#{environment_name_regex_chars}]+\z/.freeze end def environment_name_regex_message diff --git a/lib/gitlab/shell.rb b/lib/gitlab/shell.rb index 22554236c38..0baea092e6a 100644 --- a/lib/gitlab/shell.rb +++ b/lib/gitlab/shell.rb @@ -2,6 +2,8 @@ require 'securerandom' module Gitlab class Shell + GITLAB_SHELL_ENV_VARS = %w(GIT_TERMINAL_PROMPT).freeze + Error = Class.new(StandardError) KeyAdder = Struct.new(:io) do @@ -67,8 +69,8 @@ module Gitlab # add_repository("/path/to/storage", "gitlab/gitlab-ci") # def add_repository(storage, name) - Gitlab::Utils.system_silent([gitlab_shell_projects_path, - 'add-project', storage, "#{name}.git"]) + gitlab_shell_fast_execute([gitlab_shell_projects_path, + 'add-project', storage, "#{name}.git"]) end # Import repository @@ -82,10 +84,9 @@ module Gitlab def import_repository(storage, name, url) # Timeout should be less than 900 ideally, to prevent the memory killer # to silently kill the process without knowing we are timing out here. - output, status = Popen.popen([gitlab_shell_projects_path, 'import-project', - storage, "#{name}.git", url, "#{Gitlab.config.gitlab_shell.git_timeout}"]) - raise Error, output unless status.zero? - true + cmd = [gitlab_shell_projects_path, 'import-project', + storage, "#{name}.git", url, "#{Gitlab.config.gitlab_shell.git_timeout}"] + gitlab_shell_fast_execute_raise_error(cmd) end # Fetch remote for repository @@ -103,9 +104,7 @@ module Gitlab args << '--force' if forced args << '--no-tags' if no_tags - output, status = Popen.popen(args) - raise Error, output unless status.zero? - true + gitlab_shell_fast_execute_raise_error(args) end # Move repository @@ -117,8 +116,8 @@ module Gitlab # mv_repository("/path/to/storage", "gitlab/gitlab-ci", "randx/gitlab-ci-new") # def mv_repository(storage, path, new_path) - Gitlab::Utils.system_silent([gitlab_shell_projects_path, 'mv-project', - storage, "#{path}.git", "#{new_path}.git"]) + gitlab_shell_fast_execute([gitlab_shell_projects_path, 'mv-project', + storage, "#{path}.git", "#{new_path}.git"]) end # Fork repository to new namespace @@ -131,9 +130,9 @@ module Gitlab # fork_repository("/path/to/forked_from/storage", "gitlab/gitlab-ci", "/path/to/forked_to/storage", "randx") # def fork_repository(forked_from_storage, path, forked_to_storage, fork_namespace) - Gitlab::Utils.system_silent([gitlab_shell_projects_path, 'fork-project', - forked_from_storage, "#{path}.git", forked_to_storage, - fork_namespace]) + gitlab_shell_fast_execute([gitlab_shell_projects_path, 'fork-project', + forked_from_storage, "#{path}.git", forked_to_storage, + fork_namespace]) end # Remove repository from file system @@ -145,8 +144,8 @@ module Gitlab # remove_repository("/path/to/storage", "gitlab/gitlab-ci") # def remove_repository(storage, name) - Gitlab::Utils.system_silent([gitlab_shell_projects_path, - 'rm-project', storage, "#{name}.git"]) + gitlab_shell_fast_execute([gitlab_shell_projects_path, + 'rm-project', storage, "#{name}.git"]) end # Add new key to gitlab-shell @@ -155,8 +154,8 @@ module Gitlab # add_key("key-42", "sha-rsa ...") # def add_key(key_id, key_content) - Gitlab::Utils.system_silent([gitlab_shell_keys_path, - 'add-key', key_id, self.class.strip_key(key_content)]) + gitlab_shell_fast_execute([gitlab_shell_keys_path, + 'add-key', key_id, self.class.strip_key(key_content)]) end # Batch-add keys to authorized_keys @@ -175,8 +174,10 @@ module Gitlab # remove_key("key-342", "sha-rsa ...") # def remove_key(key_id, key_content) - Gitlab::Utils.system_silent([gitlab_shell_keys_path, - 'rm-key', key_id, key_content]) + args = [gitlab_shell_keys_path, 'rm-key', key_id] + args << key_content if key_content + + gitlab_shell_fast_execute(args) end # Remove all ssh keys from gitlab shell @@ -185,7 +186,7 @@ module Gitlab # remove_all_keys # def remove_all_keys - Gitlab::Utils.system_silent([gitlab_shell_keys_path, 'clear']) + gitlab_shell_fast_execute([gitlab_shell_keys_path, 'clear']) end # Add empty directory for storing repositories @@ -267,5 +268,31 @@ module Gitlab def gitlab_shell_keys_path File.join(gitlab_shell_path, 'bin', 'gitlab-keys') end + + private + + def gitlab_shell_fast_execute(cmd) + output, status = gitlab_shell_fast_execute_helper(cmd) + + return true if status.zero? + + Rails.logger.error("gitlab-shell failed with error #{status}: #{output}") + false + end + + def gitlab_shell_fast_execute_raise_error(cmd) + output, status = gitlab_shell_fast_execute_helper(cmd) + + raise Error, output unless status.zero? + true + end + + def gitlab_shell_fast_execute_helper(cmd) + vars = ENV.to_h.slice(*GITLAB_SHELL_ENV_VARS) + + # Don't pass along the entire parent environment to prevent gitlab-shell + # from wasting I/O by searching through GEM_PATH + Bundler.with_original_env { Popen.popen(cmd, nil, vars) } + end end end diff --git a/lib/gitlab/sql/glob.rb b/lib/gitlab/sql/glob.rb new file mode 100644 index 00000000000..5e89e12b2b1 --- /dev/null +++ b/lib/gitlab/sql/glob.rb @@ -0,0 +1,22 @@ +module Gitlab + module SQL + module Glob + extend self + + # Convert a simple glob pattern with wildcard (*) to SQL LIKE pattern + # with SQL expression + def to_like(pattern) + <<~SQL + REPLACE(REPLACE(REPLACE(#{pattern}, + #{q('%')}, #{q('\\%')}), + #{q('_')}, #{q('\\_')}), + #{q('*')}, #{q('%')}) + SQL + end + + def q(string) + ActiveRecord::Base.connection.quote(string) + end + end + end +end diff --git a/lib/gitlab/url_builder.rb b/lib/gitlab/url_builder.rb index 23af9318d1a..073af685a09 100644 --- a/lib/gitlab/url_builder.rb +++ b/lib/gitlab/url_builder.rb @@ -23,9 +23,9 @@ module Gitlab when WikiPage wiki_page_url when ProjectSnippet - project_snippet_url(object) + project_snippet_url(object.project, object) when Snippet - personal_snippet_url(object) + snippet_url(object) else raise NotImplementedError.new("No URL builder defined for #{object.class}") end @@ -65,13 +65,13 @@ module Gitlab if snippet.is_a?(PersonalSnippet) snippet_url(snippet, anchor: dom_id(object)) else - project_snippet_url(snippet, anchor: dom_id(object)) + project_snippet_url(snippet.project, snippet, anchor: dom_id(object)) end end end def wiki_page_url - namespace_project_wiki_url(object.wiki.project.namespace, object.wiki.project, object.slug) + project_wiki_url(object.wiki.project, object.slug) end end end diff --git a/lib/tasks/gitlab/info.rake b/lib/tasks/gitlab/info.rake index e3883278886..e9fb6a008b0 100644 --- a/lib/tasks/gitlab/info.rake +++ b/lib/tasks/gitlab/info.rake @@ -42,8 +42,7 @@ namespace :gitlab do http_clone_url = project.http_url_to_repo ssh_clone_url = project.ssh_url_to_repo - omniauth_providers = Gitlab.config.omniauth.providers - omniauth_providers.map! { |provider| provider['name'] } + omniauth_providers = Gitlab.config.omniauth.providers.map { |provider| provider['name'] } puts "" puts "GitLab information".color(:yellow) diff --git a/locale/bg/gitlab.po b/locale/bg/gitlab.po index dd1430700f8..db4dc9a02da 100644 --- a/locale/bg/gitlab.po +++ b/locale/bg/gitlab.po @@ -4,17 +4,28 @@ msgid "" msgstr "" "Project-Id-Version: gitlab 1.0.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-06-15 21:59-0500\n" +"POT-Creation-Date: 2017-06-19 15:50-0500\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"PO-Revision-Date: 2017-06-20 06:26-0400\n" +"PO-Revision-Date: 2017-06-23 04:07-0400\n" "Last-Translator: Lyubomir Vasilev <lyubomirv@abv.bg>\n" "Language-Team: Bulgarian (https://translate.zanata.org/project/view/GitLab)\n" "Language: bg\n" "X-Generator: Zanata 3.9.6\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" +msgid "%d additional commit has been omitted to prevent performance issues." +msgid_plural "" +"%d additional commits have been omitted to prevent performance issues." +msgstr[0] "%d подаване беше пропуÑнато, за да не Ñе натоварва ÑиÑтемата." +msgstr[1] "%d Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñ Ð±Ñха пропуÑнати, за да не Ñе натоварва ÑиÑтемата." + +msgid "%d commit" +msgid_plural "%d commits" +msgstr[0] "%d подаване" +msgstr[1] "%d подаваниÑ" + msgid "%{commit_author_link} committed %{commit_timeago}" msgstr "%{commit_author_link} подаде %{commit_timeago}" @@ -67,9 +78,24 @@ msgstr "" "автоматичното внедрÑване, изберете Yaml шаблон за GitLab CI и подайте " "промените Ñи. %{link_to_autodeploy_doc}" +msgid "BranchSwitcherPlaceholder|Search branches" +msgstr "ТърÑете в клоновете" + +msgid "BranchSwitcherTitle|Switch branch" +msgstr "Превключване на клона" + msgid "Branches" msgstr "Клонове" +msgid "Browse Directory" +msgstr "Преглед на папката" + +msgid "Browse File" +msgstr "Преглед на файла" + +msgid "Browse Files" +msgstr "Преглед на файловете" + msgid "Browse files" msgstr "Разглеждане на файловете" @@ -177,6 +203,9 @@ msgstr "ДобавÑне на „%{file_name}“" msgid "Commits" msgstr "ПодаваниÑ" +msgid "Commits feed" +msgstr "Поток от подаваниÑ" + msgid "Commits|History" msgstr "ИÑториÑ" @@ -339,6 +368,9 @@ msgstr "Планът за Ñхема не може да бъде премахнРmsgid "Files" msgstr "Файлове" +msgid "Filter by commit message" +msgstr "Филтриране по Ñъобщение" + msgid "Find by path" msgstr "ТърÑене по път" @@ -711,10 +743,10 @@ msgstr "Изберете чаÑова зона" msgid "Select target branch" msgstr "Изберете целеви клон" -msgid "Set a password on your account to pull or push via %{protocol}" +msgid "Set a password on your account to pull or push via %{protocol}." msgstr "" "Задайте парола на профила Ñи, за да можете да изтеглÑте и изпращате промени " -"чрез %{protocol}" +"чрез %{protocol}." msgid "Set up CI" msgstr "ÐаÑтройка на ÐИ" @@ -1032,9 +1064,15 @@ msgstr "Качване на нов файл" msgid "Upload file" msgstr "Качване на файл" +msgid "UploadLink|click to upload" +msgstr "щракнете за качване" + msgid "Use your global notification setting" msgstr "Използване на глобалната Ви наÑтройка за извеÑтиÑта" +msgid "View open merge request" +msgstr "Преглед на отворената заÑвка за Ñливане" + msgid "VisibilityLevel|Internal" msgstr "Вътрешен" diff --git a/locale/en/gitlab.po b/locale/en/gitlab.po index afb8fb3176f..bda3fc09e85 100644 --- a/locale/en/gitlab.po +++ b/locale/en/gitlab.po @@ -17,9 +17,27 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n != 1;\n" "\n" +msgid "%d additional commit has been omitted to prevent performance issues." +msgid_plural "%d additional commits have been omitted to prevent performance issues." +msgstr[0] "" +msgstr[1] "" + +msgid "%d commit" +msgid_plural "%d commits" +msgstr[0] "" +msgstr[1] "" + msgid "%{commit_author_link} committed %{commit_timeago}" msgstr "" +msgid "1 pipeline" +msgid_plural "%d pipelines" +msgstr[0] "" +msgstr[1] "" + +msgid "A collection of graphs regarding Continuous Integration" +msgstr "" + msgid "About auto deploy" msgstr "" @@ -61,9 +79,24 @@ msgstr[1] "" msgid "Branch <strong>%{branch_name}</strong> was created. To set up auto deploy, choose a GitLab CI Yaml template and commit your changes. %{link_to_autodeploy_doc}" msgstr "" +msgid "BranchSwitcherPlaceholder|Search branches" +msgstr "" + +msgid "BranchSwitcherTitle|Switch branch" +msgstr "" + msgid "Branches" msgstr "" +msgid "Browse Directory" +msgstr "" + +msgid "Browse File" +msgstr "" + +msgid "Browse Files" +msgstr "" + msgid "Browse files" msgstr "" @@ -159,6 +192,9 @@ msgid_plural "Commits" msgstr[0] "" msgstr[1] "" +msgid "Commit duration in minutes for last 30 commits" +msgstr "" + msgid "Commit message" msgstr "" @@ -171,6 +207,9 @@ msgstr "" msgid "Commits" msgstr "" +msgid "Commits feed" +msgstr "" + msgid "Commits|History" msgstr "" @@ -195,6 +234,9 @@ msgstr "" msgid "Create New Directory" msgstr "" +msgid "Create a personal access token on your account to pull or push via %{protocol}." +msgstr "" + msgid "Create directory" msgstr "" @@ -213,6 +255,9 @@ msgstr "" msgid "CreateTag|Tag" msgstr "" +msgid "CreateTokenToCloneLink|create a personal access token" +msgstr "" + msgid "Cron Timezone" msgstr "" @@ -323,6 +368,9 @@ msgstr "" msgid "Files" msgstr "" +msgid "Filter by commit message" +msgstr "" + msgid "Find by path" msgstr "" @@ -370,6 +418,15 @@ msgstr "" msgid "Introducing Cycle Analytics" msgstr "" +msgid "Jobs for last month" +msgstr "" + +msgid "Jobs for last week" +msgstr "" + +msgid "Jobs for last year" +msgstr "" + msgid "LFSStatus|Disabled" msgstr "" @@ -535,6 +592,21 @@ msgstr "" msgid "Pipeline Schedules" msgstr "" +msgid "PipelineCharts|Failed:" +msgstr "" + +msgid "PipelineCharts|Overall statistics" +msgstr "" + +msgid "PipelineCharts|Success ratio:" +msgstr "" + +msgid "PipelineCharts|Successful:" +msgstr "" + +msgid "PipelineCharts|Total:" +msgstr "" + msgid "PipelineSchedules|Activated" msgstr "" @@ -565,6 +637,18 @@ msgstr "" msgid "PipelineSheduleIntervalPattern|Custom" msgstr "" +msgid "Pipelines" +msgstr "" + +msgid "Pipelines charts" +msgstr "" + +msgid "Pipeline|all" +msgstr "" + +msgid "Pipeline|success" +msgstr "" + msgid "Pipeline|with stage" msgstr "" @@ -688,7 +772,7 @@ msgstr "" msgid "Select target branch" msgstr "" -msgid "Set a password on your account to pull or push via %{protocol}" +msgid "Set a password on your account to pull or push via %{protocol}." msgstr "" msgid "Set up CI" @@ -714,10 +798,7 @@ msgstr "" msgid "StarProject|Star" msgstr "" -msgid "Start a %{new_merge_request} with these changes" -msgstr "" - -msgid "Start a <strong>new merge request</strong> with these changes" +msgid "Start a %{new_merge_request} with these changes" msgstr "" msgid "Switch branch/tag" @@ -948,9 +1029,15 @@ msgstr "" msgid "Upload file" msgstr "" +msgid "UploadLink|click to upload" +msgstr "" + msgid "Use your global notification setting" msgstr "" +msgid "View open merge request" +msgstr "" + msgid "VisibilityLevel|Internal" msgstr "" diff --git a/locale/eo/gitlab.po b/locale/eo/gitlab.po index 3ef9e19067d..0ca8dfca266 100644 --- a/locale/eo/gitlab.po +++ b/locale/eo/gitlab.po @@ -4,17 +4,28 @@ msgid "" msgstr "" "Project-Id-Version: gitlab 1.0.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-06-15 21:59-0500\n" +"POT-Creation-Date: 2017-06-19 15:50-0500\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"PO-Revision-Date: 2017-06-20 06:24-0400\n" +"PO-Revision-Date: 2017-07-05 02:56-0400\n" "Last-Translator: Lyubomir Vasilev <lyubomirv@abv.bg>\n" "Language-Team: Esperanto (https://translate.zanata.org/project/view/GitLab)\n" "Language: eo\n" "X-Generator: Zanata 3.9.6\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" +msgid "%d additional commit has been omitted to prevent performance issues." +msgid_plural "" +"%d additional commits have been omitted to prevent performance issues." +msgstr[0] "%d enmetado estis transsaltita, por ne troÅarÄi la sistemon." +msgstr[1] "%d enmetadoj estis transsaltitaj, por ne troÅarÄi la sistemon." + +msgid "%d commit" +msgid_plural "%d commits" +msgstr[0] "%d enmetado" +msgstr[1] "%d enmetadoj" + msgid "%{commit_author_link} committed %{commit_timeago}" msgstr "%{commit_author_link} enmetis %{commit_timeago}" @@ -67,9 +78,24 @@ msgstr "" "disponigadon, bonvolu elekti Yaml-Åablonon por GitLab CI kaj enmeti viajn " "ÅanÄojn. %{link_to_autodeploy_doc}" +msgid "BranchSwitcherPlaceholder|Search branches" +msgstr "Serĉu branĉon" + +msgid "BranchSwitcherTitle|Switch branch" +msgstr "Iri al branĉo" + msgid "Branches" msgstr "Branĉoj" +msgid "Browse Directory" +msgstr "Foliumi dosierujon" + +msgid "Browse File" +msgstr "Foliumi dosieron" + +msgid "Browse Files" +msgstr "Foliumi dosierojn" + msgid "Browse files" msgstr "Elekti dosierojn" @@ -177,6 +203,9 @@ msgstr "Aldoni „%{file_name}“" msgid "Commits" msgstr "Enmetadoj" +msgid "Commits feed" +msgstr "Fluo de enmetadoj" + msgid "Commits|History" msgstr "Historio" @@ -339,6 +368,9 @@ msgstr "Ne eblas forigi la ĉenstablan planon" msgid "Files" msgstr "Dosieroj" +msgid "Filter by commit message" +msgstr "Filtri per mesaÄo" + msgid "Find by path" msgstr "Trovi per dosierindiko" @@ -712,10 +744,10 @@ msgstr "Elektu horzonon" msgid "Select target branch" msgstr "Elektu celan branĉon" -msgid "Set a password on your account to pull or push via %{protocol}" +msgid "Set a password on your account to pull or push via %{protocol}." msgstr "" "Kreu pasvorton por via konto por ebligi al vi eltiri kaj alpuÅi per " -"%{protocol}" +"%{protocol}." msgid "Set up CI" msgstr "Agordi SI" @@ -1033,9 +1065,15 @@ msgstr "AlÅuti novan dosieron" msgid "Upload file" msgstr "AlÅuti dosieron" +msgid "UploadLink|click to upload" +msgstr "alklaku por alÅuti" + msgid "Use your global notification setting" msgstr "Uzi vian Äeneralan agordon pri la sciigoj" +msgid "View open merge request" +msgstr "Vidi la malfermitan peton pri kunfando" + msgid "VisibilityLevel|Internal" msgstr "Interna" diff --git a/locale/es/gitlab.po b/locale/es/gitlab.po index cc44a06cbc5..cec086b871c 100644 --- a/locale/es/gitlab.po +++ b/locale/es/gitlab.po @@ -719,8 +719,8 @@ msgstr "Selecciona una zona horaria" msgid "Select target branch" msgstr "Selecciona una rama de destino" -msgid "Set a password on your account to pull or push via %{protocol}" -msgstr "Establezca una contraseña en su cuenta para actualizar o enviar a través de %{protocol}" +msgid "Set a password on your account to pull or push via %{protocol}." +msgstr "Establezca una contraseña en su cuenta para actualizar o enviar a través de %{protocol}." msgid "Set up CI" msgstr "Configurar CI" diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 07f9efeb495..9f1caeddaa7 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -8,8 +8,8 @@ msgid "" msgstr "" "Project-Id-Version: gitlab 1.0.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-06-19 15:50-0500\n" -"PO-Revision-Date: 2017-06-19 15:50-0500\n" +"POT-Creation-Date: 2017-06-28 13:32+0200\n" +"PO-Revision-Date: 2017-06-28 13:32+0200\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" "Language: \n" @@ -18,7 +18,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" -msgid "%d additional commit have been omitted to prevent performance issues." +msgid "%d additional commit has been omitted to prevent performance issues." msgid_plural "%d additional commits have been omitted to prevent performance issues." msgstr[0] "" msgstr[1] "" @@ -31,6 +31,14 @@ msgstr[1] "" msgid "%{commit_author_link} committed %{commit_timeago}" msgstr "" +msgid "1 pipeline" +msgid_plural "%d pipelines" +msgstr[0] "" +msgstr[1] "" + +msgid "A collection of graphs regarding Continuous Integration" +msgstr "" + msgid "About auto deploy" msgstr "" @@ -185,6 +193,9 @@ msgid_plural "Commits" msgstr[0] "" msgstr[1] "" +msgid "Commit duration in minutes for last 30 commits" +msgstr "" + msgid "Commit message" msgstr "" @@ -224,6 +235,9 @@ msgstr "" msgid "Create New Directory" msgstr "" +msgid "Create a personal access token on your account to pull or push via %{protocol}." +msgstr "" + msgid "Create directory" msgstr "" @@ -242,6 +256,9 @@ msgstr "" msgid "CreateTag|Tag" msgstr "" +msgid "CreateTokenToCloneLink|create a personal access token" +msgstr "" + msgid "Cron Timezone" msgstr "" @@ -402,6 +419,15 @@ msgstr "" msgid "Introducing Cycle Analytics" msgstr "" +msgid "Jobs for last month" +msgstr "" + +msgid "Jobs for last week" +msgstr "" + +msgid "Jobs for last year" +msgstr "" + msgid "LFSStatus|Disabled" msgstr "" @@ -567,6 +593,21 @@ msgstr "" msgid "Pipeline Schedules" msgstr "" +msgid "PipelineCharts|Failed:" +msgstr "" + +msgid "PipelineCharts|Overall statistics" +msgstr "" + +msgid "PipelineCharts|Success ratio:" +msgstr "" + +msgid "PipelineCharts|Successful:" +msgstr "" + +msgid "PipelineCharts|Total:" +msgstr "" + msgid "PipelineSchedules|Activated" msgstr "" @@ -597,6 +638,18 @@ msgstr "" msgid "PipelineSheduleIntervalPattern|Custom" msgstr "" +msgid "Pipelines" +msgstr "" + +msgid "Pipelines charts" +msgstr "" + +msgid "Pipeline|all" +msgstr "" + +msgid "Pipeline|success" +msgstr "" + msgid "Pipeline|with stage" msgstr "" @@ -720,7 +773,7 @@ msgstr "" msgid "Select target branch" msgstr "" -msgid "Set a password on your account to pull or push via %{protocol}" +msgid "Set a password on your account to pull or push via %{protocol}." msgstr "" msgid "Set up CI" diff --git a/locale/it/gitlab.po b/locale/it/gitlab.po new file mode 100644 index 00000000000..db992021403 --- /dev/null +++ b/locale/it/gitlab.po @@ -0,0 +1,1185 @@ +# Huang Tao <htve@outlook.com>, 2017. #zanata +# Paolo Falomo <info@paolofalomo.it>, 2017. #zanata +msgid "" +msgstr "" +"Project-Id-Version: gitlab 1.0.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-06-19 15:50-0500\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"PO-Revision-Date: 2017-07-02 10:32-0400\n" +"Last-Translator: Paolo Falomo <info@paolofalomo.it>\n" +"Language-Team: Italian\n" +"Language: it\n" +"X-Generator: Zanata 3.9.6\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" + +msgid "%d additional commit has been omitted to prevent performance issues." +msgid_plural "" +"%d additional commits have been omitted to prevent performance issues." +msgstr[0] "" +"%d commit aggiuntivo è stato omesso per evitare degradi di prestazioni negli " +"issues." +msgstr[1] "" +"%d commit aggiuntivi sono stati omessi per evitare degradi di prestazioni " +"negli issues." + +msgid "%d commit" +msgid_plural "%d commits" +msgstr[0] "%d commit" +msgstr[1] "%d commit" + +msgid "%{commit_author_link} committed %{commit_timeago}" +msgstr "%{commit_author_link} ha committato %{commit_timeago}" + +msgid "About auto deploy" +msgstr "Riguardo il rilascio automatico" + +msgid "Active" +msgstr "Attivo" + +msgid "Activity" +msgstr "Attività " + +msgid "Add Changelog" +msgstr "Aggiungi Changelog" + +msgid "Add Contribution guide" +msgstr "Aggiungi Guida per contribuire" + +msgid "Add License" +msgstr "Aggiungi Licenza" + +msgid "Add an SSH key to your profile to pull or push via SSH." +msgstr "" +"Aggiungi una chiave SSH al tuo profilo per eseguire pull o push tramite SSH" + +msgid "Add new directory" +msgstr "Aggiungi una directory (cartella)" + +msgid "Archived project! Repository is read-only" +msgstr "Progetto archiviato! La Repository è sola-lettura" + +msgid "Are you sure you want to delete this pipeline schedule?" +msgstr "Sei sicuro di voler cancellare questa pipeline programmata?" + +msgid "Attach a file by drag & drop or %{upload_link}" +msgstr "" +"Aggiungi un file tramite trascina & rilascia ( drag & drop) o " +"%{upload_link}" + +msgid "Branch" +msgid_plural "Branches" +msgstr[0] "Branch" +msgstr[1] "Branches" + +msgid "" +"Branch <strong>%{branch_name}</strong> was created. To set up auto deploy, " +"choose a GitLab CI Yaml template and commit your changes. " +"%{link_to_autodeploy_doc}" +msgstr "" +"La branch <strong>%{branch_name}</strong> è stata creata. Per impostare un " +"rilascio automatico scegli un template CI di Gitlab e committa le tue " +"modifiche %{link_to_autodeploy_doc}" + +msgid "BranchSwitcherPlaceholder|Search branches" +msgstr "Cerca branches" + +msgid "BranchSwitcherTitle|Switch branch" +msgstr "Cambia branch" + +msgid "Branches" +msgstr "Branches" + +msgid "Browse Directory" +msgstr "Naviga direttori" + +msgid "Browse File" +msgstr "Esplora File" + +msgid "Browse Files" +msgstr "Esplora Files" + +msgid "Browse files" +msgstr "Guarda i files" + +msgid "ByAuthor|by" +msgstr "per" + +msgid "CI configuration" +msgstr "Configurazione CI (Integrazione Continua)" + +msgid "Cancel" +msgstr "Cancella" + +msgid "ChangeTypeActionLabel|Pick into branch" +msgstr "Preleva nella branch" + +msgid "ChangeTypeActionLabel|Revert in branch" +msgstr "Ripristina nella branch" + +msgid "ChangeTypeAction|Cherry-pick" +msgstr "Cherry-pick" + +msgid "ChangeTypeAction|Revert" +msgstr "Ripristina" + +msgid "Changelog" +msgstr "Changelog" + +msgid "Charts" +msgstr "Grafici" + +msgid "Cherry-pick this commit" +msgstr "Cherry-pick this commit" + +msgid "Cherry-pick this merge request" +msgstr "Cherry-pick questa richiesta di merge" + +msgid "CiStatusLabel|canceled" +msgstr "cancellato" + +msgid "CiStatusLabel|created" +msgstr "creato" + +msgid "CiStatusLabel|failed" +msgstr "fallito" + +msgid "CiStatusLabel|manual action" +msgstr "azione manuale" + +msgid "CiStatusLabel|passed" +msgstr "superata" + +msgid "CiStatusLabel|passed with warnings" +msgstr "superata con avvisi" + +msgid "CiStatusLabel|pending" +msgstr "in coda" + +msgid "CiStatusLabel|skipped" +msgstr "saltata" + +msgid "CiStatusLabel|waiting for manual action" +msgstr "in attesa di azione manuale" + +msgid "CiStatusText|blocked" +msgstr "bloccata" + +msgid "CiStatusText|canceled" +msgstr "cancellata" + +msgid "CiStatusText|created" +msgstr "creata" + +msgid "CiStatusText|failed" +msgstr "fallita" + +msgid "CiStatusText|manual" +msgstr "manuale" + +msgid "CiStatusText|passed" +msgstr "superata" + +msgid "CiStatusText|pending" +msgstr "in coda" + +msgid "CiStatusText|skipped" +msgstr "saltata" + +msgid "CiStatus|running" +msgstr "in corso" + +msgid "Commit" +msgid_plural "Commits" +msgstr[0] "Commit" +msgstr[1] "Commits" + +msgid "Commit message" +msgstr "Messaggio del commit" + +msgid "CommitBoxTitle|Commit" +msgstr "Commit" + +msgid "CommitMessage|Add %{file_name}" +msgstr "Aggiungi %{file_name}" + +msgid "Commits" +msgstr "Commits" + +msgid "Commits feed" +msgstr "Feed dei Commits" + +msgid "Commits|History" +msgstr "Cronologia" + +msgid "Committed by" +msgstr "Committato da " + +msgid "Compare" +msgstr "Confronta" + +msgid "Contribution guide" +msgstr "Guida per contribuire" + +msgid "Contributors" +msgstr "Collaboratori" + +msgid "Copy URL to clipboard" +msgstr "Copia URL negli appunti" + +msgid "Copy commit SHA to clipboard" +msgstr "Copia l'SHA del commit negli appunti" + +msgid "Create New Directory" +msgstr "Crea una nuova cartella" + +msgid "Create directory" +msgstr "Crea cartella" + +msgid "Create empty bare repository" +msgstr "Crea una repository vuota" + +msgid "Create merge request" +msgstr "Crea una richiesta di merge" + +msgid "Create new..." +msgstr "Crea nuovo..." + +msgid "CreateNewFork|Fork" +msgstr "Fork" + +msgid "CreateTag|Tag" +msgstr "Tag" + +msgid "Cron Timezone" +msgstr "Cron Timezone" + +msgid "Cron syntax" +msgstr "Sintassi Cron" + +msgid "Custom notification events" +msgstr "Eventi-Notifica personalizzati" + +msgid "" +"Custom notification levels are the same as participating levels. With custom " +"notification levels you will also receive notifications for select events. " +"To find out more, check out %{notification_link}." +msgstr "" +"I livelli di notifica personalizzati sono uguali a quelli di partecipazione. " +"Con i livelli di notifica personalizzati riceverai anche notifiche per gli " +"eventi da te scelti %{notification_link}." + +msgid "Cycle Analytics" +msgstr "Statistiche Cicliche" + +msgid "" +"Cycle Analytics gives an overview of how much time it takes to go from idea " +"to production in your project." +msgstr "" +"L'Analisi Ciclica fornisce una panoramica sul tempo che trascorre tra l'idea " +"ed il rilascio in produzione del tuo progetto" + +msgid "CycleAnalyticsStage|Code" +msgstr "Codice" + +msgid "CycleAnalyticsStage|Issue" +msgstr "Issue" + +msgid "CycleAnalyticsStage|Plan" +msgstr "Pianificazione" + +msgid "CycleAnalyticsStage|Production" +msgstr "Produzione" + +msgid "CycleAnalyticsStage|Review" +msgstr "Revisione" + +msgid "CycleAnalyticsStage|Staging" +msgstr "Pre-rilascio" + +msgid "CycleAnalyticsStage|Test" +msgstr "Test" + +msgid "Define a custom pattern with cron syntax" +msgstr "Definisci un patter personalizzato mediante la sintassi cron" + +msgid "Delete" +msgstr "Elimina" + +msgid "Deploy" +msgid_plural "Deploys" +msgstr[0] "Rilascio" +msgstr[1] "Rilasci" + +msgid "Description" +msgstr "Descrizione" + +msgid "Directory name" +msgstr "Nome cartella" + +msgid "Don't show again" +msgstr "Non mostrare più" + +msgid "Download" +msgstr "Scarica" + +msgid "Download tar" +msgstr "Scarica tar" + +msgid "Download tar.bz2" +msgstr "Scarica tar.bz2" + +msgid "Download tar.gz" +msgstr "Scarica tar.gz" + +msgid "Download zip" +msgstr "Scarica zip" + +msgid "DownloadArtifacts|Download" +msgstr "Scarica" + +msgid "DownloadCommit|Email Patches" +msgstr "Email Patches" + +msgid "DownloadCommit|Plain Diff" +msgstr "Differenze" + +msgid "DownloadSource|Download" +msgstr "Scarica" + +msgid "Edit" +msgstr "Modifica" + +msgid "Edit Pipeline Schedule %{id}" +msgstr "Cambia programmazione della pipeline %{id}" + +msgid "Every day (at 4:00am)" +msgstr "Ogni giorno (alle 4 del mattino)" + +msgid "Every month (on the 1st at 4:00am)" +msgstr "Ogni primo giorno del mese (alle 4 del mattino)" + +msgid "Every week (Sundays at 4:00am)" +msgstr "Ogni settimana (Di domenica alle 4 del mattino)" + +msgid "Failed to change the owner" +msgstr "Impossibile cambiare owner" + +msgid "Failed to remove the pipeline schedule" +msgstr "Impossibile rimuovere la pipeline pianificata" + +msgid "Files" +msgstr "Files" + +msgid "Filter by commit message" +msgstr "Filtra per messaggio di commit" + +msgid "Find by path" +msgstr "Trova in percorso" + +msgid "Find file" +msgstr "Trova file" + +msgid "FirstPushedBy|First" +msgstr "Primo" + +msgid "FirstPushedBy|pushed by" +msgstr "Push di" + +msgid "Fork" +msgid_plural "Forks" +msgstr[0] "Fork" +msgstr[1] "Forks" + +msgid "ForkedFromProjectPath|Forked from" +msgstr "Fork da" + +msgid "From issue creation until deploy to production" +msgstr "Dalla creazione di un issue fino al rilascio in produzione" + +msgid "From merge request merge until deploy to production" +msgstr "" +"Dalla richiesta di merge fino effettua il merge fino al rilascio in " +"produzione" + +msgid "Go to your fork" +msgstr "Vai il tuo fork" + +msgid "GoToYourFork|Fork" +msgstr "Fork" + +msgid "Home" +msgstr "Home" + +msgid "Housekeeping successfully started" +msgstr "Housekeeping iniziato con successo" + +msgid "Import repository" +msgstr "Importa repository" + +msgid "Interval Pattern" +msgstr "Intervallo di Pattern" + +msgid "Introducing Cycle Analytics" +msgstr "Introduzione delle Analisi Cicliche" + +msgid "LFSStatus|Disabled" +msgstr "Disabilitato" + +msgid "LFSStatus|Enabled" +msgstr "Abilitato" + +msgid "Last %d day" +msgid_plural "Last %d days" +msgstr[0] "L'ultimo %d giorno" +msgstr[1] "Gli ultimi %d giorni" + +msgid "Last Pipeline" +msgstr "Ultima Pipeline" + +msgid "Last Update" +msgstr "Ultimo Aggiornamento" + +msgid "Last commit" +msgstr "Ultimo Commit" + +msgid "Learn more in the" +msgstr "Leggi di più su" + +msgid "Learn more in the|pipeline schedules documentation" +msgstr "documentazione sulla pianificazione delle pipelines" + +msgid "Leave group" +msgstr "Abbandona il gruppo" + +msgid "Leave project" +msgstr "Abbandona il progetto" + +msgid "Limited to showing %d event at most" +msgid_plural "Limited to showing %d events at most" +msgstr[0] "Limita visualizzazione %d d'evento" +msgstr[1] "Limita visualizzazione %d di eventi" + +msgid "Median" +msgstr "Mediano" + +msgid "MissingSSHKeyWarningLink|add an SSH key" +msgstr "aggiungi una chiave SSH" + +msgid "New Issue" +msgid_plural "New Issues" +msgstr[0] "Nuovo Issue" +msgstr[1] "Nuovi Issues" + +msgid "New Pipeline Schedule" +msgstr "Nuova pianificazione Pipeline" + +msgid "New branch" +msgstr "Nuova Branch" + +msgid "New directory" +msgstr "Nuova directory" + +msgid "New file" +msgstr "Nuovo file" + +msgid "New issue" +msgstr "Nuovo Issue" + +msgid "New merge request" +msgstr "Nuova richiesta di merge" + +msgid "New schedule" +msgstr "Nuova pianficazione" + +msgid "New snippet" +msgstr "Nuovo snippet" + +msgid "New tag" +msgstr "Nuovo tag" + +msgid "No repository" +msgstr "Nessuna Repository" + +msgid "No schedules" +msgstr "Nessuna pianificazione" + +msgid "Not available" +msgstr "Non disponibile" + +msgid "Not enough data" +msgstr "Dati insufficienti " + +msgid "Notification events" +msgstr "Notifica eventi" + +msgid "NotificationEvent|Close issue" +msgstr "Chiudi issue" + +msgid "NotificationEvent|Close merge request" +msgstr "Chiudi richiesta di merge" + +msgid "NotificationEvent|Failed pipeline" +msgstr "Pipeline fallita" + +msgid "NotificationEvent|Merge merge request" +msgstr "Completa la richiesta di merge" + +msgid "NotificationEvent|New issue" +msgstr "Nuovo issue" + +msgid "NotificationEvent|New merge request" +msgstr "Nuova richiesta di merge" + +msgid "NotificationEvent|New note" +msgstr "Nuova nota" + +msgid "NotificationEvent|Reassign issue" +msgstr "Riassegna issue" + +msgid "NotificationEvent|Reassign merge request" +msgstr "Riassegna richiesta di Merge" + +msgid "NotificationEvent|Reopen issue" +msgstr "Riapri issue" + +msgid "NotificationEvent|Successful pipeline" +msgstr "Pipeline Completata" + +msgid "NotificationLevel|Custom" +msgstr "Personalizzato" + +msgid "NotificationLevel|Disabled" +msgstr "Disabilitato" + +msgid "NotificationLevel|Global" +msgstr "Globale" + +msgid "NotificationLevel|On mention" +msgstr "Se menzionato" + +msgid "NotificationLevel|Participate" +msgstr "Partecipa" + +msgid "NotificationLevel|Watch" +msgstr "Osserva" + +msgid "OfSearchInADropdown|Filter" +msgstr "Filtra" + +msgid "OpenedNDaysAgo|Opened" +msgstr "Aperto" + +msgid "Options" +msgstr "Opzioni" + +msgid "Owner" +msgstr "Owner" + +msgid "Pipeline" +msgstr "Pipeline" + +msgid "Pipeline Health" +msgstr "Stato della Pipeline" + +msgid "Pipeline Schedule" +msgstr "Pianificazione Pipeline" + +msgid "Pipeline Schedules" +msgstr "Pianificazione multipla Pipeline" + +msgid "PipelineSchedules|Activated" +msgstr "Attivata" + +msgid "PipelineSchedules|Active" +msgstr "Attiva" + +msgid "PipelineSchedules|All" +msgstr "Tutto" + +msgid "PipelineSchedules|Inactive" +msgstr "Inattiva" + +msgid "PipelineSchedules|Next Run" +msgstr "Prossima esecuzione" + +msgid "PipelineSchedules|None" +msgstr "Nessuna" + +msgid "PipelineSchedules|Provide a short description for this pipeline" +msgstr "Fornisci una breve descrizione per questa pipeline" + +msgid "PipelineSchedules|Take ownership" +msgstr "Prendi possesso" + +msgid "PipelineSchedules|Target" +msgstr "Target" + +msgid "PipelineSheduleIntervalPattern|Custom" +msgstr "Personalizzato" + +msgid "Pipeline|with stage" +msgstr "con stadio" + +msgid "Pipeline|with stages" +msgstr "con più stadi" + +msgid "Project '%{project_name}' queued for deletion." +msgstr "Il Progetto '%{project_name}' in coda di eliminazione." + +msgid "Project '%{project_name}' was successfully created." +msgstr "Il Progetto '%{project_name}' è stato creato con successo." + +msgid "Project '%{project_name}' was successfully updated." +msgstr "Il Progetto '%{project_name}' è stato aggiornato con successo." + +msgid "Project '%{project_name}' will be deleted." +msgstr "Il Progetto '%{project_name}' verrà eliminato" + +msgid "Project access must be granted explicitly to each user." +msgstr "L'accesso al progetto dev'esser fornito esplicitamente ad ogni utente" + +msgid "Project export could not be deleted." +msgstr "L'esportazione del progetto non può essere eliminata." + +msgid "Project export has been deleted." +msgstr "L'esportazione del progetto è stata eliminata." + +msgid "" +"Project export link has expired. Please generate a new export from your " +"project settings." +msgstr "" +"Il link d'esportazione del progetto è scaduto. Genera una nuova esportazione " +"dalle impostazioni del tuo progetto." + +msgid "Project export started. A download link will be sent by email." +msgstr "" +"Esportazione del progetto iniziata. Un link di download sarà inviato via " +"email." + +msgid "Project home" +msgstr "Home di progetto" + +msgid "ProjectFeature|Disabled" +msgstr "Disabilitato" + +msgid "ProjectFeature|Everyone with access" +msgstr "Chiunque con accesso" + +msgid "ProjectFeature|Only team members" +msgstr "Solo i membri del team" + +msgid "ProjectFileTree|Name" +msgstr "Nome" + +msgid "ProjectLastActivity|Never" +msgstr "Mai" + +msgid "ProjectLifecycle|Stage" +msgstr "Stadio" + +msgid "ProjectNetworkGraph|Graph" +msgstr "Grafico" + +msgid "Read more" +msgstr "Continua..." + +msgid "Readme" +msgstr "Leggimi" + +msgid "RefSwitcher|Branches" +msgstr "Branches" + +msgid "RefSwitcher|Tags" +msgstr "Tags" + +msgid "Related Commits" +msgstr "Commit correlati" + +msgid "Related Deployed Jobs" +msgstr "Attività di Rilascio Correlate" + +msgid "Related Issues" +msgstr "Issues Correlati" + +msgid "Related Jobs" +msgstr "Attività Correlate" + +msgid "Related Merge Requests" +msgstr "Richieste di Merge Correlate" + +msgid "Related Merged Requests" +msgstr "Richieste di Merge Completate Correlate" + +msgid "Remind later" +msgstr "Ricordamelo più tardi" + +msgid "Remove project" +msgstr "Rimuovi progetto" + +msgid "Request Access" +msgstr "Richiedi accesso" + +msgid "Revert this commit" +msgstr "Ripristina questo commit" + +msgid "Revert this merge request" +msgstr "Ripristina questa richiesta di merge" + +msgid "Save pipeline schedule" +msgstr "Salva pianificazione pipeline" + +msgid "Schedule a new pipeline" +msgstr "Pianifica una nuova Pipeline" + +msgid "Scheduling Pipelines" +msgstr "Pianificazione pipelines" + +msgid "Search branches and tags" +msgstr "Ricerca branches e tags" + +msgid "Select Archive Format" +msgstr "Seleziona formato d'archivio" + +msgid "Select a timezone" +msgstr "Seleziona una timezone" + +msgid "Select target branch" +msgstr "Seleziona una branch di destinazione" + +msgid "Set a password on your account to pull or push via %{protocol}." +msgstr "" +"Imposta una password sul tuo account per eseguire pull o push tramite " +"%{protocol}." + +msgid "Set up CI" +msgstr "Configura CI" + +msgid "Set up Koding" +msgstr "Configura Koding" + +msgid "Set up auto deploy" +msgstr "Configura il rilascio automatico" + +msgid "SetPasswordToCloneLink|set a password" +msgstr "imposta una password" + +msgid "Showing %d event" +msgid_plural "Showing %d events" +msgstr[0] "Visualizza %d evento" +msgstr[1] "Visualizza %d eventi" + +msgid "Source code" +msgstr "Codice Sorgente" + +msgid "StarProject|Star" +msgstr "Star" + +msgid "Start a %{new_merge_request} with these changes" +msgstr "inizia una %{new_merge_request} con queste modifiche" + +msgid "Switch branch/tag" +msgstr "Cambia branch/tag" + +msgid "Tag" +msgid_plural "Tags" +msgstr[0] "Tag" +msgstr[1] "Tags" + +msgid "Tags" +msgstr "Tags" + +msgid "Target Branch" +msgstr "Branch di destinazione" + +msgid "" +"The coding stage shows the time from the first commit to creating the merge " +"request. The data will automatically be added here once you create your " +"first merge request." +msgstr "" +"Lo stadio di programmazione mostra il tempo trascorso dal primo commit alla " +"creazione di una richiesta di merge (MR). I dati saranno aggiunti una volta " +"che avrai creato la prima richiesta di merge." + +msgid "The collection of events added to the data gathered for that stage." +msgstr "L'insieme di eventi aggiunti ai dati raccolti per quello stadio." + +msgid "The fork relationship has been removed." +msgstr "La relazione del fork è stata rimossa" + +msgid "" +"The issue stage shows the time it takes from creating an issue to assigning " +"the issue to a milestone, or add the issue to a list on your Issue Board. " +"Begin creating issues to see data for this stage." +msgstr "" +"Questo stadio di issue mostra il tempo che ci vuole dal creare un issue " +"all'assegnarli una milestone, o ad aggiungere un issue alla tua board. Crea " +"un issue per vedere questo stadio." + +msgid "The phase of the development lifecycle." +msgstr "Il ciclo vitale della fase di sviluppo." + +msgid "" +"The pipelines schedule runs pipelines in the future, repeatedly, for " +"specific branches or tags. Those scheduled pipelines will inherit limited " +"project access based on their associated user." +msgstr "" +"Le pipelines pianificate vengono eseguite nel futuro, ripetitivamente, per " +"specifici tag o branch ed ereditano restrizioni di progetto basate " +"sull'utente ad esse associato." + +msgid "" +"The planning stage shows the time from the previous step to pushing your " +"first commit. This time will be added automatically once you push your first " +"commit." +msgstr "" +"Lo stadio di pianificazione mostra il tempo trascorso dal primo commit al " +"suo step precedente. Questo periodo sarà disponibile automaticamente nel " +"momento in cui farai il primo commit." + +msgid "" +"The production stage shows the total time it takes between creating an issue " +"and deploying the code to production. The data will be automatically added " +"once you have completed the full idea to production cycle." +msgstr "" +"Lo stadio di produzione mostra il tempo totale che trascorre tra la " +"creazione di un issue il suo rilascio (inteso come codice) in produzione. " +"Questo dato sarà disponibile automaticamente nel momento in cui avrai " +"completato l'intero processo ideale del ciclo di produzione" + +msgid "The project can be accessed by any logged in user." +msgstr "Qualunque utente autenticato può accedere a questo progetto." + +msgid "The project can be accessed without any authentication." +msgstr "" +"Chiunque può accedere a questo progetto (senza alcuna autenticazione)." + +msgid "The repository for this project does not exist." +msgstr "La repository di questo progetto non esiste." + +msgid "" +"The review stage shows the time from creating the merge request to merging " +"it. The data will automatically be added after you merge your first merge " +"request." +msgstr "" +"Lo stadio di revisione mostra il tempo tra una richiesta di merge al suo " +"svolgimento effettivo. Questo dato sarà disponibile appena avrai completato " +"una MR (Merger Request)" + +msgid "" +"The staging stage shows the time between merging the MR and deploying code " +"to the production environment. The data will be automatically added once you " +"deploy to production for the first time." +msgstr "" +"Lo stadio di pre-rilascio mostra il tempo che trascorre da una MR (Richiesta " +"di Merge) completata al suo rilascio in ambiente di produzione. Questa " +"informazione sarà disponibile dal tuo primo rilascio in produzione" + +msgid "" +"The testing stage shows the time GitLab CI takes to run every pipeline for " +"the related merge request. The data will automatically be added after your " +"first pipeline finishes running." +msgstr "" +"Lo stadio di test mostra il tempo che ogni Pipeline impiega per essere " +"eseguita in ogni Richiesta di Merge correlata. L'informazione sarà " +"disponibile automaticamente quando la tua prima Pipeline avrà finito d'esser " +"eseguita." + +msgid "The time taken by each data entry gathered by that stage." +msgstr "" +"Il tempo aggregato relativo eventi/data entry raccolto in quello stadio." + +msgid "" +"The value lying at the midpoint of a series of observed values. E.g., " +"between 3, 5, 9, the median is 5. Between 3, 5, 7, 8, the median is (5+7)/2 =" +" 6." +msgstr "" +"Il valore falsato nel mezzo di una serie di dati osservati. ES: tra 3,5,9 il " +"mediano è 5. Tra 3,5,7,8 il mediano è (5+7)/2 quindi 6." + +msgid "" +"This means you can not push code until you create an empty repository or " +"import existing one." +msgstr "" +"Questo significa che non è possibile effettuare push di codice fino a che " +"non crei una repository vuota o ne importi una esistente" + +msgid "Time before an issue gets scheduled" +msgstr "Il tempo che impiega un issue per esser pianificato" + +msgid "Time before an issue starts implementation" +msgstr "Il tempo che impiega un issue per esser implementato" + +msgid "Time between merge request creation and merge/close" +msgstr "Il tempo tra la creazione di una richiesta di merge ed il merge/close" + +msgid "Time until first merge request" +msgstr "Il tempo fino alla prima richiesta di merge" + +msgid "Timeago|%s days ago" +msgstr "%s giorni fa" + +msgid "Timeago|%s days remaining" +msgstr "%s giorni rimanenti" + +msgid "Timeago|%s hours remaining" +msgstr "%s ore rimanenti" + +msgid "Timeago|%s minutes ago" +msgstr "%s minuti fa" + +msgid "Timeago|%s minutes remaining" +msgstr "%s minuti rimanenti" + +msgid "Timeago|%s months ago" +msgstr "%s minuti fa" + +msgid "Timeago|%s months remaining" +msgstr "%s mesi rimanenti" + +msgid "Timeago|%s seconds remaining" +msgstr "%s secondi rimanenti" + +msgid "Timeago|%s weeks ago" +msgstr "%s settimane fa" + +msgid "Timeago|%s weeks remaining" +msgstr "%s settimane rimanenti" + +msgid "Timeago|%s years ago" +msgstr "%s anni fa" + +msgid "Timeago|%s years remaining" +msgstr "%s anni rimanenti" + +msgid "Timeago|1 day remaining" +msgstr "1 giorno rimanente" + +msgid "Timeago|1 hour remaining" +msgstr "1 ora rimanente" + +msgid "Timeago|1 minute remaining" +msgstr "1 minuto rimanente" + +msgid "Timeago|1 month remaining" +msgstr "1 mese rimanente" + +msgid "Timeago|1 week remaining" +msgstr "1 settimana rimanente" + +msgid "Timeago|1 year remaining" +msgstr "1 anno rimanente" + +msgid "Timeago|Past due" +msgstr "Entro" + +msgid "Timeago|a day ago" +msgstr "un giorno fa" + +msgid "Timeago|a month ago" +msgstr "un mese fa" + +msgid "Timeago|a week ago" +msgstr "una settimana fa" + +msgid "Timeago|a while" +msgstr "poco fa" + +msgid "Timeago|a year ago" +msgstr "un anno fa" + +msgid "Timeago|about %s hours ago" +msgstr "circa %s ore fa" + +msgid "Timeago|about a minute ago" +msgstr "circa un minuto fa" + +msgid "Timeago|about an hour ago" +msgstr "circa un ora fa" + +msgid "Timeago|in %s days" +msgstr "in %s giorni" + +msgid "Timeago|in %s hours" +msgstr "in %s ore" + +msgid "Timeago|in %s minutes" +msgstr "in %s minuti" + +msgid "Timeago|in %s months" +msgstr "in %s mesi" + +msgid "Timeago|in %s seconds" +msgstr "in %s secondi" + +msgid "Timeago|in %s weeks" +msgstr "in %s settimane" + +msgid "Timeago|in %s years" +msgstr "in %s anni" + +msgid "Timeago|in 1 day" +msgstr "in 1 giorno" + +msgid "Timeago|in 1 hour" +msgstr "in 1 ora" + +msgid "Timeago|in 1 minute" +msgstr "in 1 minuto" + +msgid "Timeago|in 1 month" +msgstr "in 1 mese" + +msgid "Timeago|in 1 week" +msgstr "in 1 settimana" + +msgid "Timeago|in 1 year" +msgstr "in 1 anno" + +msgid "Timeago|less than a minute ago" +msgstr "meno di un minuto fa" + +msgid "Time|hr" +msgid_plural "Time|hrs" +msgstr[0] "hr" +msgstr[1] "hr" + +msgid "Time|min" +msgid_plural "Time|mins" +msgstr[0] "min" +msgstr[1] "mins" + +msgid "Time|s" +msgstr "s" + +msgid "Total Time" +msgstr "Tempo Totale" + +msgid "Total test time for all commits/merges" +msgstr "Tempo totale di test per tutti i commits/merges" + +msgid "Unstar" +msgstr "Unstar" + +msgid "Upload New File" +msgstr "Carica un nuovo file" + +msgid "Upload file" +msgstr "Carica file" + +msgid "UploadLink|click to upload" +msgstr "clicca per caricare" + +msgid "Use your global notification setting" +msgstr "Usa le tue impostazioni globali " + +msgid "View open merge request" +msgstr "Mostra la richieste di merge aperte" + +msgid "VisibilityLevel|Internal" +msgstr "Interno" + +msgid "VisibilityLevel|Private" +msgstr "Privato" + +msgid "VisibilityLevel|Public" +msgstr "Pubblico" + +msgid "Want to see the data? Please ask an administrator for access." +msgstr "" +"Vuoi visualizzare i dati? Richiedi l'accesso ad un amministratore, grazie." + +msgid "We don't have enough data to show this stage." +msgstr "Non ci sono sufficienti dati da mostrare su questo stadio" + +msgid "Withdraw Access Request" +msgstr "Ritira richiesta d'accesso" + +msgid "" +"You are going to remove %{project_name_with_namespace}.\n" +"Removed project CANNOT be restored!\n" +"Are you ABSOLUTELY sure?" +msgstr "" +"Stai per rimuovere %{project_name_with_namespace}.\n" +"I progetti rimossi NON POSSONO essere ripristinati\n" +"Sei assolutamente sicuro?" + +msgid "" +"You are going to remove the fork relationship to source project " +"%{forked_from_project}. Are you ABSOLUTELY sure?" +msgstr "" +"Stai per rimuovere la relazione con il progetto sorgente " +"%{forked_from_project}. Sei ASSOLUTAMENTE sicuro?" + +msgid "" +"You are going to transfer %{project_name_with_namespace} to another owner. " +"Are you ABSOLUTELY sure?" +msgstr "" +"Stai per trasferire %{project_name_with_namespace} ad un altro owner. Sei " +"ASSOLUTAMENTE sicuro?" + +msgid "You can only add files when you are on a branch" +msgstr "Puoi aggiungere files solo quando sei in una branch" + +msgid "You have reached your project limit" +msgstr "Hai raggiunto il tuo limite di progetto" + +msgid "You must sign in to star a project" +msgstr "Devi accedere per porre una star al progetto" + +msgid "You need permission." +msgstr "Necessiti del permesso." + +msgid "You will not get any notifications via email" +msgstr "Non riceverai alcuna notifica via email" + +msgid "You will only receive notifications for the events you choose" +msgstr "Riceverai notifiche solo per gli eventi che hai scelto" + +msgid "" +"You will only receive notifications for threads you have participated in" +msgstr "Riceverai notifiche solo per i threads a cui hai partecipato" + +msgid "You will receive notifications for any activity" +msgstr "Riceverai notifiche per ogni attività " + +msgid "" +"You will receive notifications only for comments in which you were " +"@mentioned" +msgstr "Riceverai notifiche solo per i commenti ai quale sei stato menzionato" + +msgid "" +"You won't be able to pull or push project code via %{protocol} until you " +"%{set_password_link} on your account" +msgstr "" +"Non sarai in grado di eseguire pull o push di codice tramite %{protocol} " +"fino a che %{set_password_link} nel tuo account." + +msgid "" +"You won't be able to pull or push project code via SSH until you " +"%{add_ssh_key_link} to your profile" +msgstr "" +"Non sarai in grado di effettuare push o pull tramite SSH fino a che " +"%{add_ssh_key_link} al tuo profilo" + +msgid "Your name" +msgstr "Il tuo nome" + +msgid "day" +msgid_plural "days" +msgstr[0] "giorno" +msgstr[1] "giorni" + +msgid "new merge request" +msgstr "Nuova richiesta di merge" + +msgid "notification emails" +msgstr "Notifiche via email" + +msgid "parent" +msgid_plural "parents" +msgstr[0] "parent" +msgstr[1] "parents" + diff --git a/locale/it/gitlab.po.time_stamp b/locale/it/gitlab.po.time_stamp new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/locale/it/gitlab.po.time_stamp diff --git a/locale/zh_CN/gitlab.po b/locale/zh_CN/gitlab.po index 8ba95093b82..2f21aae2899 100644 --- a/locale/zh_CN/gitlab.po +++ b/locale/zh_CN/gitlab.po @@ -4,17 +4,26 @@ msgid "" msgstr "" "Project-Id-Version: gitlab 1.0.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-06-15 21:59-0500\n" +"POT-Creation-Date: 2017-06-19 15:50-0500\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"PO-Revision-Date: 2017-06-19 09:57-0400\n" +"PO-Revision-Date: 2017-06-27 03:18-0400\n" "Last-Translator: Huang Tao <htve@outlook.com>\n" "Language-Team: Chinese (China) (https://translate.zanata.org/project/view/GitLab)\n" "Language: zh-CN\n" "X-Generator: Zanata 3.9.6\n" "Plural-Forms: nplurals=1; plural=0\n" +msgid "%d additional commit has been omitted to prevent performance issues." +msgid_plural "" +"%d additional commits have been omitted to prevent performance issues." +msgstr[0] "为æ高页é¢åŠ 载速度åŠæ€§èƒ½ï¼Œå·²çœç•¥äº† %d 次æ交。" + +msgid "%d commit" +msgid_plural "%d commits" +msgstr[0] "%d 次æ交" + msgid "%{commit_author_link} committed %{commit_timeago}" msgstr "ç”± %{commit_author_link} æ交于 %{commit_timeago}" @@ -63,9 +72,24 @@ msgstr "" "已创建分支 <strong>%{branch_name}</strong> 。如需设置自动部署, 请选择åˆé€‚çš„ GitLab CI Yaml " "模æ¿å¹¶æ交更改。%{link_to_autodeploy_doc}" +msgid "BranchSwitcherPlaceholder|Search branches" +msgstr "æœç´¢åˆ†æ”¯" + +msgid "BranchSwitcherTitle|Switch branch" +msgstr "切æ¢åˆ†æ”¯" + msgid "Branches" msgstr "分支" +msgid "Browse Directory" +msgstr "æµè§ˆç›®å½•" + +msgid "Browse File" +msgstr "æµè§ˆæ–‡ä»¶" + +msgid "Browse Files" +msgstr "æµè§ˆæ–‡ä»¶" + msgid "Browse files" msgstr "æµè§ˆæ–‡ä»¶" @@ -172,6 +196,9 @@ msgstr "æ·»åŠ %{file_name}" msgid "Commits" msgstr "æ交" +msgid "Commits feed" +msgstr "æ交动æ€" + msgid "Commits|History" msgstr "历å²" @@ -329,6 +356,9 @@ msgstr "æ— æ³•åˆ é™¤æµæ°´çº¿è®¡åˆ’" msgid "Files" msgstr "文件" +msgid "Filter by commit message" +msgstr "按æ交消æ¯è¿‡æ»¤" + msgid "Find by path" msgstr "按路径查找" @@ -692,7 +722,7 @@ msgstr "选择时区" msgid "Select target branch" msgstr "é€‰æ‹©ç›®æ ‡åˆ†æ”¯" -msgid "Set a password on your account to pull or push via %{protocol}" +msgid "Set a password on your account to pull or push via %{protocol}." msgstr "为账å·åˆ›å»ºä¸€ä¸ªç”¨äºŽæŽ¨é€æˆ–拉å–çš„ %{protocol} 密ç 。" msgid "Set up CI" @@ -974,9 +1004,15 @@ msgstr "ä¸Šä¼ æ–°æ–‡ä»¶" msgid "Upload file" msgstr "ä¸Šä¼ æ–‡ä»¶" +msgid "UploadLink|click to upload" +msgstr "ç‚¹å‡»ä¸Šä¼ " + msgid "Use your global notification setting" msgstr "使用全局通知设置" +msgid "View open merge request" +msgstr "查看待处ç†çš„åˆå¹¶è¯·æ±‚" + msgid "VisibilityLevel|Internal" msgstr "内部" diff --git a/locale/zh_HK/gitlab.po b/locale/zh_HK/gitlab.po index 4d545d27185..afdbd01b7d7 100644 --- a/locale/zh_HK/gitlab.po +++ b/locale/zh_HK/gitlab.po @@ -9,13 +9,22 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"PO-Revision-Date: 2017-06-19 09:57-0400\n" +"PO-Revision-Date: 2017-06-23 01:23-0400\n" "Last-Translator: Huang Tao <htve@outlook.com>\n" "Language-Team: Chinese (Hong Kong) (https://translate.zanata.org/project/view/GitLab)\n" "Language: zh-HK\n" "X-Generator: Zanata 3.9.6\n" "Plural-Forms: nplurals=1; plural=0\n" +msgid "%d additional commit has been omitted to prevent performance issues." +msgid_plural "" +"%d additional commits have been omitted to prevent performance issues." +msgstr[0] "為æ高é é¢åŠ 載速度åŠæ€§èƒ½ï¼Œå·²çœç•¥äº† %d 次æ交。" + +msgid "%d commit" +msgid_plural "%d commits" +msgstr[0] " %d 次æ交" + msgid "%{commit_author_link} committed %{commit_timeago}" msgstr "ç”± %{commit_author_link} æ交於 %{commit_timeago}" @@ -64,9 +73,24 @@ msgstr "" "分支 <strong>%{branch_name}</strong> 已創建。如需è¨ç½®è‡ªå‹•éƒ¨ç½²ï¼Œ è«‹é¸æ“‡åˆé©çš„ GitLab CI Yaml " "模æ¿ä½µæ交更改。%{link_to_autodeploy_doc}" +msgid "BranchSwitcherPlaceholder|Search branches" +msgstr "æœç´¢åˆ†æ”¯" + +msgid "BranchSwitcherTitle|Switch branch" +msgstr "切æ›åˆ†æ”¯" + msgid "Branches" msgstr "分支" +msgid "Browse Directory" +msgstr "ç€è¦½ç›®éŒ„" + +msgid "Browse File" +msgstr "ç€è¦½æ–‡ä»¶" + +msgid "Browse Files" +msgstr "ç€è¦½æ–‡ä»¶" + msgid "Browse files" msgstr "ç€è¦½æ–‡ä»¶" @@ -173,6 +197,9 @@ msgstr "æ·»åŠ %{file_name}" msgid "Commits" msgstr "æ交" +msgid "Commits feed" +msgstr "æ交動態" + msgid "Commits|History" msgstr "æ·å²" @@ -330,6 +357,9 @@ msgstr "無法刪除æµæ°´ç·šè¨ˆåŠƒ" msgid "Files" msgstr "文件" +msgid "Filter by commit message" +msgstr "按æ交消æ¯éŽæ¿¾" + msgid "Find by path" msgstr "按路徑查找" @@ -693,7 +723,7 @@ msgstr "é¸æ“‡æ™‚å€" msgid "Select target branch" msgstr "é¸æ“‡ç›®æ¨™åˆ†æ”¯" -msgid "Set a password on your account to pull or push via %{protocol}" +msgid "Set a password on your account to pull or push via %{protocol}." msgstr "ç‚ºè³¬è™Ÿæ·»åŠ å£¹å€‹ç”¨æ–¼æŽ¨é€æˆ–拉å–çš„ %{protocol} 密碼。" msgid "Set up CI" @@ -975,9 +1005,15 @@ msgstr "上傳新文件" msgid "Upload file" msgstr "上傳文件" +msgid "UploadLink|click to upload" +msgstr "點擊上傳" + msgid "Use your global notification setting" msgstr "使用全局通知è¨ç½®" +msgid "View open merge request" +msgstr "查看開啟的åˆä¸¦è«‹æ±‚" + msgid "VisibilityLevel|Internal" msgstr "內部" diff --git a/locale/zh_TW/gitlab.po b/locale/zh_TW/gitlab.po index bb2b84c67b0..fa0b3b339fa 100644 --- a/locale/zh_TW/gitlab.po +++ b/locale/zh_TW/gitlab.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: gitlab 1.0.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-06-15 21:59-0500\n" +"POT-Creation-Date: 2017-06-19 15:50-0500\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -18,6 +18,15 @@ msgstr "" "X-Generator: Zanata 3.9.6\n" "Plural-Forms: nplurals=1; plural=0\n" +msgid "%d additional commit has been omitted to prevent performance issues." +msgid_plural "" +"%d additional commits have been omitted to prevent performance issues." +msgstr[0] "å› æ•ˆèƒ½è€ƒé‡ï¼Œä¸é¡¯ç¤º %d 個更動 (commit)。" + +msgid "%d commit" +msgid_plural "%d commits" +msgstr[0] "%d 個更動 (commit)" + msgid "%{commit_author_link} committed %{commit_timeago}" msgstr "%{commit_author_link} 在 %{commit_timeago} é€äº¤" @@ -66,9 +75,24 @@ msgstr "" "已建立分支 (branch) <strong>%{branch_name}</strong> 。如è¦è¨å®šè‡ªå‹•éƒ¨ç½²ï¼Œ è«‹é¸æ“‡åˆé©çš„ GitLab CI " "Yaml 模æ¿ï¼Œç„¶å¾Œè¨˜å¾—è¦é€äº¤ (commit) 您的編輯內容。%{link_to_autodeploy_doc}\n" +msgid "BranchSwitcherPlaceholder|Search branches" +msgstr "æœå°‹åˆ†æ”¯ (branches)" + +msgid "BranchSwitcherTitle|Switch branch" +msgstr "切æ›åˆ†æ”¯ (branch)" + msgid "Branches" msgstr "分支 (branch) " +msgid "Browse Directory" +msgstr "ç€è¦½ç›®éŒ„" + +msgid "Browse File" +msgstr "ç€è¦½æª”案" + +msgid "Browse Files" +msgstr "ç€è¦½æª”案" + msgid "Browse files" msgstr "ç€è¦½æª”案" @@ -175,6 +199,9 @@ msgstr "建立 %{file_name}" msgid "Commits" msgstr "更動記錄 (commit) " +msgid "Commits feed" +msgstr "æ›´å‹•æ‘˜è¦ (commit feed)" + msgid "Commits|History" msgstr "éŽåŽ»æ›´å‹• (commit) " @@ -332,6 +359,9 @@ msgstr "無法刪除æµæ°´ç·š (pipeline) 排程" msgid "Files" msgstr "檔案" +msgid "Filter by commit message" +msgstr "以更動說明篩é¸" + msgid "Find by path" msgstr "以路徑æœå°‹" @@ -695,7 +725,7 @@ msgstr "é¸æ“‡æ™‚å€" msgid "Select target branch" msgstr "é¸æ“‡ç›®æ¨™åˆ†æ”¯ (branch) " -msgid "Set a password on your account to pull or push via %{protocol}" +msgid "Set a password on your account to pull or push via %{protocol}." msgstr "è«‹å…ˆè¨å®šå¯†ç¢¼ï¼Œæ‰èƒ½ä½¿ç”¨ %{protocol} 來上傳 (push) 或下載 (pull) 。" msgid "Set up CI" @@ -985,9 +1015,15 @@ msgstr "上傳新檔案" msgid "Upload file" msgstr "上傳檔案" +msgid "UploadLink|click to upload" +msgstr "點擊上傳" + msgid "Use your global notification setting" msgstr "使用全域通知è¨å®š" +msgid "View open merge request" +msgstr "查看æ¤åˆ†æ”¯çš„åˆä½µè«‹æ±‚ (merge request)" + msgid "VisibilityLevel|Internal" msgstr "內部" diff --git a/rubocop/cop/active_record_dependent.rb b/rubocop/cop/active_record_dependent.rb new file mode 100644 index 00000000000..8d15f150885 --- /dev/null +++ b/rubocop/cop/active_record_dependent.rb @@ -0,0 +1,26 @@ +require_relative '../model_helpers' + +module RuboCop + module Cop + # Cop that prevents the use of `dependent: ...` in ActiveRecord models. + class ActiveRecordDependent < RuboCop::Cop::Cop + include ModelHelpers + + MSG = 'Do not use `dependent: to remove associated data, ' \ + 'use foreign keys with cascading deletes instead'.freeze + + METHOD_NAMES = [:has_many, :has_one, :belongs_to].freeze + + def on_send(node) + return unless in_model?(node) + return unless METHOD_NAMES.include?(node.children[1]) + + node.children.last.each_node(:pair) do |pair| + key_name = pair.children[0].children[0] + + add_offense(pair, :expression) if key_name == :dependent + end + end + end + end +end diff --git a/rubocop/cop/activerecord_serialize.rb b/rubocop/cop/active_record_serialize.rb index 9bdcc3b4c34..204caf37f8b 100644 --- a/rubocop/cop/activerecord_serialize.rb +++ b/rubocop/cop/active_record_serialize.rb @@ -3,7 +3,7 @@ require_relative '../model_helpers' module RuboCop module Cop # Cop that prevents the use of `serialize` in ActiveRecord models. - class ActiverecordSerialize < RuboCop::Cop::Cop + class ActiveRecordSerialize < RuboCop::Cop::Cop include ModelHelpers MSG = 'Do not store serialized data in the database, use separate columns and/or tables instead'.freeze diff --git a/rubocop/cop/project_path_helper.rb b/rubocop/cop/project_path_helper.rb new file mode 100644 index 00000000000..3e1ce71ac06 --- /dev/null +++ b/rubocop/cop/project_path_helper.rb @@ -0,0 +1,51 @@ +module RuboCop + module Cop + class ProjectPathHelper < RuboCop::Cop::Cop + MSG = 'Use short project path helpers without explicitly passing the namespace: ' \ + '`foo_project_bar_path(project, bar)` instead of ' \ + '`foo_namespace_project_bar_path(project.namespace, project, bar)`.'.freeze + + METHOD_NAME_PATTERN = /\A([a-z_]+_)?namespace_project(?:_[a-z_]+)?_(?:url|path)\z/.freeze + + def on_send(node) + return unless method_name(node).to_s =~ METHOD_NAME_PATTERN + + namespace_expr, project_expr = arguments(node) + return unless namespace_expr && project_expr + + return unless namespace_expr.type == :send + return unless method_name(namespace_expr) == :namespace + return unless receiver(namespace_expr) == project_expr + + add_offense(node, :selector) + end + + def autocorrect(node) + helper_name = method_name(node).to_s.sub('namespace_project', 'project') + + arguments = arguments(node) + arguments.shift # Remove namespace argument + + replacement = "#{helper_name}(#{arguments.map(&:source).join(', ')})" + + lambda do |corrector| + corrector.replace(node.source_range, replacement) + end + end + + private + + def receiver(node) + node.children[0] + end + + def method_name(node) + node.children[1] + end + + def arguments(node) + node.children[2..-1] + end + end + end +end diff --git a/rubocop/rubocop.rb b/rubocop/rubocop.rb index 55d7708fa8c..1e70314598a 100644 --- a/rubocop/rubocop.rb +++ b/rubocop/rubocop.rb @@ -1,8 +1,10 @@ require_relative 'cop/custom_error_class' require_relative 'cop/gem_fetcher' -require_relative 'cop/activerecord_serialize' +require_relative 'cop/active_record_serialize' require_relative 'cop/redirect_with_status' require_relative 'cop/polymorphic_associations' +require_relative 'cop/project_path_helper' +require_relative 'cop/active_record_dependent' require_relative 'cop/migration/add_column' require_relative 'cop/migration/add_column_with_default_to_large_table' require_relative 'cop/migration/add_concurrent_foreign_key' diff --git a/spec/controllers/groups/milestones_controller_spec.rb b/spec/controllers/groups/milestones_controller_spec.rb index f3263bc177d..c6e5fb61cf9 100644 --- a/spec/controllers/groups/milestones_controller_spec.rb +++ b/spec/controllers/groups/milestones_controller_spec.rb @@ -23,6 +23,21 @@ describe Groups::MilestonesController do project.team << [user, :master] end + describe "#index" do + it 'shows group milestones page' do + get :index, group_id: group.to_param + + expect(response).to have_http_status(200) + end + + it 'shows group milestones JSON' do + get :index, group_id: group.to_param, format: :json + + expect(response).to have_http_status(200) + expect(response.content_type).to eq 'application/json' + end + end + it_behaves_like 'milestone tabs' describe "#create" do diff --git a/spec/controllers/projects/artifacts_controller_spec.rb b/spec/controllers/projects/artifacts_controller_spec.rb index 428bc45b842..d2c613a2423 100644 --- a/spec/controllers/projects/artifacts_controller_spec.rb +++ b/spec/controllers/projects/artifacts_controller_spec.rb @@ -134,10 +134,7 @@ describe Projects::ArtifactsController do context 'found the job and redirect' do shared_examples 'redirect to the job' do it 'redirects' do - path = browse_namespace_project_job_artifacts_path( - project.namespace, - project, - job) + path = browse_project_job_artifacts_path(project, job) expect(response).to redirect_to(path) end @@ -174,11 +171,7 @@ describe Projects::ArtifactsController do end it 'redirects' do - path = file_namespace_project_job_artifacts_path( - project.namespace, - project, - job, - 'README.md') + path = file_project_job_artifacts_path(project, job, 'README.md') expect(response).to redirect_to(path) end diff --git a/spec/controllers/projects/blob_controller_spec.rb b/spec/controllers/projects/blob_controller_spec.rb index 561bc219bb4..02bbc48dc59 100644 --- a/spec/controllers/projects/blob_controller_spec.rb +++ b/spec/controllers/projects/blob_controller_spec.rb @@ -117,7 +117,7 @@ describe Projects::BlobController do end it 'redirects to blob show' do - expect(response).to redirect_to(namespace_project_blob_path(project.namespace, project, 'master/CHANGELOG')) + expect(response).to redirect_to(project_blob_path(project, 'master/CHANGELOG')) end end @@ -164,7 +164,7 @@ describe Projects::BlobController do end def blob_after_edit_path - namespace_project_blob_path(project.namespace, project, 'master/CHANGELOG') + project_blob_path(project, 'master/CHANGELOG') end before do @@ -186,7 +186,7 @@ describe Projects::BlobController do it 'redirects to MR diff' do put :update, mr_params - after_edit_path = diffs_namespace_project_merge_request_path(project.namespace, project, merge_request) + after_edit_path = diffs_project_merge_request_path(project, merge_request) file_anchor = "##{Digest::SHA1.hexdigest('CHANGELOG')}" expect(response).to redirect_to(after_edit_path + file_anchor) end @@ -223,7 +223,7 @@ describe Projects::BlobController do it 'redirects to blob' do put :update, default_params - expect(response).to redirect_to(namespace_project_blob_path(forked_project.namespace, forked_project, 'master/CHANGELOG')) + expect(response).to redirect_to(project_blob_path(forked_project, 'master/CHANGELOG')) end end @@ -235,8 +235,7 @@ describe Projects::BlobController do put :update, default_params expect(response).to redirect_to( - namespace_project_new_merge_request_path( - forked_project.namespace, + project_new_merge_request_path( forked_project, merge_request: { source_project_id: forked_project.id, diff --git a/spec/controllers/projects/branches_controller_spec.rb b/spec/controllers/projects/branches_controller_spec.rb index 14426b09c73..9cd4e9dbf84 100644 --- a/spec/controllers/projects/branches_controller_spec.rb +++ b/spec/controllers/projects/branches_controller_spec.rb @@ -110,7 +110,7 @@ describe Projects::BranchesController do branch_name: branch, issue_iid: issue.iid - expect(response).to redirect_to namespace_project_tree_path(project.namespace, project, branch) + expect(response).to redirect_to project_tree_path(project, branch) end it 'redirects to autodeploy setup page' do @@ -127,7 +127,7 @@ describe Projects::BranchesController do branch_name: branch, issue_iid: issue.iid - expect(response.location).to include(namespace_project_new_blob_path(project.namespace, project, branch)) + expect(response.location).to include(project_new_blob_path(project, branch)) expect(response).to have_http_status(302) end end @@ -303,7 +303,7 @@ describe Projects::BranchesController do it 'redirects to branches path' do expect(response) - .to redirect_to(namespace_project_branches_path(project.namespace, project)) + .to redirect_to(project_branches_path(project)) end end end @@ -323,7 +323,7 @@ describe Projects::BranchesController do it 'redirects to branches' do destroy_all_merged - expect(response).to redirect_to namespace_project_branches_path(project.namespace, project) + expect(response).to redirect_to project_branches_path(project) end it 'starts worker to delete merged branches' do diff --git a/spec/controllers/projects/commit_controller_spec.rb b/spec/controllers/projects/commit_controller_spec.rb index e10da40eaab..eb61a0c080c 100644 --- a/spec/controllers/projects/commit_controller_spec.rb +++ b/spec/controllers/projects/commit_controller_spec.rb @@ -169,7 +169,7 @@ describe Projects::CommitController do start_branch: 'master', id: commit.id) - expect(response).to redirect_to namespace_project_commits_path(project.namespace, project, 'master') + expect(response).to redirect_to project_commits_path(project, 'master') expect(flash[:notice]).to eq('The commit has been successfully reverted.') end end @@ -191,7 +191,7 @@ describe Projects::CommitController do start_branch: 'master', id: commit.id) - expect(response).to redirect_to namespace_project_commit_path(project.namespace, project, commit.id) + expect(response).to redirect_to project_commit_path(project, commit.id) expect(flash[:alert]).to match('Sorry, we cannot revert this commit automatically.') end end @@ -218,7 +218,7 @@ describe Projects::CommitController do start_branch: 'master', id: master_pickable_commit.id) - expect(response).to redirect_to namespace_project_commits_path(project.namespace, project, 'master') + expect(response).to redirect_to project_commits_path(project, 'master') expect(flash[:notice]).to eq('The commit has been successfully cherry-picked.') end end @@ -240,7 +240,7 @@ describe Projects::CommitController do start_branch: 'master', id: master_pickable_commit.id) - expect(response).to redirect_to namespace_project_commit_path(project.namespace, project, master_pickable_commit.id) + expect(response).to redirect_to project_commit_path(project, master_pickable_commit.id) expect(flash[:alert]).to match('Sorry, we cannot cherry-pick this commit automatically.') end end diff --git a/spec/controllers/projects/compare_controller_spec.rb b/spec/controllers/projects/compare_controller_spec.rb index 8f4694c9854..b4f9fd9b7a2 100644 --- a/spec/controllers/projects/compare_controller_spec.rb +++ b/spec/controllers/projects/compare_controller_spec.rb @@ -72,7 +72,7 @@ describe Projects::CompareController do from: '', to: 'master') - expect(response).to redirect_to(namespace_project_compare_index_path(project.namespace, project, to: 'master')) + expect(response).to redirect_to(project_compare_index_path(project, to: 'master')) end it 'redirects back to index when params[:to] is empty and preserves params[:from]' do @@ -82,7 +82,7 @@ describe Projects::CompareController do from: 'master', to: '') - expect(response).to redirect_to(namespace_project_compare_index_path(project.namespace, project, from: 'master')) + expect(response).to redirect_to(project_compare_index_path(project, from: 'master')) end it 'redirects back to index when params[:from] and params[:to] are empty' do diff --git a/spec/controllers/projects/environments_controller_spec.rb b/spec/controllers/projects/environments_controller_spec.rb index ad0b046742d..f88f50c3cc6 100644 --- a/spec/controllers/projects/environments_controller_spec.rb +++ b/spec/controllers/projects/environments_controller_spec.rb @@ -58,11 +58,9 @@ describe Projects::EnvironmentsController do expect(json_response['stopped_count']).to eq 1 end - it 'does not set the polling interval header' do - # TODO, this is a temporary fix, see follow up issue: - # https://gitlab.com/gitlab-org/gitlab-ee/issues/2677 + it 'sets the polling interval header' do expect(response).to have_http_status(:ok) - expect(response.headers['Poll-Interval']).to be_nil + expect(response.headers['Poll-Interval']).to eq("3000") end end @@ -184,7 +182,7 @@ describe Projects::EnvironmentsController do expect(response).to have_http_status(200) expect(json_response).to eq( { 'redirect_url' => - namespace_project_job_url(project.namespace, project, action) }) + project_job_url(project, action) }) end end @@ -198,7 +196,7 @@ describe Projects::EnvironmentsController do expect(response).to have_http_status(200) expect(json_response).to eq( { 'redirect_url' => - namespace_project_environment_url(project.namespace, project, environment) }) + project_environment_url(project, environment) }) end end end diff --git a/spec/controllers/projects/group_links_controller_spec.rb b/spec/controllers/projects/group_links_controller_spec.rb index b5435357f53..48a2994cbc0 100644 --- a/spec/controllers/projects/group_links_controller_spec.rb +++ b/spec/controllers/projects/group_links_controller_spec.rb @@ -34,7 +34,7 @@ describe Projects::GroupLinksController do it 'redirects to project group links page' do expect(response).to redirect_to( - namespace_project_settings_members_path(project.namespace, project) + project_settings_members_path(project) ) end end @@ -65,7 +65,7 @@ describe Projects::GroupLinksController do it 'redirects to project group links page' do expect(response).to redirect_to( - namespace_project_settings_members_path(project.namespace, project) + project_settings_members_path(project) ) end end @@ -79,7 +79,7 @@ describe Projects::GroupLinksController do it 'redirects to project group links page' do expect(response).to redirect_to( - namespace_project_settings_members_path(project.namespace, project) + project_settings_members_path(project) ) expect(flash[:alert]).to eq('Please select a group.') end diff --git a/spec/controllers/projects/imports_controller_spec.rb b/spec/controllers/projects/imports_controller_spec.rb index 6724b474179..9be61342616 100644 --- a/spec/controllers/projects/imports_controller_spec.rb +++ b/spec/controllers/projects/imports_controller_spec.rb @@ -59,7 +59,7 @@ describe Projects::ImportsController do it 'redirects to new_namespace_project_import_path' do get :show, namespace_id: project.namespace.to_param, project_id: project - expect(response).to redirect_to new_namespace_project_import_path(project.namespace, project) + expect(response).to redirect_to new_project_import_path(project) end end @@ -75,7 +75,7 @@ describe Projects::ImportsController do get :show, namespace_id: project.namespace.to_param, project_id: project expect(flash[:notice]).to eq 'The project was successfully forked.' - expect(response).to redirect_to namespace_project_path(project.namespace, project) + expect(response).to redirect_to project_path(project) end end @@ -84,14 +84,14 @@ describe Projects::ImportsController do get :show, namespace_id: project.namespace.to_param, project_id: project expect(flash[:notice]).to eq 'The project was successfully imported.' - expect(response).to redirect_to namespace_project_path(project.namespace, project) + expect(response).to redirect_to project_path(project) end end context 'when continue params is present' do let(:params) do { - to: namespace_project_path(project.namespace, project), + to: project_path(project), notice: 'Finished' } end @@ -120,7 +120,7 @@ describe Projects::ImportsController do it 'redirects to namespace_project_path' do get :show, namespace_id: project.namespace.to_param, project_id: project - expect(response).to redirect_to namespace_project_path(project.namespace, project) + expect(response).to redirect_to project_path(project) end end end diff --git a/spec/controllers/projects/issues_controller_spec.rb b/spec/controllers/projects/issues_controller_spec.rb index 9f98427a86b..22aad0b3225 100644 --- a/spec/controllers/projects/issues_controller_spec.rb +++ b/spec/controllers/projects/issues_controller_spec.rb @@ -35,7 +35,7 @@ describe Projects::IssuesController do it "returns 301 if request path doesn't match project path" do get :index, namespace_id: project.namespace, project_id: project.path.upcase - expect(response).to redirect_to(namespace_project_issues_path(project.namespace, project)) + expect(response).to redirect_to(project_issues_path(project)) end it "returns 404 when issues are disabled" do @@ -329,7 +329,7 @@ describe Projects::IssuesController do update_verified_issue expect(response) - .to redirect_to(namespace_project_issue_path(project.namespace, project, issue)) + .to redirect_to(project_issue_path(project, issue)) end it 'accepts an issue after recaptcha is verified' do diff --git a/spec/controllers/projects/labels_controller_spec.rb b/spec/controllers/projects/labels_controller_spec.rb index bf1776eb320..f19ad4c2c81 100644 --- a/spec/controllers/projects/labels_controller_spec.rb +++ b/spec/controllers/projects/labels_controller_spec.rb @@ -178,7 +178,7 @@ describe Projects::LabelsController do it 'redirects to the correct casing' do get :index, namespace_id: project.namespace, project_id: project.to_param.upcase - expect(response).to redirect_to(namespace_project_labels_path(project.namespace, project)) + expect(response).to redirect_to(project_labels_path(project)) expect(controller).not_to set_flash[:notice] end end @@ -191,7 +191,7 @@ describe Projects::LabelsController do it 'redirects to the canonical path' do get :index, namespace_id: project.namespace, project_id: project.to_param + 'old' - expect(response).to redirect_to(namespace_project_labels_path(project.namespace, project)) + expect(response).to redirect_to(project_labels_path(project)) expect(controller).to set_flash[:notice].to(project_moved_message(redirect_route, project)) end end diff --git a/spec/controllers/projects/mattermosts_controller_spec.rb b/spec/controllers/projects/mattermosts_controller_spec.rb index 422a8b6fac0..12e413db902 100644 --- a/spec/controllers/projects/mattermosts_controller_spec.rb +++ b/spec/controllers/projects/mattermosts_controller_spec.rb @@ -38,7 +38,7 @@ describe Projects::MattermostsController do it 'shows the error' do allow_any_instance_of(MattermostSlashCommandsService).to receive(:configure).and_return([false, "error message"]) - expect(subject).to redirect_to(new_namespace_project_mattermost_url(project.namespace, project)) + expect(subject).to redirect_to(new_project_mattermost_url(project)) end end @@ -51,7 +51,7 @@ describe Projects::MattermostsController do subject service = project.services.last - expect(subject).to redirect_to(edit_namespace_project_service_url(project.namespace, project, service)) + expect(subject).to redirect_to(edit_project_service_url(project, service)) end end end diff --git a/spec/controllers/projects/pages_domains_controller_spec.rb b/spec/controllers/projects/pages_domains_controller_spec.rb index 33853c4b9d0..920189be381 100644 --- a/spec/controllers/projects/pages_domains_controller_spec.rb +++ b/spec/controllers/projects/pages_domains_controller_spec.rb @@ -46,7 +46,7 @@ describe Projects::PagesDomainsController do post(:create, request_params.merge(pages_domain: pages_domain_params)) end.to change { PagesDomain.count }.by(1) - expect(response).to redirect_to(namespace_project_pages_path(project.namespace, project)) + expect(response).to redirect_to(project_pages_path(project)) end end @@ -56,7 +56,7 @@ describe Projects::PagesDomainsController do delete(:destroy, request_params.merge(id: pages_domain.domain)) end.to change { PagesDomain.count }.by(-1) - expect(response).to redirect_to(namespace_project_pages_path(project.namespace, project)) + expect(response).to redirect_to(project_pages_path(project)) end end diff --git a/spec/controllers/projects/project_members_controller_spec.rb b/spec/controllers/projects/project_members_controller_spec.rb index f2b59ba82ca..548ec8f487f 100644 --- a/spec/controllers/projects/project_members_controller_spec.rb +++ b/spec/controllers/projects/project_members_controller_spec.rb @@ -9,7 +9,7 @@ describe Projects::ProjectMembersController do get :index, namespace_id: project.namespace, project_id: project expect(response).to have_http_status(302) - expect(response.location).to include namespace_project_settings_members_path(project.namespace, project) + expect(response.location).to include project_settings_members_path(project) end end @@ -50,7 +50,7 @@ describe Projects::ProjectMembersController do access_level: Gitlab::Access::GUEST expect(response).to set_flash.to 'Users were successfully added.' - expect(response).to redirect_to(namespace_project_settings_members_path(project.namespace, project)) + expect(response).to redirect_to(project_settings_members_path(project)) end it 'adds no user to members' do @@ -62,7 +62,7 @@ describe Projects::ProjectMembersController do access_level: Gitlab::Access::GUEST expect(response).to set_flash.to 'Message' - expect(response).to redirect_to(namespace_project_settings_members_path(project.namespace, project)) + expect(response).to redirect_to(project_settings_members_path(project)) end end end @@ -111,7 +111,7 @@ describe Projects::ProjectMembersController do id: member expect(response).to redirect_to( - namespace_project_settings_members_path(project.namespace, project) + project_settings_members_path(project) ) expect(project.members).not_to include member end @@ -183,7 +183,7 @@ describe Projects::ProjectMembersController do project_id: project expect(response).to set_flash.to 'Your access request to the project has been withdrawn.' - expect(response).to redirect_to(namespace_project_path(project.namespace, project)) + expect(response).to redirect_to(project_path(project)) expect(project.requesters).to be_empty expect(project.users).not_to include user end @@ -202,7 +202,7 @@ describe Projects::ProjectMembersController do expect(response).to set_flash.to 'Your request for access has been queued for review.' expect(response).to redirect_to( - namespace_project_path(project.namespace, project) + project_path(project) ) expect(project.requesters.exists?(user_id: user)).to be_truthy expect(project.users).not_to include user @@ -253,7 +253,7 @@ describe Projects::ProjectMembersController do id: member expect(response).to redirect_to( - namespace_project_settings_members_path(project.namespace, project) + project_settings_members_path(project) ) expect(project.members).to include member end @@ -290,7 +290,7 @@ describe Projects::ProjectMembersController do expect(project.team_members).to include member expect(response).to set_flash.to 'Successfully imported' expect(response).to redirect_to( - namespace_project_settings_members_path(project.namespace, project) + project_settings_members_path(project) ) end end diff --git a/spec/controllers/projects/services_controller_spec.rb b/spec/controllers/projects/services_controller_spec.rb index 4dc227a36d4..5a9d8a75f3e 100644 --- a/spec/controllers/projects/services_controller_spec.rb +++ b/spec/controllers/projects/services_controller_spec.rb @@ -79,7 +79,7 @@ describe Projects::ServicesController do put :update, namespace_id: project.namespace.id, project_id: project.id, id: service.id, service: { active: true } - expect(response).to redirect_to(namespace_project_settings_integrations_path(project.namespace, project)) + expect(response).to redirect_to(project_settings_integrations_path(project)) expect(flash[:notice]).to eq 'HipChat activated.' end end diff --git a/spec/controllers/projects/snippets_controller_spec.rb b/spec/controllers/projects/snippets_controller_spec.rb index ec0b7f8c967..cc444f31797 100644 --- a/spec/controllers/projects/snippets_controller_spec.rb +++ b/spec/controllers/projects/snippets_controller_spec.rb @@ -148,7 +148,7 @@ describe Projects::SnippetsController do { spam_log_id: spam_logs.last.id, recaptcha_verification: true }) - expect(response).to redirect_to(Snippet.last) + expect(response).to redirect_to(project_snippet_path(project, Snippet.last)) end end end @@ -228,7 +228,7 @@ describe Projects::SnippetsController do { spam_log_id: spam_logs.last.id, recaptcha_verification: true }) - expect(response).to redirect_to(snippet) + expect(response).to redirect_to(project_snippet_path(project, snippet)) end end end @@ -273,7 +273,7 @@ describe Projects::SnippetsController do { spam_log_id: spam_logs.last.id, recaptcha_verification: true }) - expect(response).to redirect_to(snippet) + expect(response).to redirect_to(project_snippet_path(project, snippet)) end end end diff --git a/spec/controllers/projects/variables_controller_spec.rb b/spec/controllers/projects/variables_controller_spec.rb index 1ecfe48475c..a0ecc756653 100644 --- a/spec/controllers/projects/variables_controller_spec.rb +++ b/spec/controllers/projects/variables_controller_spec.rb @@ -16,7 +16,7 @@ describe Projects::VariablesController do variable: { key: "one", value: "two" } expect(flash[:notice]).to include 'Variables were successfully updated.' - expect(response).to redirect_to(namespace_project_settings_ci_cd_path(project.namespace, project)) + expect(response).to redirect_to(project_settings_ci_cd_path(project)) end end @@ -44,7 +44,7 @@ describe Projects::VariablesController do id: variable.id, variable: { key: variable.key, value: 'two' } expect(flash[:notice]).to include 'Variable was successfully updated.' - expect(response).to redirect_to(namespace_project_variables_path(project.namespace, project)) + expect(response).to redirect_to(project_variables_path(project)) end it 'renders the action #show if the variable key is invalid' do diff --git a/spec/controllers/projects_controller_spec.rb b/spec/controllers/projects_controller_spec.rb index 240a81367d0..f96fe7ad5cb 100644 --- a/spec/controllers/projects_controller_spec.rb +++ b/spec/controllers/projects_controller_spec.rb @@ -482,7 +482,7 @@ describe ProjectsController do it 'redirects to the canonical path (testing non-show action)' do get :refs, namespace_id: 'foo', id: 'bar' - expect(response).to redirect_to(refs_namespace_project_path(namespace_id: public_project.namespace, id: public_project)) + expect(response).to redirect_to(refs_project_path(public_project)) expect(controller).to set_flash[:notice].to(project_moved_message(redirect_route, public_project)) end end diff --git a/spec/controllers/sent_notifications_controller_spec.rb b/spec/controllers/sent_notifications_controller_spec.rb index 917bd44c91b..7340a4e16c0 100644 --- a/spec/controllers/sent_notifications_controller_spec.rb +++ b/spec/controllers/sent_notifications_controller_spec.rb @@ -88,7 +88,7 @@ describe SentNotificationsController, type: :controller do it 'redirects to the issue page' do expect(response) - .to redirect_to(namespace_project_issue_path(project.namespace, project, issue)) + .to redirect_to(project_issue_path(project, issue)) end end @@ -114,7 +114,7 @@ describe SentNotificationsController, type: :controller do it 'redirects to the merge request page' do expect(response) - .to redirect_to(namespace_project_merge_request_path(project.namespace, project, merge_request)) + .to redirect_to(project_merge_request_path(project, merge_request)) end end end diff --git a/spec/controllers/snippets_controller_spec.rb b/spec/controllers/snippets_controller_spec.rb index 430d1208cd1..15416a89017 100644 --- a/spec/controllers/snippets_controller_spec.rb +++ b/spec/controllers/snippets_controller_spec.rb @@ -341,7 +341,7 @@ describe SnippetsController do { spam_log_id: spam_logs.last.id, recaptcha_verification: true }) - expect(response).to redirect_to(snippet) + expect(response).to redirect_to(snippet_path(snippet)) end end end diff --git a/spec/factories/ci/builds.rb b/spec/factories/ci/builds.rb index 0cc498f0ce9..a77f01ecb00 100644 --- a/spec/factories/ci/builds.rb +++ b/spec/factories/ci/builds.rb @@ -207,7 +207,8 @@ FactoryGirl.define do cache: { key: 'cache_key', untracked: false, - paths: ['vendor/*'] + paths: ['vendor/*'], + policy: 'pull-push' } } end diff --git a/spec/factories/ci/runner_projects.rb b/spec/factories/ci/runner_projects.rb index 6712dd5d82e..33a17cf7ed5 100644 --- a/spec/factories/ci/runner_projects.rb +++ b/spec/factories/ci/runner_projects.rb @@ -1,6 +1,6 @@ FactoryGirl.define do factory :ci_runner_project, class: Ci::RunnerProject do - runner_id 1 - project_id 1 + runner factory: :ci_runner + project factory: :empty_project end end diff --git a/spec/factories/personal_snippets.rb b/spec/factories/personal_snippets.rb deleted file mode 100644 index 0f13b2c1020..00000000000 --- a/spec/factories/personal_snippets.rb +++ /dev/null @@ -1,4 +0,0 @@ -FactoryGirl.define do - factory :personal_snippet, parent: :snippet, class: :PersonalSnippet do - end -end diff --git a/spec/factories/project_snippets.rb b/spec/factories/project_snippets.rb deleted file mode 100644 index e0fe1b36fd3..00000000000 --- a/spec/factories/project_snippets.rb +++ /dev/null @@ -1,5 +0,0 @@ -FactoryGirl.define do - factory :project_snippet, parent: :snippet, class: :ProjectSnippet do - project factory: :empty_project - end -end diff --git a/spec/factories/snippets.rb b/spec/factories/snippets.rb index 388f662e6e5..f6ce99d50f9 100644 --- a/spec/factories/snippets.rb +++ b/spec/factories/snippets.rb @@ -18,4 +18,11 @@ FactoryGirl.define do visibility_level Snippet::PRIVATE end end + + factory :project_snippet, parent: :snippet, class: :ProjectSnippet do + project factory: :empty_project + end + + factory :personal_snippet, parent: :snippet, class: :PersonalSnippet do + end end diff --git a/spec/features/admin/admin_disables_git_access_protocol_spec.rb b/spec/features/admin/admin_disables_git_access_protocol_spec.rb index 679bf63e0fd..063d54270bd 100644 --- a/spec/features/admin/admin_disables_git_access_protocol_spec.rb +++ b/spec/features/admin/admin_disables_git_access_protocol_spec.rb @@ -51,7 +51,7 @@ feature 'Admin disables Git access protocol', feature: true do end def visit_project - visit namespace_project_path(project.namespace, project) + visit project_path(project) end def disable_http_protocol diff --git a/spec/features/admin/admin_projects_spec.rb b/spec/features/admin/admin_projects_spec.rb index a4ce3e1d5ee..c6488cea798 100644 --- a/spec/features/admin/admin_projects_spec.rb +++ b/spec/features/admin/admin_projects_spec.rb @@ -42,7 +42,7 @@ describe "Admin::Projects", feature: true do end it do - expect(current_path).to eq admin_namespace_project_path(project.namespace, project) + expect(current_path).to eq admin_project_path(project) end it "has project info" do @@ -62,7 +62,7 @@ describe "Admin::Projects", feature: true do end it 'transfers project to group web', js: true do - visit admin_namespace_project_path(project.namespace, project) + visit admin_project_path(project) click_button 'Search for Namespace' click_link 'group: web' @@ -79,7 +79,7 @@ describe "Admin::Projects", feature: true do end it 'adds admin a to a project as developer', js: true do - visit namespace_project_project_members_path(project.namespace, project) + visit project_project_members_path(project) page.within '.users-project-form' do select2(current_user.id, from: '#user_ids', multiple: true) @@ -102,7 +102,7 @@ describe "Admin::Projects", feature: true do end it 'removes admin from the project' do - visit namespace_project_project_members_path(project.namespace, project) + visit project_project_members_path(project) page.within '.content-list' do expect(page).to have_content(current_user.name) diff --git a/spec/features/admin/admin_settings_spec.rb b/spec/features/admin/admin_settings_spec.rb index 2d6565e6d3b..59a50ff9264 100644 --- a/spec/features/admin/admin_settings_spec.rb +++ b/spec/features/admin/admin_settings_spec.rb @@ -16,6 +16,19 @@ feature 'Admin updates settings', feature: true do expect(page).to have_content "Application settings saved successfully" end + scenario 'Uncheck all restricted visibility levels' do + find('#application_setting_visibility_level_0').set(false) + find('#application_setting_visibility_level_10').set(false) + find('#application_setting_visibility_level_20').set(false) + + click_button 'Save' + + expect(page).to have_content "Application settings saved successfully" + expect(find('#application_setting_visibility_level_0')).not_to be_checked + expect(find('#application_setting_visibility_level_10')).not_to be_checked + expect(find('#application_setting_visibility_level_20')).not_to be_checked + end + scenario 'Change application settings' do uncheck 'Gravatar enabled' fill_in 'Home page URL', with: 'https://about.gitlab.com/' diff --git a/spec/features/admin/admin_uses_repository_checks_spec.rb b/spec/features/admin/admin_uses_repository_checks_spec.rb index 91d70435db8..5be0e2b2f17 100644 --- a/spec/features/admin/admin_uses_repository_checks_spec.rb +++ b/spec/features/admin/admin_uses_repository_checks_spec.rb @@ -43,6 +43,6 @@ feature 'Admin uses repository checks', feature: true do end def visit_admin_project_page(project) - visit admin_namespace_project_path(project.namespace, project) + visit admin_project_path(project) end end diff --git a/spec/features/atom/issues_spec.rb b/spec/features/atom/issues_spec.rb index b94ad973fed..f7d170a7bf6 100644 --- a/spec/features/atom/issues_spec.rb +++ b/spec/features/atom/issues_spec.rb @@ -16,7 +16,7 @@ describe 'Issues Feed', feature: true do context 'when authenticated' do it 'renders atom feed' do gitlab_sign_in user - visit namespace_project_issues_path(project.namespace, project, :atom) + visit project_issues_path(project, :atom) expect(response_headers['Content-Type']) .to have_content('application/atom+xml') @@ -30,7 +30,7 @@ describe 'Issues Feed', feature: true do context 'when authenticated via private token' do it 'renders atom feed' do - visit namespace_project_issues_path(project.namespace, project, :atom, + visit project_issues_path(project, :atom, private_token: user.private_token) expect(response_headers['Content-Type']) @@ -45,7 +45,7 @@ describe 'Issues Feed', feature: true do context 'when authenticated via RSS token' do it 'renders atom feed' do - visit namespace_project_issues_path(project.namespace, project, :atom, + visit project_issues_path(project, :atom, rss_token: user.rss_token) expect(response_headers['Content-Type']) @@ -59,7 +59,7 @@ describe 'Issues Feed', feature: true do end it "renders atom feed with url parameters for project issues" do - visit namespace_project_issues_path(project.namespace, project, + visit project_issues_path(project, :atom, rss_token: user.rss_token, state: 'opened', assignee_id: user.id) link = find('link[type="application/atom+xml"]') diff --git a/spec/features/auto_deploy_spec.rb b/spec/features/auto_deploy_spec.rb index 74f5f70702a..3536d59bb08 100644 --- a/spec/features/auto_deploy_spec.rb +++ b/spec/features/auto_deploy_spec.rb @@ -16,7 +16,7 @@ describe 'Auto deploy' do end it 'does not show a button to set up auto deploy' do - visit namespace_project_path(project.namespace, project) + visit project_path(project) expect(page).to have_no_content('Set up auto deploy') end end @@ -24,7 +24,7 @@ describe 'Auto deploy' do context 'when a deployment service is active' do before do project.kubernetes_service.update!(active: true) - visit namespace_project_path(project.namespace, project) + visit project_path(project) end it 'shows a button to set up auto deploy' do diff --git a/spec/features/boards/add_issues_modal_spec.rb b/spec/features/boards/add_issues_modal_spec.rb index ba58af22841..eeb63f3f81a 100644 --- a/spec/features/boards/add_issues_modal_spec.rb +++ b/spec/features/boards/add_issues_modal_spec.rb @@ -16,12 +16,12 @@ describe 'Issue Boards add issue modal', :feature, :js do gitlab_sign_in(user) - visit namespace_project_board_path(project.namespace, project, board) + visit project_board_path(project, board) wait_for_requests end it 'resets filtered search state' do - visit namespace_project_board_path(project.namespace, project, board, search: 'testing') + visit project_board_path(project, board, search: 'testing') wait_for_requests diff --git a/spec/features/boards/boards_spec.rb b/spec/features/boards/boards_spec.rb index 87fc31d414c..1f697581179 100644 --- a/spec/features/boards/boards_spec.rb +++ b/spec/features/boards/boards_spec.rb @@ -17,7 +17,7 @@ describe 'Issue Boards', feature: true, js: true do context 'no lists' do before do - visit namespace_project_board_path(project.namespace, project, board) + visit project_board_path(project, board) wait_for_requests expect(page).to have_selector('.board', count: 3) end @@ -81,7 +81,7 @@ describe 'Issue Boards', feature: true, js: true do let!(:issue9) { create(:labeled_issue, project: project, labels: [planning, testing, bug, accepting], relative_position: 1) } before do - visit namespace_project_board_path(project.namespace, project, board) + visit project_board_path(project, board) wait_for_requests @@ -158,7 +158,7 @@ describe 'Issue Boards', feature: true, js: true do create(:labeled_issue, project: project, labels: [planning]) end - visit namespace_project_board_path(project.namespace, project, board) + visit project_board_path(project, board) wait_for_requests page.within(find('.board:nth-child(2)')) do @@ -507,7 +507,7 @@ describe 'Issue Boards', feature: true, js: true do context 'keyboard shortcuts' do before do - visit namespace_project_board_path(project.namespace, project, board) + visit project_board_path(project, board) wait_for_requests end @@ -520,7 +520,7 @@ describe 'Issue Boards', feature: true, js: true do context 'signed out user' do before do gitlab_sign_out - visit namespace_project_board_path(project.namespace, project, board) + visit project_board_path(project, board) wait_for_requests end @@ -544,7 +544,7 @@ describe 'Issue Boards', feature: true, js: true do project.team << [user_guest, :guest] gitlab_sign_out gitlab_sign_in(user_guest) - visit namespace_project_board_path(project.namespace, project, board) + visit project_board_path(project, board) wait_for_requests end diff --git a/spec/features/boards/issue_ordering_spec.rb b/spec/features/boards/issue_ordering_spec.rb index 1e620061e5e..62693fb3d11 100644 --- a/spec/features/boards/issue_ordering_spec.rb +++ b/spec/features/boards/issue_ordering_spec.rb @@ -22,7 +22,7 @@ describe 'Issue Boards', :feature, :js do let!(:issue4) { create(:labeled_issue, project: project, labels: [label]) } before do - visit namespace_project_board_path(project.namespace, project, board) + visit project_board_path(project, board) wait_for_requests expect(page).to have_selector('.board', count: 3) @@ -47,7 +47,7 @@ describe 'Issue Boards', :feature, :js do context 'ordering in list' do before do - visit namespace_project_board_path(project.namespace, project, board) + visit project_board_path(project, board) wait_for_requests expect(page).to have_selector('.board', count: 3) @@ -110,7 +110,7 @@ describe 'Issue Boards', :feature, :js do let!(:issue6) { create(:labeled_issue, project: project, title: 'testing 3', labels: [label2], relative_position: 1.0) } before do - visit namespace_project_board_path(project.namespace, project, board) + visit project_board_path(project, board) wait_for_requests expect(page).to have_selector('.board', count: 4) diff --git a/spec/features/boards/keyboard_shortcut_spec.rb b/spec/features/boards/keyboard_shortcut_spec.rb index ed3b38e6a7e..34ae6c9d81d 100644 --- a/spec/features/boards/keyboard_shortcut_spec.rb +++ b/spec/features/boards/keyboard_shortcut_spec.rb @@ -8,7 +8,7 @@ describe 'Issue Boards shortcut', feature: true, js: true do gitlab_sign_in :admin - visit namespace_project_path(project.namespace, project) + visit project_path(project) end it 'takes user to issue board index' do diff --git a/spec/features/boards/modal_filter_spec.rb b/spec/features/boards/modal_filter_spec.rb index 8899e1ef5e5..40d1191a597 100644 --- a/spec/features/boards/modal_filter_spec.rb +++ b/spec/features/boards/modal_filter_spec.rb @@ -202,7 +202,7 @@ describe 'Issue Boards add issue modal filtering', :feature, :js do end def visit_board - visit namespace_project_board_path(project.namespace, project, board) + visit project_board_path(project, board) wait_for_requests click_button('Add issues') diff --git a/spec/features/boards/new_issue_spec.rb b/spec/features/boards/new_issue_spec.rb index 77cd87d6601..fa9d8b3f33d 100644 --- a/spec/features/boards/new_issue_spec.rb +++ b/spec/features/boards/new_issue_spec.rb @@ -12,7 +12,7 @@ describe 'Issue Boards new issue', feature: true, js: true do gitlab_sign_in(user) - visit namespace_project_board_path(project.namespace, project, board) + visit project_board_path(project, board) wait_for_requests expect(page).to have_selector('.board', count: 3) @@ -83,7 +83,7 @@ describe 'Issue Boards new issue', feature: true, js: true do context 'unauthorized user' do before do - visit namespace_project_board_path(project.namespace, project, board) + visit project_board_path(project, board) wait_for_requests end diff --git a/spec/features/boards/sidebar_spec.rb b/spec/features/boards/sidebar_spec.rb index 1c9595def21..f96ceffbc7d 100644 --- a/spec/features/boards/sidebar_spec.rb +++ b/spec/features/boards/sidebar_spec.rb @@ -22,7 +22,7 @@ describe 'Issue Boards', feature: true, js: true do gitlab_sign_in(user) - visit namespace_project_board_path(project.namespace, project, board) + visit project_board_path(project, board) wait_for_requests end @@ -83,7 +83,7 @@ describe 'Issue Boards', feature: true, js: true do create(:issue, project: project) create(:issue, :closed, project: project) - visit namespace_project_board_path(project.namespace, project, board) + visit project_board_path(project, board) wait_for_requests click_card(find('.board:nth-child(1)').first('.card')) diff --git a/spec/features/boards/sub_group_project_spec.rb b/spec/features/boards/sub_group_project_spec.rb index d57ae6a71e7..ddff4737563 100644 --- a/spec/features/boards/sub_group_project_spec.rb +++ b/spec/features/boards/sub_group_project_spec.rb @@ -15,7 +15,7 @@ describe 'Sub-group project issue boards', :feature, :js do gitlab_sign_in(user) - visit namespace_project_board_path(project.namespace, project, board) + visit project_board_path(project, board) wait_for_requests end diff --git a/spec/features/commits_spec.rb b/spec/features/commits_spec.rb index 0373f649ee8..fb1e47994ef 100644 --- a/spec/features/commits_spec.rb +++ b/spec/features/commits_spec.rb @@ -66,7 +66,7 @@ describe 'Commits' do end before do - visit namespace_project_commits_path(project.namespace, project, :master) + visit project_commits_path(project, :master) end it 'shows correct build status from default branch' do @@ -192,7 +192,7 @@ describe 'Commits' do before do project.team << [user, :master] sign_in(user) - visit namespace_project_commits_path(project.namespace, project, branch_name) + visit project_commits_path(project, branch_name) end it 'includes the committed_date for each commit' do diff --git a/spec/features/container_registry_spec.rb b/spec/features/container_registry_spec.rb index 80d16539d5a..55ef1ef29bd 100644 --- a/spec/features/container_registry_spec.rb +++ b/spec/features/container_registry_spec.rb @@ -55,7 +55,6 @@ describe "Container Registry" do end def visit_container_registry - visit namespace_project_container_registry_index_path( - project.namespace, project) + visit project_container_registry_index_path(project) end end diff --git a/spec/features/copy_as_gfm_spec.rb b/spec/features/copy_as_gfm_spec.rb index 005c88f6bab..25c5df56d57 100644 --- a/spec/features/copy_as_gfm_spec.rb +++ b/spec/features/copy_as_gfm_spec.rb @@ -16,7 +16,7 @@ describe 'Copy as GFM', feature: true, js: true do # `markdown` helper expects a `@project` variable @project = @feat.project - visit namespace_project_issue_path(@project.namespace, @project, @feat.issue) + visit project_issue_path(@project, @feat.issue) end # The filters referenced in lib/banzai/pipeline/gfm_pipeline.rb convert GitLab Flavored Markdown (GFM) to HTML. @@ -121,13 +121,13 @@ describe 'Copy as GFM', feature: true, js: true do # full issue reference @feat.issue.to_reference(full: true), # issue URL - namespace_project_issue_url(@project.namespace, @project, @feat.issue), + project_issue_url(@project, @feat.issue), # issue URL with note anchor - namespace_project_issue_url(@project.namespace, @project, @feat.issue, anchor: 'note_123'), + project_issue_url(@project, @feat.issue, anchor: 'note_123'), # issue link - "[Issue](#{namespace_project_issue_url(@project.namespace, @project, @feat.issue)})", + "[Issue](#{project_issue_url(@project, @feat.issue)})", # issue link with note anchor - "[Issue](#{namespace_project_issue_url(@project.namespace, @project, @feat.issue, anchor: 'note_123')})" + "[Issue](#{project_issue_url(@project, @feat.issue, anchor: 'note_123')})" ) verify( @@ -466,7 +466,7 @@ describe 'Copy as GFM', feature: true, js: true do context 'from a diff' do before do - visit namespace_project_commit_path(project.namespace, project, sample_commit.id) + visit project_commit_path(project, sample_commit.id) end context 'selecting one word of text' do @@ -507,7 +507,7 @@ describe 'Copy as GFM', feature: true, js: true do context 'from a blob' do before do - visit namespace_project_blob_path(project.namespace, project, File.join('master', 'files/ruby/popen.rb')) + visit project_blob_path(project, File.join('master', 'files/ruby/popen.rb')) wait_for_requests end @@ -549,7 +549,7 @@ describe 'Copy as GFM', feature: true, js: true do context 'from a GFM code block' do before do - visit namespace_project_blob_path(project.namespace, project, File.join('markdown', 'doc/api/users.md')) + visit project_blob_path(project, File.join('markdown', 'doc/api/users.md')) wait_for_requests end diff --git a/spec/features/cycle_analytics_spec.rb b/spec/features/cycle_analytics_spec.rb index 5a7ea975455..7825d23c8f9 100644 --- a/spec/features/cycle_analytics_spec.rb +++ b/spec/features/cycle_analytics_spec.rb @@ -16,7 +16,7 @@ feature 'Cycle Analytics', feature: true, js: true do gitlab_sign_in(user) - visit namespace_project_cycle_analytics_path(project.namespace, project) + visit project_cycle_analytics_path(project) wait_for_requests end @@ -39,7 +39,7 @@ feature 'Cycle Analytics', feature: true, js: true do deploy_master gitlab_sign_in(user) - visit namespace_project_cycle_analytics_path(project.namespace, project) + visit project_cycle_analytics_path(project) end it 'shows data on each stage' do @@ -71,7 +71,7 @@ feature 'Cycle Analytics', feature: true, js: true do project.team << [user, :master] gitlab_sign_in(user) - visit namespace_project_cycle_analytics_path(project.namespace, project) + visit project_cycle_analytics_path(project) wait_for_requests end @@ -94,7 +94,7 @@ feature 'Cycle Analytics', feature: true, js: true do deploy_master gitlab_sign_in(guest) - visit namespace_project_cycle_analytics_path(project.namespace, project) + visit project_cycle_analytics_path(project) wait_for_requests end diff --git a/spec/features/dashboard/project_member_activity_index_spec.rb b/spec/features/dashboard/project_member_activity_index_spec.rb index 0ba87d921d0..ea0b2e99c3e 100644 --- a/spec/features/dashboard/project_member_activity_index_spec.rb +++ b/spec/features/dashboard/project_member_activity_index_spec.rb @@ -10,7 +10,7 @@ feature 'Project member activity', feature: true, js: true do def visit_activities_and_wait_with_event(event_type) Event.create(project: project, author_id: user.id, action: event_type) - visit activity_namespace_project_path(project.namespace, project) + visit activity_project_path(project) wait_for_requests end diff --git a/spec/features/dashboard/projects_spec.rb b/spec/features/dashboard/projects_spec.rb index f29186f368d..7d1fe2bd435 100644 --- a/spec/features/dashboard/projects_spec.rb +++ b/spec/features/dashboard/projects_spec.rb @@ -1,8 +1,8 @@ require 'spec_helper' -RSpec.describe 'Dashboard Projects', feature: true do +feature 'Dashboard Projects' do let(:user) { create(:user) } - let(:project) { create(:project, name: "awesome stuff") } + let(:project) { create(:project, name: 'awesome stuff') } let(:project2) { create(:project, :public, name: 'Community project') } before do @@ -15,6 +15,14 @@ RSpec.describe 'Dashboard Projects', feature: true do expect(page).to have_content('awesome stuff') end + it 'shows "New project" button' do + visit dashboard_projects_path + + page.within '#content-body' do + expect(page).to have_link('New project') + end + end + context 'when last_repository_updated_at, last_activity_at and update_at are present' do it 'shows the last_repository_updated_at attribute as the update date' do project.update_attributes!(last_repository_updated_at: Time.now, last_activity_at: 1.hour.ago) @@ -47,8 +55,8 @@ RSpec.describe 'Dashboard Projects', feature: true do end end - describe "with a pipeline", redis: true do - let!(:pipeline) { create(:ci_pipeline, project: project, sha: project.commit.sha) } + describe 'with a pipeline', redis: true do + let(:pipeline) { create(:ci_pipeline, project: project, sha: project.commit.sha) } before do # Since the cache isn't updated when a new pipeline is created @@ -60,7 +68,7 @@ RSpec.describe 'Dashboard Projects', feature: true do it 'shows that the last pipeline passed' do visit dashboard_projects_path - expect(page).to have_xpath("//a[@href='#{pipelines_namespace_project_commit_path(project.namespace, project, project.commit)}']") + expect(page).to have_xpath("//a[@href='#{pipelines_project_commit_path(project, project.commit)}']") end end diff --git a/spec/features/dashboard/todos/todos_spec.rb b/spec/features/dashboard/todos/todos_spec.rb index 7fa4d198e00..30bab7eeaa7 100644 --- a/spec/features/dashboard/todos/todos_spec.rb +++ b/spec/features/dashboard/todos/todos_spec.rb @@ -330,7 +330,7 @@ feature 'Dashboard Todos' do end it 'links to the pipelines for the merge request' do - href = pipelines_namespace_project_merge_request_path(project.namespace, project, todo.target) + href = pipelines_project_merge_request_path(project, todo.target) expect(page).to have_link "merge request #{todo.target.to_reference(full: true)}", href end diff --git a/spec/features/discussion_comments/commit_spec.rb b/spec/features/discussion_comments/commit_spec.rb index 96128061e4d..620184e2933 100644 --- a/spec/features/discussion_comments/commit_spec.rb +++ b/spec/features/discussion_comments/commit_spec.rb @@ -11,7 +11,7 @@ describe 'Discussion Comments Merge Request', :feature, :js do project.add_master(user) gitlab_sign_in(user) - visit namespace_project_commit_path(project.namespace, project, sample_commit.id) + visit project_commit_path(project, sample_commit.id) end it_behaves_like 'discussion comments', 'commit' diff --git a/spec/features/discussion_comments/issue_spec.rb b/spec/features/discussion_comments/issue_spec.rb index d7c1cd12fb5..f90f82f8a48 100644 --- a/spec/features/discussion_comments/issue_spec.rb +++ b/spec/features/discussion_comments/issue_spec.rb @@ -9,7 +9,7 @@ describe 'Discussion Comments Issue', :feature, :js do project.add_master(user) gitlab_sign_in(user) - visit namespace_project_issue_path(project.namespace, project, issue) + visit project_issue_path(project, issue) end it_behaves_like 'discussion comments', 'issue' diff --git a/spec/features/discussion_comments/merge_request_spec.rb b/spec/features/discussion_comments/merge_request_spec.rb index 31fb9c72d25..577d9c69bbc 100644 --- a/spec/features/discussion_comments/merge_request_spec.rb +++ b/spec/features/discussion_comments/merge_request_spec.rb @@ -9,7 +9,7 @@ describe 'Discussion Comments Merge Request', :feature, :js do project.add_master(user) gitlab_sign_in(user) - visit namespace_project_merge_request_path(project.namespace, project, merge_request) + visit project_merge_request_path(project, merge_request) end it_behaves_like 'discussion comments', 'merge request' diff --git a/spec/features/discussion_comments/snippets_spec.rb b/spec/features/discussion_comments/snippets_spec.rb index 998d633c83d..a59be88db7d 100644 --- a/spec/features/discussion_comments/snippets_spec.rb +++ b/spec/features/discussion_comments/snippets_spec.rb @@ -9,7 +9,7 @@ describe 'Discussion Comments Issue', :feature, :js do project.add_master(user) gitlab_sign_in(user) - visit namespace_project_snippet_path(project.namespace, project, snippet) + visit project_snippet_path(project, snippet) end it_behaves_like 'discussion comments', 'snippet' diff --git a/spec/features/expand_collapse_diffs_spec.rb b/spec/features/expand_collapse_diffs_spec.rb index d492a15ea17..f45752ab3f3 100644 --- a/spec/features/expand_collapse_diffs_spec.rb +++ b/spec/features/expand_collapse_diffs_spec.rb @@ -14,7 +14,7 @@ feature 'Expand and collapse diffs', js: true, feature: true do # Ensure that undiffable.md is in .gitattributes project.repository.copy_gitattributes(branch) - visit namespace_project_commit_path(project.namespace, project, project.commit(branch)) + visit project_commit_path(project, project.commit(branch)) execute_script('window.ajaxUris = []; $(document).ajaxSend(function(event, xhr, settings) { ajaxUris.push(settings.url) });') end @@ -38,7 +38,7 @@ feature 'Expand and collapse diffs', js: true, feature: true do expect(large_diff).not_to have_selector('.code') expect(large_diff).to have_selector('.nothing-here-block') - visit namespace_project_commit_path(project.namespace, project, project.commit(branch), anchor: "#{large_diff[:id]}_0_1") + visit project_commit_path(project, project.commit(branch), anchor: "#{large_diff[:id]}_0_1") execute_script('window.location.reload()') wait_for_requests @@ -52,7 +52,7 @@ feature 'Expand and collapse diffs', js: true, feature: true do expect(large_diff).not_to have_selector('.code') expect(large_diff).to have_selector('.nothing-here-block') - visit namespace_project_commit_path(project.namespace, project, project.commit(branch), anchor: large_diff[:id]) + visit project_commit_path(project, project.commit(branch), anchor: large_diff[:id]) execute_script('window.location.reload()') wait_for_requests diff --git a/spec/features/explore/new_menu_spec.rb b/spec/features/explore/new_menu_spec.rb index 2d7e703688f..5cd72e1d249 100644 --- a/spec/features/explore/new_menu_spec.rb +++ b/spec/features/explore/new_menu_spec.rb @@ -47,7 +47,7 @@ feature 'Top Plus Menu', feature: true, js: true do end scenario 'click on New issue shows new issue page' do - visit namespace_project_path(project.namespace, project) + visit project_path(project) click_topmenuitem("New issue") @@ -56,7 +56,7 @@ feature 'Top Plus Menu', feature: true, js: true do end scenario 'click on New merge request shows new merge request page' do - visit namespace_project_path(project.namespace, project) + visit project_path(project) click_topmenuitem("New merge request") @@ -66,7 +66,7 @@ feature 'Top Plus Menu', feature: true, js: true do end scenario 'click on New project snippet shows new snippet page' do - visit namespace_project_path(project.namespace, project) + visit project_path(project) page.within '.header-content' do find('.header-new-dropdown-toggle').trigger('click') @@ -107,7 +107,7 @@ feature 'Top Plus Menu', feature: true, js: true do end scenario 'click on New issue shows new issue page' do - visit namespace_project_path(project.namespace, project) + visit project_path(project) click_topmenuitem("New issue") @@ -116,31 +116,31 @@ feature 'Top Plus Menu', feature: true, js: true do end scenario 'has no New merge request menu item' do - visit namespace_project_path(project.namespace, project) + visit project_path(project) hasnot_topmenuitem("New merge request") end scenario 'has no New project snippet menu item' do - visit namespace_project_path(project.namespace, project) + visit project_path(project) expect(find('.header-new.dropdown')).not_to have_selector('.header-new-project-snippet') end scenario 'public project has no New Issue Button' do - visit namespace_project_path(public_project.namespace, public_project) + visit project_path(public_project) hasnot_topmenuitem("New issue") end scenario 'public project has no New merge request menu item' do - visit namespace_project_path(public_project.namespace, public_project) + visit project_path(public_project) hasnot_topmenuitem("New merge request") end scenario 'public project has no New project snippet menu item' do - visit namespace_project_path(public_project.namespace, public_project) + visit project_path(public_project) expect(find('.header-new.dropdown')).not_to have_selector('.header-new-project-snippet') end diff --git a/spec/features/gitlab_flavored_markdown_spec.rb b/spec/features/gitlab_flavored_markdown_spec.rb index 2d13af2a52a..8659a868682 100644 --- a/spec/features/gitlab_flavored_markdown_spec.rb +++ b/spec/features/gitlab_flavored_markdown_spec.rb @@ -25,25 +25,25 @@ describe "GitLab Flavored Markdown", feature: true do end it "renders title in commits#index" do - visit namespace_project_commits_path(project.namespace, project, 'master', limit: 1) + visit project_commits_path(project, 'master', limit: 1) expect(page).to have_link(issue.to_reference) end it "renders title in commits#show" do - visit namespace_project_commit_path(project.namespace, project, commit) + visit project_commit_path(project, commit) expect(page).to have_link(issue.to_reference) end it "renders description in commits#show" do - visit namespace_project_commit_path(project.namespace, project, commit) + visit project_commit_path(project, commit) expect(page).to have_link(fred.to_reference) end it "renders title in repositories#branches" do - visit namespace_project_branches_path(project.namespace, project) + visit project_branches_path(project) expect(page).to have_link(issue.to_reference) end @@ -66,19 +66,19 @@ describe "GitLab Flavored Markdown", feature: true do end it "renders subject in issues#index" do - visit namespace_project_issues_path(project.namespace, project) + visit project_issues_path(project) expect(page).to have_link(@other_issue.to_reference) end it "renders subject in issues#show" do - visit namespace_project_issue_path(project.namespace, project, @issue) + visit project_issue_path(project, @issue) expect(page).to have_link(@other_issue.to_reference) end it "renders details in issues#show" do - visit namespace_project_issue_path(project.namespace, project, @issue) + visit project_issue_path(project, @issue) expect(page).to have_link(fred.to_reference) end @@ -92,13 +92,13 @@ describe "GitLab Flavored Markdown", feature: true do end it "renders title in merge_requests#index" do - visit namespace_project_merge_requests_path(project.namespace, project) + visit project_merge_requests_path(project) expect(page).to have_link(issue.to_reference) end it "renders title in merge_requests#show" do - visit namespace_project_merge_request_path(project.namespace, project, @merge_request) + visit project_merge_request_path(project, @merge_request) expect(page).to have_link(issue.to_reference) end @@ -113,19 +113,19 @@ describe "GitLab Flavored Markdown", feature: true do end it "renders title in milestones#index" do - visit namespace_project_milestones_path(project.namespace, project) + visit project_milestones_path(project) expect(page).to have_link(issue.to_reference) end it "renders title in milestones#show" do - visit namespace_project_milestone_path(project.namespace, project, @milestone) + visit project_milestone_path(project, @milestone) expect(page).to have_link(issue.to_reference) end it "renders description in milestones#show" do - visit namespace_project_milestone_path(project.namespace, project, @milestone) + visit project_milestone_path(project, @milestone) expect(page).to have_link(fred.to_reference) end diff --git a/spec/features/groups_spec.rb b/spec/features/groups_spec.rb index ecacca00a61..c1dc7be7088 100644 --- a/spec/features/groups_spec.rb +++ b/spec/features/groups_spec.rb @@ -135,7 +135,7 @@ feature 'Group', feature: true do expect(page).not_to have_content('secret-group') end - describe 'group edit' do + describe 'group edit', js: true do let(:group) { create(:group) } let(:path) { edit_group_path(group) } let(:new_name) { 'new-name' } @@ -157,8 +157,8 @@ feature 'Group', feature: true do end it 'removes group' do - click_link 'Remove group' - + expect { remove_with_confirm('Remove group', group.path) }.to change {Group.count}.by(-1) + expect(group.members.all.count).to be_zero expect(page).to have_content "scheduled for deletion" end end @@ -212,4 +212,10 @@ feature 'Group', feature: true do expect(page).to have_content(nested_group.name) end end + + def remove_with_confirm(button_text, confirm_with) + click_button button_text + fill_in 'confirm_name_input', with: confirm_with + click_button 'Confirm' + end end diff --git a/spec/features/issuables/issuable_list_spec.rb b/spec/features/issuables/issuable_list_spec.rb index f3a5a8463d1..5046bfb5949 100644 --- a/spec/features/issuables/issuable_list_spec.rb +++ b/spec/features/issuables/issuable_list_spec.rb @@ -39,9 +39,9 @@ describe 'issuable list', feature: true do def visit_issuable_list(issuable_type) if issuable_type == :issue - visit namespace_project_issues_path(project.namespace, project) + visit project_issues_path(project) else - visit namespace_project_merge_requests_path(project.namespace, project) + visit project_merge_requests_path(project) end end diff --git a/spec/features/issuables/user_sees_sidebar_spec.rb b/spec/features/issuables/user_sees_sidebar_spec.rb index 4d7a7dc1806..948d151a517 100644 --- a/spec/features/issuables/user_sees_sidebar_spec.rb +++ b/spec/features/issuables/user_sees_sidebar_spec.rb @@ -14,7 +14,7 @@ describe 'Issue Sidebar on Mobile' do context 'mobile sidebar on merge requests', js: true do before do - visit namespace_project_merge_request_path(merge_request.project.namespace, merge_request.project, merge_request) + visit project_merge_request_path(merge_request.project, merge_request) end it_behaves_like "issue sidebar stays collapsed on mobile" @@ -22,7 +22,7 @@ describe 'Issue Sidebar on Mobile' do context 'mobile sidebar on issues', js: true do before do - visit namespace_project_issue_path(project.namespace, project, issue) + visit project_issue_path(project, issue) end it_behaves_like "issue sidebar stays collapsed on mobile" diff --git a/spec/features/issues/award_emoji_spec.rb b/spec/features/issues/award_emoji_spec.rb index 6698e2c79a1..2c84965f7f3 100644 --- a/spec/features/issues/award_emoji_spec.rb +++ b/spec/features/issues/award_emoji_spec.rb @@ -19,7 +19,7 @@ describe 'Awards Emoji', feature: true do before do # The `heart_tip` emoji is not valid anymore so we need to skip validation issue.award_emoji.build(user: user, name: 'heart_tip').save!(validate: false) - visit namespace_project_issue_path(project.namespace, project, issue) + visit project_issue_path(project, issue) wait_for_requests end @@ -33,7 +33,7 @@ describe 'Awards Emoji', feature: true do let!(:note) { create(:note_on_issue, noteable: issue, project: issue.project, note: "Hello world") } before do - visit namespace_project_issue_path(project.namespace, project, issue) + visit project_issue_path(project, issue) wait_for_requests end @@ -97,7 +97,7 @@ describe 'Awards Emoji', feature: true do context 'unauthorized user', js: true do before do - visit namespace_project_issue_path(project.namespace, project, issue) + visit project_issue_path(project, issue) end it 'has disabled emoji button' do diff --git a/spec/features/issues/award_spec.rb b/spec/features/issues/award_spec.rb index a1c97caea20..62c5fce81b6 100644 --- a/spec/features/issues/award_spec.rb +++ b/spec/features/issues/award_spec.rb @@ -8,7 +8,7 @@ feature 'Issue awards', js: true, feature: true do describe 'logged in' do before do gitlab_sign_in(user) - visit namespace_project_issue_path(project.namespace, project, issue) + visit project_issue_path(project, issue) wait_for_requests end @@ -17,7 +17,7 @@ feature 'Issue awards', js: true, feature: true do expect(page).to have_selector('.js-emoji-btn.active') expect(first('.js-emoji-btn')).to have_content '1' - visit namespace_project_issue_path(project.namespace, project, issue) + visit project_issue_path(project, issue) expect(first('.js-emoji-btn')).to have_content '1' end @@ -26,7 +26,7 @@ feature 'Issue awards', js: true, feature: true do find('.js-emoji-btn.active').click expect(first('.js-emoji-btn')).to have_content '0' - visit namespace_project_issue_path(project.namespace, project, issue) + visit project_issue_path(project, issue) expect(first('.js-emoji-btn')).to have_content '0' end @@ -40,7 +40,7 @@ feature 'Issue awards', js: true, feature: true do describe 'logged out' do before do - visit namespace_project_issue_path(project.namespace, project, issue) + visit project_issue_path(project, issue) wait_for_requests end diff --git a/spec/features/issues/bulk_assignment_labels_spec.rb b/spec/features/issues/bulk_assignment_labels_spec.rb index a99c19cb787..86226d97f79 100644 --- a/spec/features/issues/bulk_assignment_labels_spec.rb +++ b/spec/features/issues/bulk_assignment_labels_spec.rb @@ -348,7 +348,7 @@ feature 'Issues > Labels bulk assignment', feature: true do before do gitlab_sign_in user - visit namespace_project_issues_path(project.namespace, project) + visit project_issues_path(project) end context 'cannot bulk assign labels' do @@ -410,7 +410,7 @@ feature 'Issues > Labels bulk assignment', feature: true do end def enable_bulk_update - visit namespace_project_issues_path(project.namespace, project) + visit project_issues_path(project) click_button 'Edit Issues' end diff --git a/spec/features/issues/create_branch_merge_request_spec.rb b/spec/features/issues/create_branch_merge_request_spec.rb index aa538803dd8..f730141f82c 100644 --- a/spec/features/issues/create_branch_merge_request_spec.rb +++ b/spec/features/issues/create_branch_merge_request_spec.rb @@ -12,7 +12,7 @@ feature 'Create Branch/Merge Request Dropdown on issue page', feature: true, js: end it 'allows creating a merge request from the issue page' do - visit namespace_project_issue_path(project.namespace, project, issue) + visit project_issue_path(project, issue) select_dropdown_option('create-mr') @@ -21,21 +21,21 @@ feature 'Create Branch/Merge Request Dropdown on issue page', feature: true, js: expect(page).to have_content("created branch 1-cherry-coloured-funk") expect(page).to have_content("mentioned in merge request !1") - visit namespace_project_merge_request_path(project.namespace, project, MergeRequest.first) + visit project_merge_request_path(project, MergeRequest.first) expect(page).to have_content('WIP: Resolve "Cherry-Coloured Funk"') - expect(current_path).to eq(namespace_project_merge_request_path(project.namespace, project, MergeRequest.first)) + expect(current_path).to eq(project_merge_request_path(project, MergeRequest.first)) end it 'allows creating a branch from the issue page' do - visit namespace_project_issue_path(project.namespace, project, issue) + visit project_issue_path(project, issue) select_dropdown_option('create-branch') wait_for_requests expect(page).to have_selector('.dropdown-toggle-text ', text: '1-cherry-coloured-funk') - expect(current_path).to eq namespace_project_tree_path(project.namespace, project, '1-cherry-coloured-funk') + expect(current_path).to eq project_tree_path(project, '1-cherry-coloured-funk') end context "when there is a referenced merge request" do @@ -52,7 +52,7 @@ feature 'Create Branch/Merge Request Dropdown on issue page', feature: true, js: before do referenced_mr.cache_merge_request_closes_issues!(user) - visit namespace_project_issue_path(project.namespace, project, issue) + visit project_issue_path(project, issue) end it 'disables the create branch button' do @@ -66,7 +66,7 @@ feature 'Create Branch/Merge Request Dropdown on issue page', feature: true, js: it 'disables the create branch button' do issue = create(:issue, :confidential, project: project) - visit namespace_project_issue_path(project.namespace, project, issue) + visit project_issue_path(project, issue) expect(page).not_to have_css('.create-mr-dropdown-wrap') end @@ -75,7 +75,7 @@ feature 'Create Branch/Merge Request Dropdown on issue page', feature: true, js: context 'for visitors' do before do - visit namespace_project_issue_path(project.namespace, project, issue) + visit project_issue_path(project, issue) end it 'shows no buttons' do diff --git a/spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb b/spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb index 5f631043e15..3b7622882c1 100644 --- a/spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb +++ b/spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb @@ -10,12 +10,12 @@ feature 'Resolving all open discussions in a merge request from an issue', featu before do project.team << [user, :master] gitlab_sign_in user - visit namespace_project_merge_request_path(project.namespace, project, merge_request) + visit project_merge_request_path(project, merge_request) end it 'shows a button to resolve all discussions by creating a new issue' do within('#resolve-count-app') do - expect(page).to have_link "Resolve all discussions in new issue", href: new_namespace_project_issue_path(project.namespace, project, merge_request_to_resolve_discussions_of: merge_request.iid) + expect(page).to have_link "Resolve all discussions in new issue", href: new_project_issue_path(project, merge_request_to_resolve_discussions_of: merge_request.iid) end end @@ -25,13 +25,13 @@ feature 'Resolving all open discussions in a merge request from an issue', featu end it 'hides the link for creating a new issue' do - expect(page).not_to have_link "Resolve all discussions in new issue", href: new_namespace_project_issue_path(project.namespace, project, merge_request_to_resolve_discussions_of: merge_request.iid) + expect(page).not_to have_link "Resolve all discussions in new issue", href: new_project_issue_path(project, merge_request_to_resolve_discussions_of: merge_request.iid) end end context 'creating an issue for discussions' do before do - click_link "Resolve all discussions in new issue", href: new_namespace_project_issue_path(project.namespace, project, merge_request_to_resolve_discussions_of: merge_request.iid) + click_link "Resolve all discussions in new issue", href: new_project_issue_path(project, merge_request_to_resolve_discussions_of: merge_request.iid) end it_behaves_like 'creating an issue for a discussion' @@ -45,7 +45,7 @@ feature 'Resolving all open discussions in a merge request from an issue', featu context 'with the internal tracker disabled' do before do project.project_feature.update_attribute(:issues_access_level, ProjectFeature::DISABLED) - visit namespace_project_merge_request_path(project.namespace, project, merge_request) + visit project_merge_request_path(project, merge_request) end it 'does not show a link to create a new issue' do @@ -55,7 +55,7 @@ feature 'Resolving all open discussions in a merge request from an issue', featu context 'merge request has discussions that need to be resolved' do before do - visit namespace_project_merge_request_path(project.namespace, project, merge_request) + visit project_merge_request_path(project, merge_request) end it 'shows a warning that the merge request contains unresolved discussions' do @@ -64,13 +64,13 @@ feature 'Resolving all open discussions in a merge request from an issue', featu it 'has a link to resolve all discussions by creating an issue' do page.within '.mr-widget-body' do - expect(page).to have_link 'Create an issue to resolve them later', href: new_namespace_project_issue_path(project.namespace, project, merge_request_to_resolve_discussions_of: merge_request.iid) + expect(page).to have_link 'Create an issue to resolve them later', href: new_project_issue_path(project, merge_request_to_resolve_discussions_of: merge_request.iid) end end context 'creating an issue for discussions' do before do - page.click_link 'Create an issue to resolve them later', href: new_namespace_project_issue_path(project.namespace, project, merge_request_to_resolve_discussions_of: merge_request.iid) + page.click_link 'Create an issue to resolve them later', href: new_project_issue_path(project, merge_request_to_resolve_discussions_of: merge_request.iid) end it_behaves_like 'creating an issue for a discussion' @@ -83,7 +83,7 @@ feature 'Resolving all open discussions in a merge request from an issue', featu before do project.team << [user, :reporter] gitlab_sign_in user - visit new_namespace_project_issue_path(project.namespace, project, merge_request_to_resolve_discussions_of: merge_request.iid) + visit new_project_issue_path(project, merge_request_to_resolve_discussions_of: merge_request.iid) end it 'Shows a notice to ask someone else to resolve the discussions' do diff --git a/spec/features/issues/create_issue_for_single_discussion_in_merge_request_spec.rb b/spec/features/issues/create_issue_for_single_discussion_in_merge_request_spec.rb index 9e9e214060f..97d49184920 100644 --- a/spec/features/issues/create_issue_for_single_discussion_in_merge_request_spec.rb +++ b/spec/features/issues/create_issue_for_single_discussion_in_merge_request_spec.rb @@ -10,13 +10,13 @@ feature 'Resolve an open discussion in a merge request by creating an issue', fe before do project.team << [user, :master] gitlab_sign_in user - visit namespace_project_merge_request_path(project.namespace, project, merge_request) + visit project_merge_request_path(project, merge_request) end context 'with the internal tracker disabled' do before do project.project_feature.update_attribute(:issues_access_level, ProjectFeature::DISABLED) - visit namespace_project_merge_request_path(project.namespace, project, merge_request) + visit project_merge_request_path(project, merge_request) end it 'does not show a link to create a new issue' do @@ -43,14 +43,14 @@ feature 'Resolve an open discussion in a merge request by creating an issue', fe end it 'has a link to create a new issue for a discussion' do - new_issue_link = new_namespace_project_issue_path(project.namespace, project, discussion_to_resolve: discussion.id, merge_request_to_resolve_discussions_of: merge_request.iid) + new_issue_link = new_project_issue_path(project, discussion_to_resolve: discussion.id, merge_request_to_resolve_discussions_of: merge_request.iid) expect(page).to have_link 'Resolve this discussion in a new issue', href: new_issue_link end context 'creating the issue' do before do - click_link 'Resolve this discussion in a new issue', href: new_namespace_project_issue_path(project.namespace, project, discussion_to_resolve: discussion.id, merge_request_to_resolve_discussions_of: merge_request.iid) + click_link 'Resolve this discussion in a new issue', href: new_project_issue_path(project, discussion_to_resolve: discussion.id, merge_request_to_resolve_discussions_of: merge_request.iid) end it 'has a hidden field for the discussion' do @@ -67,7 +67,7 @@ feature 'Resolve an open discussion in a merge request by creating an issue', fe before do project.team << [user, :reporter] gitlab_sign_in user - visit new_namespace_project_issue_path(project.namespace, project, + visit new_project_issue_path(project, merge_request_to_resolve_discussions_of: merge_request.iid, discussion_to_resolve: discussion.id) end diff --git a/spec/features/issues/filtered_search/dropdown_assignee_spec.rb b/spec/features/issues/filtered_search/dropdown_assignee_spec.rb index 96f6739af2d..211f7eec560 100644 --- a/spec/features/issues/filtered_search/dropdown_assignee_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_assignee_spec.rb @@ -26,7 +26,7 @@ describe 'Dropdown assignee', :feature, :js do gitlab_sign_in(user) create(:issue, project: project) - visit namespace_project_issues_path(project.namespace, project) + visit project_issues_path(project) end describe 'behavior' do diff --git a/spec/features/issues/filtered_search/dropdown_author_spec.rb b/spec/features/issues/filtered_search/dropdown_author_spec.rb index 5ee824c662a..364c5564a1c 100644 --- a/spec/features/issues/filtered_search/dropdown_author_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_author_spec.rb @@ -34,7 +34,7 @@ describe 'Dropdown author', js: true, feature: true do gitlab_sign_in(user) create(:issue, project: project) - visit namespace_project_issues_path(project.namespace, project) + visit project_issues_path(project) end describe 'behavior' do diff --git a/spec/features/issues/filtered_search/dropdown_hint_spec.rb b/spec/features/issues/filtered_search/dropdown_hint_spec.rb index a05e4394ffd..14c506eead3 100644 --- a/spec/features/issues/filtered_search/dropdown_hint_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_hint_spec.rb @@ -17,7 +17,7 @@ describe 'Dropdown hint', :js, :feature do gitlab_sign_in(user) create(:issue, project: project) - visit namespace_project_issues_path(project.namespace, project) + visit project_issues_path(project) end describe 'behavior' do diff --git a/spec/features/issues/filtered_search/dropdown_label_spec.rb b/spec/features/issues/filtered_search/dropdown_label_spec.rb index aec9d7ceb5d..04d2b39dbf2 100644 --- a/spec/features/issues/filtered_search/dropdown_label_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_label_spec.rb @@ -37,7 +37,7 @@ describe 'Dropdown label', js: true, feature: true do gitlab_sign_in(user) create(:issue, project: project) - visit namespace_project_issues_path(project.namespace, project) + visit project_issues_path(project) end describe 'keyboard navigation' do diff --git a/spec/features/issues/filtered_search/dropdown_milestone_spec.rb b/spec/features/issues/filtered_search/dropdown_milestone_spec.rb index b21f41946b7..1507e9f7616 100644 --- a/spec/features/issues/filtered_search/dropdown_milestone_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_milestone_spec.rb @@ -33,7 +33,7 @@ describe 'Dropdown milestone', :feature, :js do gitlab_sign_in(user) create(:issue, project: project) - visit namespace_project_issues_path(project.namespace, project) + visit project_issues_path(project) end describe 'behavior' do diff --git a/spec/features/issues/filtered_search/filter_issues_spec.rb b/spec/features/issues/filtered_search/filter_issues_spec.rb index 4cb728cc82b..9fc6391fa98 100644 --- a/spec/features/issues/filtered_search/filter_issues_spec.rb +++ b/spec/features/issues/filtered_search/filter_issues_spec.rb @@ -89,7 +89,7 @@ describe 'Filter issues', js: true, feature: true do milestone: future_milestone, project: project) - visit namespace_project_issues_path(project.namespace, project) + visit project_issues_path(project) end describe 'filter issues by author' do @@ -804,7 +804,7 @@ describe 'Filter issues', js: true, feature: true do describe 'RSS feeds' do it 'updates atom feed link for project issues' do - visit namespace_project_issues_path(project.namespace, project, milestone_title: milestone.title, assignee_id: user.id) + visit project_issues_path(project, milestone_title: milestone.title, assignee_id: user.id) link = find_link('Subscribe') params = CGI.parse(URI.parse(link[:href]).query) auto_discovery_link = find('link[type="application/atom+xml"]', visible: false) @@ -836,7 +836,7 @@ describe 'Filter issues', js: true, feature: true do context 'URL has a trailing slash' do before do - visit "#{namespace_project_issues_path(project.namespace, project)}/" + visit "#{project_issues_path(project)}/" end it 'milestone dropdown loads milestones' do diff --git a/spec/features/issues/filtered_search/recent_searches_spec.rb b/spec/features/issues/filtered_search/recent_searches_spec.rb index 09f228bcf49..4a91ce4be07 100644 --- a/spec/features/issues/filtered_search/recent_searches_spec.rb +++ b/spec/features/issues/filtered_search/recent_searches_spec.rb @@ -22,7 +22,7 @@ describe 'Recent searches', js: true, feature: true do end it 'searching adds to recent searches' do - visit namespace_project_issues_path(project_1.namespace, project_1) + visit project_issues_path(project_1) input_filtered_search('foo', submit: true) input_filtered_search('bar', submit: true) @@ -35,8 +35,8 @@ describe 'Recent searches', js: true, feature: true do end it 'visiting URL with search params adds to recent searches' do - visit namespace_project_issues_path(project_1.namespace, project_1, label_name: 'foo', search: 'bar') - visit namespace_project_issues_path(project_1.namespace, project_1, label_name: 'qux', search: 'garply') + visit project_issues_path(project_1, label_name: 'foo', search: 'bar') + visit project_issues_path(project_1, label_name: 'qux', search: 'garply') items = all('.filtered-search-history-dropdown-item', visible: false) @@ -48,7 +48,7 @@ describe 'Recent searches', js: true, feature: true do it 'saved recent searches are restored last on the list' do set_recent_searches(project_1_local_storage_key, '["saved1", "saved2"]') - visit namespace_project_issues_path(project_1.namespace, project_1, search: 'foo') + visit project_issues_path(project_1, search: 'foo') items = all('.filtered-search-history-dropdown-item', visible: false) @@ -59,12 +59,12 @@ describe 'Recent searches', js: true, feature: true do end it 'searches are scoped to projects' do - visit namespace_project_issues_path(project_1.namespace, project_1) + visit project_issues_path(project_1) input_filtered_search('foo', submit: true) input_filtered_search('bar', submit: true) - visit namespace_project_issues_path(project_2.namespace, project_2) + visit project_issues_path(project_2) input_filtered_search('more', submit: true) input_filtered_search('things', submit: true) @@ -78,7 +78,7 @@ describe 'Recent searches', js: true, feature: true do it 'clicking item fills search input' do set_recent_searches(project_1_local_storage_key, '["foo", "bar"]') - visit namespace_project_issues_path(project_1.namespace, project_1) + visit project_issues_path(project_1) all('.filtered-search-history-dropdown-item', visible: false)[0].trigger('click') wait_for_filtered_search('foo') @@ -88,7 +88,7 @@ describe 'Recent searches', js: true, feature: true do it 'clear recent searches button, clears recent searches' do set_recent_searches(project_1_local_storage_key, '["foo"]') - visit namespace_project_issues_path(project_1.namespace, project_1) + visit project_issues_path(project_1) items_before = all('.filtered-search-history-dropdown-item', visible: false) @@ -102,7 +102,7 @@ describe 'Recent searches', js: true, feature: true do it 'shows flash error when failed to parse saved history' do set_recent_searches(project_1_local_storage_key, 'fail') - visit namespace_project_issues_path(project_1.namespace, project_1) + visit project_issues_path(project_1) expect(find('.flash-alert')).to have_text('An error occured while parsing recent searches') end diff --git a/spec/features/issues/filtered_search/search_bar_spec.rb b/spec/features/issues/filtered_search/search_bar_spec.rb index 806c732b935..5b67d062f15 100644 --- a/spec/features/issues/filtered_search/search_bar_spec.rb +++ b/spec/features/issues/filtered_search/search_bar_spec.rb @@ -12,7 +12,7 @@ describe 'Search bar', js: true, feature: true do gitlab_sign_in(user) create(:issue, project: project) - visit namespace_project_issues_path(project.namespace, project) + visit project_issues_path(project) end def get_left_style(style) diff --git a/spec/features/issues/filtered_search/visual_tokens_spec.rb b/spec/features/issues/filtered_search/visual_tokens_spec.rb index 22488f34813..08360bfa641 100644 --- a/spec/features/issues/filtered_search/visual_tokens_spec.rb +++ b/spec/features/issues/filtered_search/visual_tokens_spec.rb @@ -28,7 +28,7 @@ describe 'Visual tokens', js: true, feature: true do gitlab_sign_in(user) create(:issue, project: project) - visit namespace_project_issues_path(project.namespace, project) + visit project_issues_path(project) end describe 'editing author token' do diff --git a/spec/features/issues/form_spec.rb b/spec/features/issues/form_spec.rb index b369ef1ff79..5c75b0d56b0 100644 --- a/spec/features/issues/form_spec.rb +++ b/spec/features/issues/form_spec.rb @@ -1,7 +1,6 @@ require 'rails_helper' describe 'New/edit issue', :feature, :js do - include GitlabRoutingHelper include ActionView::Helpers::JavaScriptHelper include FormHelper @@ -21,7 +20,7 @@ describe 'New/edit issue', :feature, :js do context 'new issue' do before do - visit new_namespace_project_issue_path(project.namespace, project) + visit new_project_issue_path(project) end describe 'shorten users API pagination limit (CE)' do @@ -31,15 +30,15 @@ describe 'New/edit issue', :feature, :js do # the original method, resulting in infinite recurison when called. # This is likely a bug with helper modules included into dynamically generated view classes. # To work around this, we have to hold on to and call to the original implementation manually. - original_issue_dropdown_options = FormHelper.instance_method(:issue_dropdown_options) - allow_any_instance_of(FormHelper).to receive(:issue_dropdown_options).and_wrap_original do |original, *args| + original_issue_dropdown_options = FormHelper.instance_method(:issue_assignees_dropdown_options) + allow_any_instance_of(FormHelper).to receive(:issue_assignees_dropdown_options).and_wrap_original do |original, *args| options = original_issue_dropdown_options.bind(original.receiver).call(*args) options[:data][:per_page] = 2 options end - visit new_namespace_project_issue_path(project.namespace, project) + visit new_project_issue_path(project) click_button 'Unassigned' @@ -221,7 +220,7 @@ describe 'New/edit issue', :feature, :js do context 'edit issue' do before do - visit edit_namespace_project_issue_path(project.namespace, project, issue) + visit edit_project_issue_path(project, issue) end it 'allows user to update issue' do @@ -282,7 +281,7 @@ describe 'New/edit issue', :feature, :js do before do sub_group_project.add_master(user) - visit new_namespace_project_issue_path(sub_group_project.namespace, sub_group_project) + visit new_project_issue_path(sub_group_project) end it 'creates new label from dropdown' do diff --git a/spec/features/issues/gfm_autocomplete_spec.rb b/spec/features/issues/gfm_autocomplete_spec.rb index e61eb5233d0..a0f26bf9a92 100644 --- a/spec/features/issues/gfm_autocomplete_spec.rb +++ b/spec/features/issues/gfm_autocomplete_spec.rb @@ -9,7 +9,7 @@ feature 'GFM autocomplete', feature: true, js: true do before do project.team << [user, :master] gitlab_sign_in(user) - visit namespace_project_issue_path(project.namespace, project, issue) + visit project_issue_path(project, issue) wait_for_requests end diff --git a/spec/features/issues/group_label_sidebar_spec.rb b/spec/features/issues/group_label_sidebar_spec.rb index fc8515cfe9b..5531a662c67 100644 --- a/spec/features/issues/group_label_sidebar_spec.rb +++ b/spec/features/issues/group_label_sidebar_spec.rb @@ -6,13 +6,9 @@ describe 'Group label on issue', :feature do project = create(:empty_project, :public, namespace: group) feature = create(:group_label, group: group, title: 'feature') issue = create(:labeled_issue, project: project, labels: [feature]) - label_link = namespace_project_issues_path( - project.namespace, - project, - label_name: [feature.name] - ) + label_link = project_issues_path(project, label_name: [feature.name]) - visit namespace_project_issue_path(project.namespace, project, issue) + visit project_issue_path(project, issue) link = find('.issuable-show-labels a') diff --git a/spec/features/issues/issue_sidebar_spec.rb b/spec/features/issues/issue_sidebar_spec.rb index 09724781a27..8d9bfcdf4e0 100644 --- a/spec/features/issues/issue_sidebar_spec.rb +++ b/spec/features/issues/issue_sidebar_spec.rb @@ -166,7 +166,7 @@ feature 'Issue Sidebar', feature: true do end def visit_issue(project, issue) - visit namespace_project_issue_path(project.namespace, project, issue) + visit project_issue_path(project, issue) end def open_issue_sidebar diff --git a/spec/features/issues/markdown_toolbar_spec.rb b/spec/features/issues/markdown_toolbar_spec.rb index 66d823ec9d0..396b53556bf 100644 --- a/spec/features/issues/markdown_toolbar_spec.rb +++ b/spec/features/issues/markdown_toolbar_spec.rb @@ -8,7 +8,7 @@ feature 'Issue markdown toolbar', feature: true, js: true do before do gitlab_sign_in(user) - visit namespace_project_issue_path(project.namespace, project, issue) + visit project_issue_path(project, issue) end it "doesn't include first new line when adding bold" do diff --git a/spec/features/issues/move_spec.rb b/spec/features/issues/move_spec.rb index 21a7637fe7f..568f2393aef 100644 --- a/spec/features/issues/move_spec.rb +++ b/spec/features/issues/move_spec.rb @@ -41,13 +41,10 @@ feature 'issue move to another project' do find('#issuable-move', visible: false).set(new_project.id) click_button('Save changes') - wait_for_requests - - expect(current_url).to include project_path(new_project) - expect(page).to have_content("Text with #{cross_reference}#{mr.to_reference}") expect(page).to have_content("moved from #{cross_reference}#{issue.to_reference}") expect(page).to have_content(issue.title) + expect(page.current_path).to include project_path(new_project) end scenario 'searching project dropdown', js: true do @@ -98,10 +95,6 @@ feature 'issue move to another project' do end def issue_path(issue) - namespace_project_issue_path(issue.project.namespace, issue.project, issue) - end - - def project_path(project) - namespace_project_path(new_project.namespace, new_project) + project_issue_path(issue.project, issue) end end diff --git a/spec/features/issues/note_polling_spec.rb b/spec/features/issues/note_polling_spec.rb index bd31e44ef33..580b8d03fef 100644 --- a/spec/features/issues/note_polling_spec.rb +++ b/spec/features/issues/note_polling_spec.rb @@ -8,7 +8,7 @@ feature 'Issue notes polling', :feature, :js do describe 'creates' do before do - visit namespace_project_issue_path(project.namespace, project, issue) + visit project_issue_path(project, issue) end it 'displays the new comment' do @@ -28,7 +28,7 @@ feature 'Issue notes polling', :feature, :js do before do gitlab_sign_in(user) - visit namespace_project_issue_path(project.namespace, project, issue) + visit project_issue_path(project, issue) end it 'has .original-note-content to compare against' do @@ -94,7 +94,7 @@ feature 'Issue notes polling', :feature, :js do before do gitlab_sign_in(user2) - visit namespace_project_issue_path(project.namespace, project, issue) + visit project_issue_path(project, issue) end it 'has .original-note-content to compare against' do @@ -115,7 +115,7 @@ feature 'Issue notes polling', :feature, :js do before do gitlab_sign_in(user) - visit namespace_project_issue_path(project.namespace, project, issue) + visit project_issue_path(project, issue) end it 'has .original-note-content to compare against' do diff --git a/spec/features/issues/notes_on_issues_spec.rb b/spec/features/issues/notes_on_issues_spec.rb index f648295416f..1871d853a90 100644 --- a/spec/features/issues/notes_on_issues_spec.rb +++ b/spec/features/issues/notes_on_issues_spec.rb @@ -10,7 +10,7 @@ describe 'Create notes on issues', :js, :feature do before do project.team << [user, :developer] gitlab_sign_in(user) - visit namespace_project_issue_path(project.namespace, project, issue) + visit project_issue_path(project, issue) fill_in 'note[note]', with: note_text click_button 'Comment' diff --git a/spec/features/issues/spam_issues_spec.rb b/spec/features/issues/spam_issues_spec.rb index 57c783790b5..76dae9212dd 100644 --- a/spec/features/issues/spam_issues_spec.rb +++ b/spec/features/issues/spam_issues_spec.rb @@ -25,7 +25,7 @@ describe 'New issue', feature: true, js: true do before do WebMock.stub_request(:any, /.*akismet.com.*/).to_return(body: "true", status: 200) - visit new_namespace_project_issue_path(project.namespace, project) + visit new_project_issue_path(project) end it 'creates an issue after solving reCaptcha' do @@ -50,7 +50,7 @@ describe 'New issue', feature: true, js: true do before do WebMock.stub_request(:any, /.*akismet.com.*/).to_return(body: 'false', status: 200) - visit new_namespace_project_issue_path(project.namespace, project) + visit new_project_issue_path(project) end it 'creates an issue' do diff --git a/spec/features/issues/todo_spec.rb b/spec/features/issues/todo_spec.rb index a1c00dd64f6..1bcd717e8dd 100644 --- a/spec/features/issues/todo_spec.rb +++ b/spec/features/issues/todo_spec.rb @@ -8,7 +8,7 @@ feature 'Manually create a todo item from issue', feature: true, js: true do before do project.team << [user, :master] gitlab_sign_in(user) - visit namespace_project_issue_path(project.namespace, project, issue) + visit project_issue_path(project, issue) end it 'creates todo when clicking button' do @@ -21,7 +21,7 @@ feature 'Manually create a todo item from issue', feature: true, js: true do expect(page).to have_content '1' end - visit namespace_project_issue_path(project.namespace, project, issue) + visit project_issue_path(project, issue) page.within '.header-content .todos-count' do expect(page).to have_content '1' @@ -36,7 +36,7 @@ feature 'Manually create a todo item from issue', feature: true, js: true do expect(page).to have_selector('.todos-count', visible: false) - visit namespace_project_issue_path(project.namespace, project, issue) + visit project_issue_path(project, issue) expect(page).to have_selector('.todos-count', visible: false) end diff --git a/spec/features/issues/update_issues_spec.rb b/spec/features/issues/update_issues_spec.rb index dc981406e4e..5a7c4f54cb6 100644 --- a/spec/features/issues/update_issues_spec.rb +++ b/spec/features/issues/update_issues_spec.rb @@ -1,18 +1,18 @@ require 'rails_helper' -feature 'Multiple issue updating from issues#index', feature: true do +feature 'Multiple issue updating from issues#index', :js do let!(:project) { create(:project) } let!(:issue) { create(:issue, project: project) } let!(:user) { create(:user)} before do project.team << [user, :master] - gitlab_sign_in(user) + sign_in(user) end - context 'status', js: true do + context 'status' do it 'sets to closed' do - visit namespace_project_issues_path(project.namespace, project) + visit project_issues_path(project) click_button 'Edit Issues' find('#check-all-issues').click @@ -25,7 +25,7 @@ feature 'Multiple issue updating from issues#index', feature: true do it 'sets to open' do create_closed - visit namespace_project_issues_path(project.namespace, project, state: 'closed') + visit project_issues_path(project, state: 'closed') click_button 'Edit Issues' find('#check-all-issues').click @@ -37,9 +37,9 @@ feature 'Multiple issue updating from issues#index', feature: true do end end - context 'assignee', js: true do + context 'assignee' do it 'updates to current user' do - visit namespace_project_issues_path(project.namespace, project) + visit project_issues_path(project) click_button 'Edit Issues' find('#check-all-issues').click @@ -55,7 +55,7 @@ feature 'Multiple issue updating from issues#index', feature: true do it 'updates to unassigned' do create_assigned - visit namespace_project_issues_path(project.namespace, project) + visit project_issues_path(project) click_button 'Edit Issues' find('#check-all-issues').click @@ -67,11 +67,11 @@ feature 'Multiple issue updating from issues#index', feature: true do end end - context 'milestone', js: true do - let(:milestone) { create(:milestone, project: project) } + context 'milestone' do + let!(:milestone) { create(:milestone, project: project) } it 'updates milestone' do - visit namespace_project_issues_path(project.namespace, project) + visit project_issues_path(project) click_button 'Edit Issues' find('#check-all-issues').click @@ -85,7 +85,7 @@ feature 'Multiple issue updating from issues#index', feature: true do it 'sets to no milestone' do create_with_milestone - visit namespace_project_issues_path(project.namespace, project) + visit project_issues_path(project) expect(first('.issue')).to have_content milestone.title diff --git a/spec/features/issues/user_uses_slash_commands_spec.rb b/spec/features/issues/user_uses_slash_commands_spec.rb index 168cdd08137..ad28decfc00 100644 --- a/spec/features/issues/user_uses_slash_commands_spec.rb +++ b/spec/features/issues/user_uses_slash_commands_spec.rb @@ -14,7 +14,7 @@ feature 'Issues > User uses quick actions', feature: true, js: true do before do project.team << [user, :master] gitlab_sign_in(user) - visit namespace_project_issue_path(project.namespace, project, issue) + visit project_issue_path(project, issue) end after do @@ -43,7 +43,7 @@ feature 'Issues > User uses quick actions', feature: true, js: true do project.team << [guest, :guest] gitlab_sign_out gitlab_sign_in(guest) - visit namespace_project_issue_path(project.namespace, project, issue) + visit project_issue_path(project, issue) end it 'does not create a note, and sets the due date accordingly' do @@ -83,7 +83,7 @@ feature 'Issues > User uses quick actions', feature: true, js: true do project.team << [guest, :guest] gitlab_sign_out gitlab_sign_in(guest) - visit namespace_project_issue_path(project.namespace, project, issue) + visit project_issue_path(project, issue) end it 'does not create a note, and sets the due date accordingly' do @@ -108,7 +108,7 @@ feature 'Issues > User uses quick actions', feature: true, js: true do context 'Issue' do before do - visit namespace_project_issue_path(project.namespace, project, issue) + visit project_issue_path(project, issue) end it_behaves_like 'issuable time tracker' @@ -118,7 +118,7 @@ feature 'Issues > User uses quick actions', feature: true, js: true do let(:merge_request) { create(:merge_request, source_project: project) } before do - visit namespace_project_merge_request_path(project.namespace, project, merge_request) + visit project_merge_request_path(project, merge_request) end it_behaves_like 'issuable time tracker' @@ -134,7 +134,7 @@ feature 'Issues > User uses quick actions', feature: true, js: true do context 'Issue' do before do - visit namespace_project_issue_path(project.namespace, project, issue) + visit project_issue_path(project, issue) end it_behaves_like 'issuable time tracker' @@ -144,7 +144,7 @@ feature 'Issues > User uses quick actions', feature: true, js: true do let(:merge_request) { create(:merge_request, source_project: project) } before do - visit namespace_project_merge_request_path(project.namespace, project, merge_request) + visit project_merge_request_path(project, merge_request) end it_behaves_like 'issuable time tracker' diff --git a/spec/features/issues_spec.rb b/spec/features/issues_spec.rb index f47b89fd718..8cb62910e18 100644 --- a/spec/features/issues_spec.rb +++ b/spec/features/issues_spec.rb @@ -24,7 +24,7 @@ describe 'Issues', feature: true do end before do - visit edit_namespace_project_issue_path(project.namespace, project, issue) + visit edit_project_issue_path(project, issue) find('.js-zen-enter').click end @@ -42,7 +42,7 @@ describe 'Issues', feature: true do end it 'allows user to select unassigned', js: true do - visit edit_namespace_project_issue_path(project.namespace, project, issue) + visit edit_project_issue_path(project, issue) expect(page).to have_content "Assignee #{user.name}" @@ -62,7 +62,7 @@ describe 'Issues', feature: true do describe 'due date', js: true do context 'on new form' do before do - visit new_namespace_project_issue_path(project.namespace, project) + visit new_project_issue_path(project) end it 'saves with due date' do @@ -90,7 +90,7 @@ describe 'Issues', feature: true do let(:issue) { create(:issue, author: user, project: project, due_date: Date.today.at_beginning_of_month.to_s) } before do - visit edit_namespace_project_issue_path(project.namespace, project, issue) + visit edit_project_issue_path(project, issue) end it 'saves with due date' do @@ -135,7 +135,7 @@ describe 'Issues', feature: true do issue = create(:issue, author: user, assignees: [user], project: project, title: 'foobar') create(:award_emoji, awardable: issue) - visit namespace_project_issues_path(project.namespace, project, assignee_id: user.id) + visit project_issues_path(project, assignee_id: user.id) expect(page).to have_content 'foobar' expect(page.all('.no-comments').first.text).to eq "0" @@ -161,7 +161,7 @@ describe 'Issues', feature: true do let(:issue) { @issue } it 'allows filtering by issues with no specified assignee' do - visit namespace_project_issues_path(project.namespace, project, assignee_id: IssuableFinder::NONE) + visit project_issues_path(project, assignee_id: IssuableFinder::NONE) expect(page).to have_content 'foobar' expect(page).not_to have_content 'barbaz' @@ -169,7 +169,7 @@ describe 'Issues', feature: true do end it 'allows filtering by a specified assignee' do - visit namespace_project_issues_path(project.namespace, project, assignee_id: user.id) + visit project_issues_path(project, assignee_id: user.id) expect(page).not_to have_content 'foobar' expect(page).to have_content 'barbaz' @@ -190,14 +190,14 @@ describe 'Issues', feature: true do let(:later_due_milestone) { create(:milestone, due_date: '2013-12-12') } it 'sorts by newest' do - visit namespace_project_issues_path(project.namespace, project, sort: sort_value_recently_created) + visit project_issues_path(project, sort: sort_value_recently_created) expect(first_issue).to include('foo') expect(last_issue).to include('baz') end it 'sorts by oldest' do - visit namespace_project_issues_path(project.namespace, project, sort: sort_value_oldest_created) + visit project_issues_path(project, sort: sort_value_oldest_created) expect(first_issue).to include('baz') expect(last_issue).to include('foo') @@ -206,7 +206,7 @@ describe 'Issues', feature: true do it 'sorts by most recently updated' do baz.updated_at = Time.now + 100 baz.save - visit namespace_project_issues_path(project.namespace, project, sort: sort_value_recently_updated) + visit project_issues_path(project, sort: sort_value_recently_updated) expect(first_issue).to include('baz') end @@ -214,7 +214,7 @@ describe 'Issues', feature: true do it 'sorts by least recently updated' do baz.updated_at = Time.now - 100 baz.save - visit namespace_project_issues_path(project.namespace, project, sort: sort_value_oldest_updated) + visit project_issues_path(project, sort: sort_value_oldest_updated) expect(first_issue).to include('baz') end @@ -226,13 +226,13 @@ describe 'Issues', feature: true do end it 'sorts by recently due date' do - visit namespace_project_issues_path(project.namespace, project, sort: sort_value_due_date_soon) + visit project_issues_path(project, sort: sort_value_due_date_soon) expect(first_issue).to include('foo') end it 'sorts by least recently due date' do - visit namespace_project_issues_path(project.namespace, project, sort: sort_value_due_date_later) + visit project_issues_path(project, sort: sort_value_due_date_later) expect(first_issue).to include('bar') end @@ -240,7 +240,7 @@ describe 'Issues', feature: true do it 'sorts by least recently due date by excluding nil due dates' do bar.update(due_date: nil) - visit namespace_project_issues_path(project.namespace, project, sort: sort_value_due_date_later) + visit project_issues_path(project, sort: sort_value_due_date_later) expect(first_issue).to include('foo') end @@ -255,7 +255,7 @@ describe 'Issues', feature: true do it 'sorts by least recently due date by excluding nil due dates' do bar.update(due_date: nil) - visit namespace_project_issues_path(project.namespace, project, label_names: [label.name], sort: sort_value_due_date_later) + visit project_issues_path(project, label_names: [label.name], sort: sort_value_due_date_later) expect(first_issue).to include('foo') end @@ -269,7 +269,7 @@ describe 'Issues', feature: true do end it 'filters by none' do - visit namespace_project_issues_path(project.namespace, project, due_date: Issue::NoDueDate.name) + visit project_issues_path(project, due_date: Issue::NoDueDate.name) expect(page).not_to have_content('foo') expect(page).not_to have_content('bar') @@ -277,7 +277,7 @@ describe 'Issues', feature: true do end it 'filters by any' do - visit namespace_project_issues_path(project.namespace, project, due_date: Issue::AnyDueDate.name) + visit project_issues_path(project, due_date: Issue::AnyDueDate.name) expect(page).to have_content('foo') expect(page).to have_content('bar') @@ -289,7 +289,7 @@ describe 'Issues', feature: true do bar.update(due_date: Date.today.end_of_week) baz.update(due_date: Date.today - 8.days) - visit namespace_project_issues_path(project.namespace, project, due_date: Issue::DueThisWeek.name) + visit project_issues_path(project, due_date: Issue::DueThisWeek.name) expect(page).to have_content('foo') expect(page).to have_content('bar') @@ -301,7 +301,7 @@ describe 'Issues', feature: true do bar.update(due_date: Date.today.end_of_month) baz.update(due_date: Date.today - 50.days) - visit namespace_project_issues_path(project.namespace, project, due_date: Issue::DueThisMonth.name) + visit project_issues_path(project, due_date: Issue::DueThisMonth.name) expect(page).to have_content('foo') expect(page).to have_content('bar') @@ -313,7 +313,7 @@ describe 'Issues', feature: true do bar.update(due_date: Date.today + 20.days) baz.update(due_date: Date.yesterday) - visit namespace_project_issues_path(project.namespace, project, due_date: Issue::Overdue.name) + visit project_issues_path(project, due_date: Issue::Overdue.name) expect(page).not_to have_content('foo') expect(page).not_to have_content('bar') @@ -330,14 +330,14 @@ describe 'Issues', feature: true do end it 'sorts by recently due milestone' do - visit namespace_project_issues_path(project.namespace, project, sort: sort_value_milestone_soon) + visit project_issues_path(project, sort: sort_value_milestone_soon) expect(first_issue).to include('foo') expect(last_issue).to include('baz') end it 'sorts by least recently due milestone' do - visit namespace_project_issues_path(project.namespace, project, sort: sort_value_milestone_later) + visit project_issues_path(project, sort: sort_value_milestone_later) expect(first_issue).to include('bar') expect(last_issue).to include('baz') @@ -355,7 +355,7 @@ describe 'Issues', feature: true do end it 'sorts with a filter applied' do - visit namespace_project_issues_path(project.namespace, project, + visit project_issues_path(project, sort: sort_value_oldest_created, assignee_id: user2.id) @@ -397,7 +397,7 @@ describe 'Issues', feature: true do let!(:label) { create(:label, project: project) } before do - visit namespace_project_issue_path(project.namespace, project, issue) + visit project_issue_path(project, issue) end it 'will not send ajax request when no data is changed' do @@ -416,7 +416,7 @@ describe 'Issues', feature: true do context 'by authorized user' do it 'allows user to select unassigned', js: true do - visit namespace_project_issue_path(project.namespace, project, issue) + visit project_issue_path(project, issue) page.within('.assignee') do expect(page).to have_content "#{user.name}" @@ -435,7 +435,7 @@ describe 'Issues', feature: true do it 'allows user to select an assignee', js: true do issue2 = create(:issue, project: project, author: user) - visit namespace_project_issue_path(project.namespace, project, issue2) + visit project_issue_path(project, issue2) page.within('.assignee') do expect(page).to have_content "No assignee" @@ -456,7 +456,7 @@ describe 'Issues', feature: true do it 'allows user to unselect themselves', js: true do issue2 = create(:issue, project: project, author: user) - visit namespace_project_issue_path(project.namespace, project, issue2) + visit project_issue_path(project, issue2) page.within '.assignee' do click_link 'Edit' @@ -487,7 +487,7 @@ describe 'Issues', feature: true do sign_out(:user) sign_in(guest) - visit namespace_project_issue_path(project.namespace, project, issue) + visit project_issue_path(project, issue) expect(page).to have_content issue.assignees.first.name end end @@ -499,7 +499,7 @@ describe 'Issues', feature: true do context 'by authorized user' do it 'allows user to select unassigned', js: true do - visit namespace_project_issue_path(project.namespace, project, issue) + visit project_issue_path(project, issue) page.within('.milestone') do expect(page).to have_content "None" @@ -517,7 +517,7 @@ describe 'Issues', feature: true do end it 'allows user to de-select milestone', js: true do - visit namespace_project_issue_path(project.namespace, project, issue) + visit project_issue_path(project, issue) page.within('.milestone') do click_link 'Edit' @@ -550,7 +550,7 @@ describe 'Issues', feature: true do sign_out(:user) sign_in(guest) - visit namespace_project_issue_path(project.namespace, project, issue) + visit project_issue_path(project, issue) expect(page).to have_content milestone.title end end @@ -565,7 +565,7 @@ describe 'Issues', feature: true do end it 'redirects to signin then back to new issue after signin' do - visit namespace_project_issues_path(project.namespace, project) + visit project_issues_path(project) click_link 'New issue' @@ -575,13 +575,13 @@ describe 'Issues', feature: true do # need the full login flow gitlab_sign_in(create(:user)) - expect(current_path).to eq new_namespace_project_issue_path(project.namespace, project) + expect(current_path).to eq new_project_issue_path(project) end end context 'dropzone upload file', js: true do before do - visit new_namespace_project_issue_path(project.namespace, project) + visit new_project_issue_path(project) end it 'uploads file when dragging into textarea' do @@ -608,7 +608,7 @@ describe 'Issues', feature: true do message: 'added issue template', branch_name: 'master') - visit new_namespace_project_issue_path(project.namespace, project, issuable_template: 'bug') + visit new_project_issue_path(project, issuable_template: 'bug') end it 'fills in template' do @@ -625,7 +625,7 @@ describe 'Issues', feature: true do project.issues << issue stub_incoming_email_setting(enabled: true, address: "p+%{key}@gl.ab") - visit namespace_project_issues_path(project.namespace, project) + visit project_issues_path(project) click_button('Email a new issue') end @@ -654,7 +654,7 @@ describe 'Issues', feature: true do let(:issue) { create(:issue, project: project, author: user, assignees: [user]) } before do - visit namespace_project_issue_path(project.namespace, project, issue) + visit project_issue_path(project, issue) end it 'adds due date to issue' do @@ -698,7 +698,7 @@ describe 'Issues', feature: true do it 'updates the title', js: true do issue = create(:issue, author: user, assignees: [user], project: project, title: 'new title') - visit namespace_project_issue_path(project.namespace, project, issue) + visit project_issue_path(project, issue) expect(page).to have_text("new title") diff --git a/spec/features/merge_requests/assign_issues_spec.rb b/spec/features/merge_requests/assign_issues_spec.rb index cb835f533e0..9d9a31ab8e8 100644 --- a/spec/features/merge_requests/assign_issues_spec.rb +++ b/spec/features/merge_requests/assign_issues_spec.rb @@ -14,7 +14,7 @@ feature 'Merge request issue assignment', js: true, feature: true do def visit_merge_request(current_user = nil) gitlab_sign_in(current_user || user) - visit namespace_project_merge_request_path(project.namespace, project, merge_request) + visit project_merge_request_path(project, merge_request) end context 'logged in as author' do diff --git a/spec/features/merge_requests/award_spec.rb b/spec/features/merge_requests/award_spec.rb index e9dd755b6af..ed5a4fa5784 100644 --- a/spec/features/merge_requests/award_spec.rb +++ b/spec/features/merge_requests/award_spec.rb @@ -8,7 +8,7 @@ feature 'Merge request awards', js: true, feature: true do describe 'logged in' do before do gitlab_sign_in(user) - visit namespace_project_merge_request_path(project.namespace, project, merge_request) + visit project_merge_request_path(project, merge_request) end it 'adds award to merge request' do @@ -16,7 +16,7 @@ feature 'Merge request awards', js: true, feature: true do expect(page).to have_selector('.js-emoji-btn.active') expect(first('.js-emoji-btn')).to have_content '1' - visit namespace_project_merge_request_path(project.namespace, project, merge_request) + visit project_merge_request_path(project, merge_request) expect(first('.js-emoji-btn')).to have_content '1' end @@ -25,7 +25,7 @@ feature 'Merge request awards', js: true, feature: true do find('.js-emoji-btn.active').click expect(first('.js-emoji-btn')).to have_content '0' - visit namespace_project_merge_request_path(project.namespace, project, merge_request) + visit project_merge_request_path(project, merge_request) expect(first('.js-emoji-btn')).to have_content '0' end @@ -39,7 +39,7 @@ feature 'Merge request awards', js: true, feature: true do describe 'logged out' do before do - visit namespace_project_merge_request_path(project.namespace, project, merge_request) + visit project_merge_request_path(project, merge_request) end it 'does not see award menu button' do diff --git a/spec/features/merge_requests/check_if_mergeable_with_unresolved_discussions_spec.rb b/spec/features/merge_requests/check_if_mergeable_with_unresolved_discussions_spec.rb index 060cfb8fdd1..0f8ab4cd92b 100644 --- a/spec/features/merge_requests/check_if_mergeable_with_unresolved_discussions_spec.rb +++ b/spec/features/merge_requests/check_if_mergeable_with_unresolved_discussions_spec.rb @@ -64,6 +64,6 @@ feature 'Check if mergeable with unresolved discussions', js: true, feature: tru end def visit_merge_request(merge_request) - visit namespace_project_merge_request_path(merge_request.project.namespace, merge_request.project, merge_request) + visit project_merge_request_path(merge_request.project, merge_request) end end diff --git a/spec/features/merge_requests/cherry_pick_spec.rb b/spec/features/merge_requests/cherry_pick_spec.rb index 6ba96570e3d..5a5f884c6b3 100644 --- a/spec/features/merge_requests/cherry_pick_spec.rb +++ b/spec/features/merge_requests/cherry_pick_spec.rb @@ -28,7 +28,7 @@ describe 'Cherry-pick Merge Requests', js: true do end it "doesn't show a Cherry-pick button" do - visit namespace_project_merge_request_path(project.namespace, project, merge_request) + visit project_merge_request_path(project, merge_request) expect(page).not_to have_link "Cherry-pick" end @@ -36,7 +36,7 @@ describe 'Cherry-pick Merge Requests', js: true do context "With a merge commit" do it "shows a Cherry-pick button" do - visit namespace_project_merge_request_path(project.namespace, project, merge_request) + visit project_merge_request_path(project, merge_request) expect(page).to have_link "Cherry-pick" end diff --git a/spec/features/merge_requests/closes_issues_spec.rb b/spec/features/merge_requests/closes_issues_spec.rb index 365b2555c35..2f639b54637 100644 --- a/spec/features/merge_requests/closes_issues_spec.rb +++ b/spec/features/merge_requests/closes_issues_spec.rb @@ -22,7 +22,7 @@ feature 'Merge Request closing issues message', feature: true, js: true do gitlab_sign_in user - visit namespace_project_merge_request_path(project.namespace, project, merge_request) + visit project_merge_request_path(project, merge_request) wait_for_requests end diff --git a/spec/features/merge_requests/conflicts_spec.rb b/spec/features/merge_requests/conflicts_spec.rb index 9c091befa27..a9947381f46 100644 --- a/spec/features/merge_requests/conflicts_spec.rb +++ b/spec/features/merge_requests/conflicts_spec.rb @@ -86,7 +86,7 @@ feature 'Merge request conflict resolution', js: true, feature: true do let(:merge_request) { create_merge_request('conflict-resolvable') } before do - visit namespace_project_merge_request_path(project.namespace, project, merge_request) + visit project_merge_request_path(project, merge_request) end it 'shows a link to the conflict resolution page' do @@ -117,7 +117,7 @@ feature 'Merge request conflict resolution', js: true, feature: true do let(:merge_request) { create_merge_request('conflict-contains-conflict-markers') } before do - visit namespace_project_merge_request_path(project.namespace, project, merge_request) + visit project_merge_request_path(project, merge_request) click_link('conflicts', href: /\/conflicts\Z/) end @@ -166,7 +166,7 @@ feature 'Merge request conflict resolution', js: true, feature: true do project.team << [user, :developer] gitlab_sign_in(user) - visit namespace_project_merge_request_path(project.namespace, project, merge_request) + visit project_merge_request_path(project, merge_request) end it 'does not show a link to the conflict resolution page' do diff --git a/spec/features/merge_requests/create_new_mr_spec.rb b/spec/features/merge_requests/create_new_mr_spec.rb index 6a08e50bf5e..198fcba4e78 100644 --- a/spec/features/merge_requests/create_new_mr_spec.rb +++ b/spec/features/merge_requests/create_new_mr_spec.rb @@ -11,7 +11,7 @@ feature 'Create New Merge Request', feature: true, js: true do end it 'selects the source branch sha when a tag with the same name exists' do - visit namespace_project_merge_requests_path(project.namespace, project) + visit project_merge_requests_path(project) click_link 'New merge request' expect(page).to have_content('Source branch') @@ -24,7 +24,7 @@ feature 'Create New Merge Request', feature: true, js: true do end it 'selects the target branch sha when a tag with the same name exists' do - visit namespace_project_merge_requests_path(project.namespace, project) + visit project_merge_requests_path(project) click_link 'New merge request' @@ -38,7 +38,7 @@ feature 'Create New Merge Request', feature: true, js: true do end it 'generates a diff for an orphaned branch' do - visit namespace_project_merge_requests_path(project.namespace, project) + visit project_merge_requests_path(project) page.has_link?('New Merge Request') ? click_link("New Merge Request") : click_link('New merge request') expect(page).to have_content('Source branch') @@ -65,7 +65,7 @@ feature 'Create New Merge Request', feature: true, js: true do it 'does not leak the private project name & namespace' do private_project = create(:project, :private) - visit namespace_project_new_merge_request_path(project.namespace, project, merge_request: { target_project_id: private_project.id }) + visit project_new_merge_request_path(project, merge_request: { target_project_id: private_project.id }) expect(page).not_to have_content private_project.path_with_namespace expect(page).to have_content project.path_with_namespace @@ -76,7 +76,7 @@ feature 'Create New Merge Request', feature: true, js: true do it 'does not leak the private project name & namespace' do private_project = create(:project, :private) - visit namespace_project_new_merge_request_path(project.namespace, project, merge_request: { source_project_id: private_project.id }) + visit project_new_merge_request_path(project, merge_request: { source_project_id: private_project.id }) expect(page).not_to have_content private_project.path_with_namespace expect(page).to have_content project.path_with_namespace @@ -84,13 +84,13 @@ feature 'Create New Merge Request', feature: true, js: true do end it 'populates source branch button' do - visit namespace_project_new_merge_request_path(project.namespace, project, change_branches: true, merge_request: { target_branch: 'master', source_branch: 'fix' }) + visit project_new_merge_request_path(project, change_branches: true, merge_request: { target_branch: 'master', source_branch: 'fix' }) expect(find('.js-source-branch')).to have_content('fix') end it 'allows to change the diff view' do - visit namespace_project_new_merge_request_path(project.namespace, project, merge_request: { target_branch: 'master', source_branch: 'fix' }) + visit project_new_merge_request_path(project, merge_request: { target_branch: 'master', source_branch: 'fix' }) click_link 'Changes' @@ -106,7 +106,7 @@ feature 'Create New Merge Request', feature: true, js: true do end it 'does not allow non-existing branches' do - visit namespace_project_new_merge_request_path(project.namespace, project, merge_request: { target_branch: 'non-exist-target', source_branch: 'non-exist-source' }) + visit project_new_merge_request_path(project, merge_request: { target_branch: 'non-exist-target', source_branch: 'non-exist-source' }) expect(page).to have_content('The form contains the following errors') expect(page).to have_content('Source branch "non-exist-source" does not exist') @@ -115,7 +115,7 @@ feature 'Create New Merge Request', feature: true, js: true do context 'when a branch contains commits that both delete and add the same image' do it 'renders the diff successfully' do - visit namespace_project_new_merge_request_path(project.namespace, project, merge_request: { target_branch: 'master', source_branch: 'deleted-image-test' }) + visit project_new_merge_request_path(project, merge_request: { target_branch: 'master', source_branch: 'deleted-image-test' }) click_link "Changes" @@ -125,7 +125,7 @@ feature 'Create New Merge Request', feature: true, js: true do # Isolates a regression (see #24627) it 'does not show error messages on initial form' do - visit namespace_project_new_merge_request_path(project.namespace, project) + visit project_new_merge_request_path(project) expect(page).not_to have_selector('#error_explanation') expect(page).not_to have_content('The form contains the following error') end @@ -138,8 +138,8 @@ feature 'Create New Merge Request', feature: true, js: true do end it 'shows pipelines for a new merge request' do - visit namespace_project_new_merge_request_path( - project.namespace, project, + visit project_new_merge_request_path( + project, merge_request: { target_branch: 'master', source_branch: 'fix' }) page.within('.merge-request') do diff --git a/spec/features/merge_requests/created_from_fork_spec.rb b/spec/features/merge_requests/created_from_fork_spec.rb index 69059dfa562..9f1b6be67d4 100644 --- a/spec/features/merge_requests/created_from_fork_spec.rb +++ b/spec/features/merge_requests/created_from_fork_spec.rb @@ -64,7 +64,6 @@ feature 'Merge request created from fork' do end def visit_merge_request(mr) - visit namespace_project_merge_request_path(project.namespace, - project, mr) + visit project_merge_request_path(project, mr) end end diff --git a/spec/features/merge_requests/deleted_source_branch_spec.rb b/spec/features/merge_requests/deleted_source_branch_spec.rb index f2af3198319..671c17cd9e3 100644 --- a/spec/features/merge_requests/deleted_source_branch_spec.rb +++ b/spec/features/merge_requests/deleted_source_branch_spec.rb @@ -11,11 +11,7 @@ describe 'Deleted source branch', feature: true, js: true do gitlab_sign_in user merge_request.project.team << [user, :master] merge_request.update!(source_branch: 'this-branch-does-not-exist') - visit namespace_project_merge_request_path( - merge_request.project.namespace, - merge_request.project, - merge_request - ) + visit project_merge_request_path(merge_request.project, merge_request) end it 'shows a message about missing source branch' do diff --git a/spec/features/merge_requests/diff_notes_avatars_spec.rb b/spec/features/merge_requests/diff_notes_avatars_spec.rb index 989dfb71d10..1b45bb73863 100644 --- a/spec/features/merge_requests/diff_notes_avatars_spec.rb +++ b/spec/features/merge_requests/diff_notes_avatars_spec.rb @@ -25,7 +25,7 @@ feature 'Diff note avatars', feature: true, js: true do context 'discussion tab' do before do - visit namespace_project_merge_request_path(project.namespace, project, merge_request) + visit project_merge_request_path(project, merge_request) end it 'does not show avatars on discussion tab' do @@ -50,7 +50,7 @@ feature 'Diff note avatars', feature: true, js: true do context 'commit view' do before do - visit namespace_project_commit_path(project.namespace, project, merge_request.commits.first.id) + visit project_commit_path(project, merge_request.commits.first.id) end it 'does not render avatar after commenting' do @@ -65,7 +65,7 @@ feature 'Diff note avatars', feature: true, js: true do wait_for_requests end - visit namespace_project_merge_request_path(project.namespace, project, merge_request) + visit project_merge_request_path(project, merge_request) expect(page).to have_content('test comment') expect(page).not_to have_selector('.js-avatar-container') @@ -76,7 +76,7 @@ feature 'Diff note avatars', feature: true, js: true do %w(inline parallel).each do |view| context "#{view} view" do before do - visit diffs_namespace_project_merge_request_path(project.namespace, project, merge_request, view: view) + visit diffs_project_merge_request_path(project, merge_request, view: view) wait_for_requests end @@ -168,7 +168,7 @@ feature 'Diff note avatars', feature: true, js: true do before do create_list(:diff_note_on_merge_request, 3, project: project, noteable: merge_request, in_reply_to: note) - visit diffs_namespace_project_merge_request_path(project.namespace, project, merge_request, view: view) + visit diffs_project_merge_request_path(project, merge_request, view: view) wait_for_requests end diff --git a/spec/features/merge_requests/diff_notes_resolve_spec.rb b/spec/features/merge_requests/diff_notes_resolve_spec.rb index 0f8ca6f90d1..21dce185085 100644 --- a/spec/features/merge_requests/diff_notes_resolve_spec.rb +++ b/spec/features/merge_requests/diff_notes_resolve_spec.rb @@ -494,6 +494,6 @@ feature 'Diff notes resolve', feature: true, js: true do def visit_merge_request(mr = nil) mr = mr || merge_request - visit namespace_project_merge_request_path(mr.project.namespace, mr.project, mr) + visit project_merge_request_path(mr.project, mr) end end diff --git a/spec/features/merge_requests/diffs_spec.rb b/spec/features/merge_requests/diffs_spec.rb index cb6cd6571a8..35976b615ad 100644 --- a/spec/features/merge_requests/diffs_spec.rb +++ b/spec/features/merge_requests/diffs_spec.rb @@ -12,7 +12,7 @@ feature 'Diffs URL', js: true, feature: true do it 'renders the notes' do create :note_on_merge_request, project: project, noteable: merge_request, note: 'Rebasing with master' - visit diffs_namespace_project_merge_request_path(project.namespace, project, merge_request) + visit diffs_project_merge_request_path(project, merge_request) # Load notes and diff through AJAX expect(page).to have_css('.note-text', visible: false, text: 'Rebasing with master') @@ -26,7 +26,7 @@ feature 'Diffs URL', js: true, feature: true do let(:fragment) { "#note_#{note.id}" } before do - visit "#{diffs_namespace_project_merge_request_path(project.namespace, project, merge_request)}#{fragment}" + visit "#{diffs_project_merge_request_path(project, merge_request)}#{fragment}" end it 'shows expanded note' do @@ -39,7 +39,7 @@ feature 'Diffs URL', js: true, feature: true do let(:fragment) { "#note_#{note.id}" } before do - visit "#{diffs_namespace_project_merge_request_path(project.namespace, project, merge_request)}#{fragment}" + visit "#{diffs_project_merge_request_path(project, merge_request)}#{fragment}" end it 'shows expanded note' do @@ -52,7 +52,7 @@ feature 'Diffs URL', js: true, feature: true do it 'displays warning' do allow(Commit).to receive(:max_diff_options).and_return(max_files: 3) - visit diffs_namespace_project_merge_request_path(project.namespace, project, merge_request) + visit diffs_project_merge_request_path(project, merge_request) page.within('.alert') do expect(page).to have_text("Too many changes to show. Plain diff Email patch To preserve @@ -75,7 +75,7 @@ feature 'Diffs URL', js: true, feature: true do context 'as author' do it 'shows direct edit link' do gitlab_sign_in(author_user) - visit diffs_namespace_project_merge_request_path(project.namespace, project, merge_request) + visit diffs_project_merge_request_path(project, merge_request) # Throws `Capybara::Poltergeist::InvalidSelector` if we try to use `#hash` syntax expect(page).to have_selector("[id=\"#{changelog_id}\"] a.js-edit-blob") @@ -85,7 +85,7 @@ feature 'Diffs URL', js: true, feature: true do context 'as user who needs to fork' do it 'shows fork/cancel confirmation' do gitlab_sign_in(user) - visit diffs_namespace_project_merge_request_path(project.namespace, project, merge_request) + visit diffs_project_merge_request_path(project, merge_request) # Throws `Capybara::Poltergeist::InvalidSelector` if we try to use `#hash` syntax find("[id=\"#{changelog_id}\"] .js-edit-blob").click diff --git a/spec/features/merge_requests/discussion_spec.rb b/spec/features/merge_requests/discussion_spec.rb index 88ae257236c..a50f66cfc64 100644 --- a/spec/features/merge_requests/discussion_spec.rb +++ b/spec/features/merge_requests/discussion_spec.rb @@ -27,13 +27,13 @@ feature 'Merge Request Discussions', feature: true do let(:outdated_diff_refs) { project.commit("874797c3a73b60d2187ed6e2fcabd289ff75171e").diff_refs } before(:each) do - visit namespace_project_merge_request_path(project.namespace, project, merge_request) + visit project_merge_request_path(project, merge_request) end context 'active discussions' do it 'shows a link to the diff' do within(".discussion[data-discussion-id='#{active_discussion.id}']") do - path = diffs_namespace_project_merge_request_path(project.namespace, project, merge_request, anchor: active_discussion.line_code) + path = diffs_project_merge_request_path(project, merge_request, anchor: active_discussion.line_code) expect(page).to have_link('the diff', href: path) end end @@ -42,7 +42,7 @@ feature 'Merge Request Discussions', feature: true do context 'outdated discussions' do it 'shows a link to the outdated diff' do within(".discussion[data-discussion-id='#{outdated_discussion.id}']") do - path = diffs_namespace_project_merge_request_path(project.namespace, project, merge_request, diff_id: old_merge_request_diff.id, anchor: outdated_discussion.line_code) + path = diffs_project_merge_request_path(project, merge_request, diff_id: old_merge_request_diff.id, anchor: outdated_discussion.line_code) expect(page).to have_link('an old version of the diff', href: path) end end @@ -72,7 +72,7 @@ feature 'Merge Request Discussions', feature: true do end before(:each) do - visit namespace_project_merge_request_path(project.namespace, project, merge_request) + visit project_merge_request_path(project, merge_request) end context 'a regular commit comment' do diff --git a/spec/features/merge_requests/edit_mr_spec.rb b/spec/features/merge_requests/edit_mr_spec.rb index 804bf6967d6..8ee78526232 100644 --- a/spec/features/merge_requests/edit_mr_spec.rb +++ b/spec/features/merge_requests/edit_mr_spec.rb @@ -10,7 +10,7 @@ feature 'Edit Merge Request', feature: true do gitlab_sign_in user - visit edit_namespace_project_merge_request_path(project.namespace, project, merge_request) + visit edit_project_merge_request_path(project, merge_request) end context 'editing a MR' do @@ -33,7 +33,7 @@ feature 'Edit Merge Request', feature: true do merge_request.update(merge_params: { 'force_remove_source_branch' => '1' }) expect(merge_request.merge_params['force_remove_source_branch']).to be_truthy - visit edit_namespace_project_merge_request_path(project.namespace, project, merge_request) + visit edit_project_merge_request_path(project, merge_request) uncheck 'Remove source branch when merge request is accepted' click_button 'Save changes' diff --git a/spec/features/merge_requests/filter_by_labels_spec.rb b/spec/features/merge_requests/filter_by_labels_spec.rb index 9b677aeca0a..e3d48128aeb 100644 --- a/spec/features/merge_requests/filter_by_labels_spec.rb +++ b/spec/features/merge_requests/filter_by_labels_spec.rb @@ -28,7 +28,7 @@ feature 'Issue filtering by Labels', feature: true, js: true do project.team << [user, :master] gitlab_sign_in(user) - visit namespace_project_merge_requests_path(project.namespace, project) + visit project_merge_requests_path(project) end context 'filter by label bug' do diff --git a/spec/features/merge_requests/filter_merge_requests_spec.rb b/spec/features/merge_requests/filter_merge_requests_spec.rb index c12edf1fdf3..2a62cda6d84 100644 --- a/spec/features/merge_requests/filter_merge_requests_spec.rb +++ b/spec/features/merge_requests/filter_merge_requests_spec.rb @@ -17,7 +17,7 @@ describe 'Filter merge requests', feature: true do gitlab_sign_in(user) create(:merge_request, source_project: project, target_project: project) - visit namespace_project_merge_requests_path(project.namespace, project) + visit project_merge_requests_path(project) end describe 'for assignee from mr#index' do @@ -191,7 +191,7 @@ describe 'Filter merge requests', feature: true do assignee: user) mr.labels << bug_label - visit namespace_project_merge_requests_path(project.namespace, project) + visit project_merge_requests_path(project) end context 'only text', js: true do @@ -275,7 +275,7 @@ describe 'Filter merge requests', feature: true do mr1.labels << bug_label mr2.labels << bug_label - visit namespace_project_merge_requests_path(project.namespace, project) + visit project_merge_requests_path(project) end it 'is able to filter and sort merge requests' do @@ -297,7 +297,7 @@ describe 'Filter merge requests', feature: true do describe 'filter by assignee id', js: true do it 'filter by current user' do - visit namespace_project_merge_requests_path(project.namespace, project, assignee_id: user.id) + visit project_merge_requests_path(project, assignee_id: user.id) expect_tokens([{ name: 'assignee', value: "@#{user.username}" }]) expect_filtered_search_input_empty @@ -307,7 +307,7 @@ describe 'Filter merge requests', feature: true do new_user = create(:user) project.add_developer(new_user) - visit namespace_project_merge_requests_path(project.namespace, project, assignee_id: new_user.id) + visit project_merge_requests_path(project, assignee_id: new_user.id) expect_tokens([{ name: 'assignee', value: "@#{new_user.username}" }]) expect_filtered_search_input_empty @@ -316,7 +316,7 @@ describe 'Filter merge requests', feature: true do describe 'filter by author id', js: true do it 'filter by current user' do - visit namespace_project_merge_requests_path(project.namespace, project, author_id: user.id) + visit project_merge_requests_path(project, author_id: user.id) expect_tokens([{ name: 'author', value: "@#{user.username}" }]) expect_filtered_search_input_empty @@ -326,7 +326,7 @@ describe 'Filter merge requests', feature: true do new_user = create(:user) project.add_developer(new_user) - visit namespace_project_merge_requests_path(project.namespace, project, author_id: new_user.id) + visit project_merge_requests_path(project, author_id: new_user.id) expect_tokens([{ name: 'author', value: "@#{new_user.username}" }]) expect_filtered_search_input_empty diff --git a/spec/features/merge_requests/form_spec.rb b/spec/features/merge_requests/form_spec.rb index d03d498ce21..8f2857c66f7 100644 --- a/spec/features/merge_requests/form_spec.rb +++ b/spec/features/merge_requests/form_spec.rb @@ -1,8 +1,6 @@ require 'rails_helper' describe 'New/edit merge request', feature: true, js: true do - include GitlabRoutingHelper - let!(:project) { create(:project, visibility_level: Gitlab::VisibilityLevel::PUBLIC) } let(:fork_project) { create(:project, forked_from_project: project) } let!(:user) { create(:user)} @@ -23,8 +21,7 @@ describe 'New/edit merge request', feature: true, js: true do context 'new merge request' do before do - visit namespace_project_new_merge_request_path( - project.namespace, + visit project_new_merge_request_path( project, merge_request: { source_project_id: project.id, @@ -114,7 +111,7 @@ describe 'New/edit merge request', feature: true, js: true do target_branch: 'master' ) - visit edit_namespace_project_merge_request_path(project.namespace, project, merge_request) + visit edit_project_merge_request_path(project, merge_request) end it 'updates merge request' do @@ -182,8 +179,7 @@ describe 'New/edit merge request', feature: true, js: true do context 'new merge request' do before do - visit namespace_project_new_merge_request_path( - fork_project.namespace, + visit project_new_merge_request_path( fork_project, merge_request: { source_project_id: fork_project.id, @@ -251,7 +247,7 @@ describe 'New/edit merge request', feature: true, js: true do target_branch: 'master' ) - visit edit_namespace_project_merge_request_path(project.namespace, project, merge_request) + visit edit_project_merge_request_path(project, merge_request) end it 'should update merge request' do diff --git a/spec/features/merge_requests/merge_commit_message_toggle_spec.rb b/spec/features/merge_requests/merge_commit_message_toggle_spec.rb index 27ba380b005..831c60625f4 100644 --- a/spec/features/merge_requests/merge_commit_message_toggle_spec.rb +++ b/spec/features/merge_requests/merge_commit_message_toggle_spec.rb @@ -36,7 +36,7 @@ feature 'Clicking toggle commit message link', feature: true, js: true do gitlab_sign_in user - visit namespace_project_merge_request_path(project.namespace, project, merge_request) + visit project_merge_request_path(project, merge_request) expect(page).not_to have_selector('.js-commit-message') click_button "Modify commit message" diff --git a/spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb b/spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb index 8af7d985036..716f829295e 100644 --- a/spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb +++ b/spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb @@ -29,7 +29,7 @@ feature 'Merge immediately', :feature, :js do before do gitlab_sign_in user - visit namespace_project_merge_request_path(merge_request.project.namespace, merge_request.project, merge_request) + visit project_merge_request_path(merge_request.project, merge_request) end it 'enables merge immediately' do diff --git a/spec/features/merge_requests/merge_when_pipeline_succeeds_spec.rb b/spec/features/merge_requests/merge_when_pipeline_succeeds_spec.rb index bfadd7cb81a..2a4178a819b 100644 --- a/spec/features/merge_requests/merge_when_pipeline_succeeds_spec.rb +++ b/spec/features/merge_requests/merge_when_pipeline_succeeds_spec.rb @@ -155,6 +155,6 @@ feature 'Merge When Pipeline Succeeds', :feature, :js do end def visit_merge_request(merge_request) - visit namespace_project_merge_request_path(merge_request.project.namespace, merge_request.project, merge_request) + visit project_merge_request_path(merge_request.project, merge_request) end end diff --git a/spec/features/merge_requests/mini_pipeline_graph_spec.rb b/spec/features/merge_requests/mini_pipeline_graph_spec.rb index 7664fbfbb4c..2c0632a4e82 100644 --- a/spec/features/merge_requests/mini_pipeline_graph_spec.rb +++ b/spec/features/merge_requests/mini_pipeline_graph_spec.rb @@ -16,7 +16,7 @@ feature 'Mini Pipeline Graph', :js, :feature do end def visit_merge_request(format = :html) - visit namespace_project_merge_request_path(project.namespace, project, merge_request, format: format) + visit project_merge_request_path(project, merge_request, format: format) end it 'should display a mini pipeline graph' do @@ -111,7 +111,7 @@ feature 'Mini Pipeline Graph', :js, :feature do build_item.click find('.build-page') - expect(current_path).to eql(namespace_project_job_path(project.namespace, project, build)) + expect(current_path).to eql(project_job_path(project, build)) end it 'should show tooltip when hovered' do diff --git a/spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb b/spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb index 5cd9a7fbe26..6bcfef71d25 100644 --- a/spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb +++ b/spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb @@ -145,6 +145,6 @@ feature 'Only allow merge requests to be merged if the pipeline succeeds', featu end def visit_merge_request(merge_request) - visit namespace_project_merge_request_path(merge_request.project.namespace, merge_request.project, merge_request) + visit project_merge_request_path(merge_request.project, merge_request) end end diff --git a/spec/features/merge_requests/pipelines_spec.rb b/spec/features/merge_requests/pipelines_spec.rb index c2241317e04..d55e6329a9f 100644 --- a/spec/features/merge_requests/pipelines_spec.rb +++ b/spec/features/merge_requests/pipelines_spec.rb @@ -19,7 +19,7 @@ feature 'Pipelines for Merge Requests', feature: true, js: true do end before do - visit namespace_project_merge_request_path(project.namespace, project, merge_request) + visit project_merge_request_path(project, merge_request) end scenario 'user visits merge request pipelines tab' do @@ -34,7 +34,7 @@ feature 'Pipelines for Merge Requests', feature: true, js: true do context 'without pipelines' do before do - visit namespace_project_merge_request_path(project.namespace, project, merge_request) + visit project_merge_request_path(project, merge_request) end scenario 'user visits merge request page' do diff --git a/spec/features/merge_requests/target_branch_spec.rb b/spec/features/merge_requests/target_branch_spec.rb index 4328d66c748..c61f817dd9a 100644 --- a/spec/features/merge_requests/target_branch_spec.rb +++ b/spec/features/merge_requests/target_branch_spec.rb @@ -6,10 +6,7 @@ describe 'Target branch', feature: true, js: true do let(:project) { merge_request.project } def path_to_merge_request - namespace_project_merge_request_path( - project.namespace, - project, merge_request - ) + project_merge_request_path(project, merge_request) end before do diff --git a/spec/features/merge_requests/toggle_whitespace_changes_spec.rb b/spec/features/merge_requests/toggle_whitespace_changes_spec.rb index cba9a2cda99..ae7e99d1462 100644 --- a/spec/features/merge_requests/toggle_whitespace_changes_spec.rb +++ b/spec/features/merge_requests/toggle_whitespace_changes_spec.rb @@ -5,7 +5,7 @@ feature 'Toggle Whitespace Changes', js: true, feature: true do gitlab_sign_in :admin merge_request = create(:merge_request) project = merge_request.source_project - visit diffs_namespace_project_merge_request_path(project.namespace, project, merge_request) + visit diffs_project_merge_request_path(project, merge_request) end it 'has a button to toggle whitespace changes' do diff --git a/spec/features/merge_requests/toggler_behavior_spec.rb b/spec/features/merge_requests/toggler_behavior_spec.rb index c4c06e9a7a0..219b9fd8938 100644 --- a/spec/features/merge_requests/toggler_behavior_spec.rb +++ b/spec/features/merge_requests/toggler_behavior_spec.rb @@ -11,7 +11,7 @@ feature 'toggler_behavior', js: true, feature: true do gitlab_sign_in :admin project = merge_request.source_project page.current_window.resize_to(1000, 300) - visit "#{namespace_project_merge_request_path(project.namespace, project, merge_request)}#{fragment_id}" + visit "#{project_merge_request_path(project, merge_request)}#{fragment_id}" end describe 'scroll position' do diff --git a/spec/features/merge_requests/update_merge_requests_spec.rb b/spec/features/merge_requests/update_merge_requests_spec.rb index d0418c74699..f8f3e377198 100644 --- a/spec/features/merge_requests/update_merge_requests_spec.rb +++ b/spec/features/merge_requests/update_merge_requests_spec.rb @@ -13,7 +13,7 @@ feature 'Multiple merge requests updating from merge_requests#index', feature: t context 'status', js: true do describe 'close merge request' do before do - visit namespace_project_merge_requests_path(project.namespace, project) + visit project_merge_requests_path(project) end it 'closes merge request' do @@ -26,7 +26,7 @@ feature 'Multiple merge requests updating from merge_requests#index', feature: t describe 'reopen merge request' do before do merge_request.close - visit namespace_project_merge_requests_path(project.namespace, project, state: 'closed') + visit project_merge_requests_path(project, state: 'closed') end it 'reopens merge request' do @@ -40,7 +40,7 @@ feature 'Multiple merge requests updating from merge_requests#index', feature: t context 'assignee', js: true do describe 'set assignee' do before do - visit namespace_project_merge_requests_path(project.namespace, project) + visit project_merge_requests_path(project) end it "updates merge request with assignee" do @@ -56,7 +56,7 @@ feature 'Multiple merge requests updating from merge_requests#index', feature: t before do merge_request.assignee = user merge_request.save - visit namespace_project_merge_requests_path(project.namespace, project) + visit project_merge_requests_path(project) end it "removes assignee from the merge request" do @@ -72,7 +72,7 @@ feature 'Multiple merge requests updating from merge_requests#index', feature: t describe 'set milestone' do before do - visit namespace_project_merge_requests_path(project.namespace, project) + visit project_merge_requests_path(project) end it "updates merge request with milestone" do @@ -86,7 +86,7 @@ feature 'Multiple merge requests updating from merge_requests#index', feature: t before do merge_request.milestone = milestone merge_request.save - visit namespace_project_merge_requests_path(project.namespace, project) + visit project_merge_requests_path(project) end it "removes milestone from the merge request" do diff --git a/spec/features/merge_requests/user_lists_merge_requests_spec.rb b/spec/features/merge_requests/user_lists_merge_requests_spec.rb index cabb8e455f9..f541f495995 100644 --- a/spec/features/merge_requests/user_lists_merge_requests_spec.rb +++ b/spec/features/merge_requests/user_lists_merge_requests_spec.rb @@ -37,7 +37,7 @@ describe 'Projects > Merge requests > User lists merge requests', feature: true it 'filters on no assignee' do visit_merge_requests(project, assignee_id: IssuableFinder::NONE) - expect(current_path).to eq(namespace_project_merge_requests_path(project.namespace, project)) + expect(current_path).to eq(project_merge_requests_path(project)) expect(page).to have_content 'merge_lfs' expect(page).not_to have_content 'fix' expect(page).not_to have_content 'markdown' @@ -136,7 +136,7 @@ describe 'Projects > Merge requests > User lists merge requests', feature: true end it 'sorts by recently due milestone' do - visit namespace_project_merge_requests_path(project.namespace, project, + visit project_merge_requests_path(project, label_name: [label.name, label2.name], assignee_id: user.id, sort: sort_value_milestone_soon) diff --git a/spec/features/merge_requests/user_posts_diff_notes_spec.rb b/spec/features/merge_requests/user_posts_diff_notes_spec.rb index ac7e0eb2727..7b1ac60231a 100644 --- a/spec/features/merge_requests/user_posts_diff_notes_spec.rb +++ b/spec/features/merge_requests/user_posts_diff_notes_spec.rb @@ -17,7 +17,7 @@ feature 'Merge requests > User posts diff notes', :js do context 'when hovering over a parallel view diff file' do before do - visit diffs_namespace_project_merge_request_path(project.namespace, project, merge_request, view: 'parallel') + visit diffs_project_merge_request_path(project, merge_request, view: 'parallel') end context 'with an old line on the left and no line on the right' do @@ -92,7 +92,7 @@ feature 'Merge requests > User posts diff notes', :js do context 'when hovering over an inline view diff file' do before do - visit diffs_namespace_project_merge_request_path(project.namespace, project, merge_request, view: 'inline') + visit diffs_project_merge_request_path(project, merge_request, view: 'inline') end context 'with a new line' do @@ -136,9 +136,9 @@ feature 'Merge requests > User posts diff notes', :js do context 'when hovering over a diff discussion' do before do - visit diffs_namespace_project_merge_request_path(project.namespace, project, merge_request, view: 'inline') + visit diffs_project_merge_request_path(project, merge_request, view: 'inline') should_allow_commenting(find('[id="2f6fcd96b88b36ce98c38da085c795a27d92a3dd_7_7"]')) - visit namespace_project_merge_request_path(project.namespace, project, merge_request) + visit project_merge_request_path(project, merge_request) end it 'does not allow commenting' do @@ -149,7 +149,7 @@ feature 'Merge requests > User posts diff notes', :js do context 'when cancelling the comment addition' do before do - visit diffs_namespace_project_merge_request_path(project.namespace, project, merge_request, view: 'inline') + visit diffs_project_merge_request_path(project, merge_request, view: 'inline') end context 'with a new line' do @@ -161,7 +161,7 @@ feature 'Merge requests > User posts diff notes', :js do describe 'with muliple note forms' do before do - visit diffs_namespace_project_merge_request_path(project.namespace, project, merge_request, view: 'inline') + visit diffs_project_merge_request_path(project, merge_request, view: 'inline') click_diff_line(find('[id="2f6fcd96b88b36ce98c38da085c795a27d92a3dd_10_9"]')) click_diff_line(find('[id="6eb14e00385d2fb284765eb1cd8d420d33d63fc9_22_22"]')) end @@ -181,7 +181,7 @@ feature 'Merge requests > User posts diff notes', :js do context 'when the MR only supports legacy diff notes' do before do merge_request.merge_request_diff.update_attributes(start_commit_sha: nil) - visit diffs_namespace_project_merge_request_path(project.namespace, project, merge_request, view: 'inline') + visit diffs_project_merge_request_path(project, merge_request, view: 'inline') end context 'with a new line' do diff --git a/spec/features/merge_requests/user_posts_notes_spec.rb b/spec/features/merge_requests/user_posts_notes_spec.rb index 12f987e12ea..b3c8b0e9c34 100644 --- a/spec/features/merge_requests/user_posts_notes_spec.rb +++ b/spec/features/merge_requests/user_posts_notes_spec.rb @@ -14,7 +14,7 @@ describe 'Merge requests > User posts notes', :js do before do gitlab_sign_in :admin - visit namespace_project_merge_request_path(project.namespace, project, merge_request) + visit project_merge_request_path(project, merge_request) end subject { page } diff --git a/spec/features/merge_requests/user_sees_system_notes_spec.rb b/spec/features/merge_requests/user_sees_system_notes_spec.rb index 0d88a8172b0..385708a28c5 100644 --- a/spec/features/merge_requests/user_sees_system_notes_spec.rb +++ b/spec/features/merge_requests/user_sees_system_notes_spec.rb @@ -15,7 +15,7 @@ feature 'Merge requests > User sees system notes' do end it 'shows the system note' do - visit namespace_project_merge_request_path(public_project.namespace, public_project, merge_request) + visit project_merge_request_path(public_project, merge_request) expect(page).to have_css('.system-note') end @@ -23,7 +23,7 @@ feature 'Merge requests > User sees system notes' do context 'when not logged-in' do it 'hides the system note' do - visit namespace_project_merge_request_path(public_project.namespace, public_project, merge_request) + visit project_merge_request_path(public_project, merge_request) expect(page).not_to have_css('.system-note') end diff --git a/spec/features/merge_requests/user_uses_slash_commands_spec.rb b/spec/features/merge_requests/user_uses_slash_commands_spec.rb index a1f123f15ec..229dcda7ce4 100644 --- a/spec/features/merge_requests/user_uses_slash_commands_spec.rb +++ b/spec/features/merge_requests/user_uses_slash_commands_spec.rb @@ -17,7 +17,7 @@ feature 'Merge Requests > User uses quick actions', feature: true, js: true do before do project.team << [user, :master] gitlab_sign_in(user) - visit namespace_project_merge_request_path(project.namespace, project, merge_request) + visit project_merge_request_path(project, merge_request) end after do @@ -53,7 +53,7 @@ feature 'Merge Requests > User uses quick actions', feature: true, js: true do project.team << [guest, :guest] gitlab_sign_out gitlab_sign_in(guest) - visit namespace_project_merge_request_path(project.namespace, project, merge_request) + visit project_merge_request_path(project, merge_request) end it 'does not change the WIP prefix' do @@ -99,7 +99,7 @@ feature 'Merge Requests > User uses quick actions', feature: true, js: true do project.team << [guest, :guest] gitlab_sign_out gitlab_sign_in(guest) - visit namespace_project_merge_request_path(project.namespace, project, merge_request) + visit project_merge_request_path(project, merge_request) end it 'does not merge the MR' do @@ -131,7 +131,7 @@ feature 'Merge Requests > User uses quick actions', feature: true, js: true do end it 'changes target_branch in new merge_request' do - visit namespace_project_new_merge_request_path(another_project.namespace, another_project, new_url_opts) + visit project_new_merge_request_path(another_project, new_url_opts) fill_in "merge_request_title", with: 'My brand new feature' fill_in "merge_request_description", with: "le feature \n/target_branch fix\nFeature description:" @@ -145,7 +145,7 @@ feature 'Merge Requests > User uses quick actions', feature: true, js: true do it 'does not change target branch when merge request is edited' do new_merge_request = create(:merge_request, source_project: another_project) - visit edit_namespace_project_merge_request_path(another_project.namespace, another_project, new_merge_request) + visit edit_project_merge_request_path(another_project, new_merge_request) fill_in "merge_request_description", with: "Want to update target branch\n/target_branch fix\n" click_button "Save changes" @@ -183,7 +183,7 @@ feature 'Merge Requests > User uses quick actions', feature: true, js: true do project.team << [guest, :guest] gitlab_sign_out gitlab_sign_in(guest) - visit namespace_project_merge_request_path(project.namespace, project, merge_request) + visit project_merge_request_path(project, merge_request) end it 'does not change target branch' do diff --git a/spec/features/merge_requests/versions_spec.rb b/spec/features/merge_requests/versions_spec.rb index 04a72d3be34..94fcfa398c9 100644 --- a/spec/features/merge_requests/versions_spec.rb +++ b/spec/features/merge_requests/versions_spec.rb @@ -9,7 +9,7 @@ feature 'Merge Request versions', js: true, feature: true do before do gitlab_sign_in :admin - visit diffs_namespace_project_merge_request_path(project.namespace, project, merge_request) + visit diffs_project_merge_request_path(project, merge_request) end it 'show the latest version of the diff' do @@ -96,8 +96,7 @@ feature 'Merge Request versions', js: true, feature: true do end it 'has a path with comparison context' do - expect(page).to have_current_path diffs_namespace_project_merge_request_path( - project.namespace, + expect(page).to have_current_path diffs_project_merge_request_path( project, merge_request.iid, diff_id: merge_request_diff3.id, diff --git a/spec/features/merge_requests/widget_deployments_spec.rb b/spec/features/merge_requests/widget_deployments_spec.rb index e82e69c5f4a..c43c7460a08 100644 --- a/spec/features/merge_requests/widget_deployments_spec.rb +++ b/spec/features/merge_requests/widget_deployments_spec.rb @@ -14,7 +14,7 @@ feature 'Widget Deployments Header', feature: true, js: true do background do gitlab_sign_in(user) project.team << [user, role] - visit namespace_project_merge_request_path(project.namespace, project, merge_request) + visit project_merge_request_path(project, merge_request) end scenario 'displays that the environment is deployed' do diff --git a/spec/features/merge_requests/widget_spec.rb b/spec/features/merge_requests/widget_spec.rb index d8e9b949204..8135411fe03 100644 --- a/spec/features/merge_requests/widget_spec.rb +++ b/spec/features/merge_requests/widget_spec.rb @@ -12,8 +12,7 @@ describe 'Merge request', :feature, :js do context 'new merge request' do before do - visit namespace_project_new_merge_request_path( - project.namespace, + visit project_new_merge_request_path( project, merge_request: { source_project_id: project.id, @@ -44,7 +43,7 @@ describe 'Merge request', :feature, :js do end before do - visit namespace_project_merge_request_path(project.namespace, project, merge_request) + visit project_merge_request_path(project, merge_request) end it 'shows environments link' do @@ -71,7 +70,7 @@ describe 'Merge request', :feature, :js do type: 'CiService', category: 'ci') - visit namespace_project_merge_request_path(project.namespace, project, merge_request) + visit project_merge_request_path(project, merge_request) end it 'has danger button while waiting for external CI status' do @@ -92,7 +91,7 @@ describe 'Merge request', :feature, :js do head_pipeline_of: merge_request) create(:ci_build, :pending, pipeline: pipeline) - visit namespace_project_merge_request_path(project.namespace, project, merge_request) + visit project_merge_request_path(project, merge_request) end it 'has danger button when not succeeded' do @@ -112,9 +111,7 @@ describe 'Merge request', :feature, :js do status: :manual, head_pipeline_of: merge_request) - visit namespace_project_merge_request_path(project.namespace, - project, - merge_request) + visit project_merge_request_path(project, merge_request) end it 'shows information about blocked pipeline' do @@ -136,7 +133,7 @@ describe 'Merge request', :feature, :js do head_pipeline_of: merge_request) create(:ci_build, :pending, pipeline: pipeline) - visit namespace_project_merge_request_path(project.namespace, project, merge_request) + visit project_merge_request_path(project, merge_request) end it 'has info button when MWBS button' do @@ -154,7 +151,7 @@ describe 'Merge request', :feature, :js do merge_error: 'Something went wrong' ) - visit namespace_project_merge_request_path(project.namespace, project, merge_request) + visit project_merge_request_path(project, merge_request) end it 'shows information about the merge error' do @@ -175,7 +172,7 @@ describe 'Merge request', :feature, :js do merge_error: 'Something went wrong' ) - visit namespace_project_merge_request_path(project.namespace, project, merge_request) + visit project_merge_request_path(project, merge_request) end it 'shows information about the merge error' do @@ -191,7 +188,7 @@ describe 'Merge request', :feature, :js do context 'merge error' do before do allow_any_instance_of(Repository).to receive(:merge).and_return(false) - visit namespace_project_merge_request_path(project.namespace, project, merge_request) + visit project_merge_request_path(project, merge_request) end it 'updates the MR widget' do @@ -212,7 +209,7 @@ describe 'Merge request', :feature, :js do gitlab_sign_out gitlab_sign_in user2 merge_request.update(target_project: fork_project) - visit namespace_project_merge_request_path(project.namespace, project, merge_request) + visit project_merge_request_path(project, merge_request) end it 'user can merge into the source project' do diff --git a/spec/features/merge_requests/wip_message_spec.rb b/spec/features/merge_requests/wip_message_spec.rb index 0e304ba50af..224723773bf 100644 --- a/spec/features/merge_requests/wip_message_spec.rb +++ b/spec/features/merge_requests/wip_message_spec.rb @@ -11,8 +11,7 @@ feature 'Work In Progress help message', feature: true do context 'with WIP commits' do it 'shows a specific WIP hint' do - visit namespace_project_new_merge_request_path( - project.namespace, + visit project_new_merge_request_path( project, merge_request: { source_project_id: project.id, @@ -32,8 +31,7 @@ feature 'Work In Progress help message', feature: true do context 'without WIP commits' do it 'shows the regular WIP message' do - visit namespace_project_new_merge_request_path( - project.namespace, + visit project_new_merge_request_path( project, merge_request: { source_project_id: project.id, diff --git a/spec/features/milestone_spec.rb b/spec/features/milestone_spec.rb index 58989581ffe..880c53343bc 100644 --- a/spec/features/milestone_spec.rb +++ b/spec/features/milestone_spec.rb @@ -11,7 +11,7 @@ feature 'Milestone', feature: true do feature 'Create a milestone' do scenario 'shows an informative message for a new milestone' do - visit new_namespace_project_milestone_path(project.namespace, project) + visit new_project_milestone_path(project) page.within '.milestone-form' do fill_in "milestone_title", with: '8.7' @@ -31,7 +31,7 @@ feature 'Milestone', feature: true do milestone = create(:milestone, project: project, title: 8.7) create(:issue, title: "Bugfix1", project: project, milestone: milestone, state: "closed") - visit namespace_project_milestone_path(project.namespace, project, milestone) + visit project_milestone_path(project, milestone) expect(find('.alert-success')).to have_content('All issues for this milestone are closed. You may close this milestone now.') end @@ -41,7 +41,7 @@ feature 'Milestone', feature: true do scenario 'displays validation message' do milestone = create(:milestone, project: project, title: 8.7) - visit new_namespace_project_milestone_path(project.namespace, project) + visit new_project_milestone_path(project) page.within '.milestone-form' do fill_in "milestone_title", with: milestone.title end diff --git a/spec/features/milestones/show_spec.rb b/spec/features/milestones/show_spec.rb index cdf6cfba402..fc7d2f9662d 100644 --- a/spec/features/milestones/show_spec.rb +++ b/spec/features/milestones/show_spec.rb @@ -13,7 +13,7 @@ describe 'Milestone show', feature: true do end def visit_milestone - visit namespace_project_milestone_path(project.namespace, project, milestone) + visit project_milestone_path(project, milestone) end it 'avoids N+1 database queries' do diff --git a/spec/features/oauth_login_spec.rb b/spec/features/oauth_login_spec.rb new file mode 100644 index 00000000000..1b6d1f3415f --- /dev/null +++ b/spec/features/oauth_login_spec.rb @@ -0,0 +1,112 @@ +require 'spec_helper' + +feature 'OAuth Login', js: true do + def enter_code(code) + fill_in 'user_otp_attempt', with: code + click_button 'Verify code' + end + + def stub_omniauth_config(provider) + OmniAuth.config.add_mock(provider, OmniAuth::AuthHash.new(provider: provider.to_s, uid: "12345")) + Rails.application.env_config['devise.mapping'] = Devise.mappings[:user] + Rails.application.env_config['omniauth.auth'] = OmniAuth.config.mock_auth[provider] + end + + providers = [:github, :twitter, :bitbucket, :gitlab, :google_oauth2, + :facebook, :cas3, :auth0] + + before(:all) do + # The OmniAuth `full_host` parameter doesn't get set correctly (it gets set to something like `http://localhost` + # here), and causes integration tests to fail with 404s. We set the `full_host` by removing the request path (and + # anything after it) from the request URI. + @omniauth_config_full_host = OmniAuth.config.full_host + OmniAuth.config.full_host = ->(request) { request['REQUEST_URI'].sub(/#{request['REQUEST_PATH']}.*/, '') } + end + + after(:all) do + OmniAuth.config.full_host = @omniauth_config_full_host + end + + providers.each do |provider| + context "when the user logs in using the #{provider} provider" do + context 'when two-factor authentication is disabled' do + it 'logs the user in' do + stub_omniauth_config(provider) + user = create(:omniauth_user, extern_uid: 'my-uid', provider: provider.to_s) + login_via(provider.to_s, user, 'my-uid') + + expect(current_path).to eq root_path + end + end + + context 'when two-factor authentication is enabled' do + it 'logs the user in' do + stub_omniauth_config(provider) + user = create(:omniauth_user, :two_factor, extern_uid: 'my-uid', provider: provider.to_s) + login_via(provider.to_s, user, 'my-uid') + + enter_code(user.current_otp) + expect(current_path).to eq root_path + end + end + + context 'when "remember me" is checked' do + context 'when two-factor authentication is disabled' do + it 'remembers the user after a browser restart' do + stub_omniauth_config(provider) + user = create(:omniauth_user, extern_uid: 'my-uid', provider: provider.to_s) + login_via(provider.to_s, user, 'my-uid', remember_me: true) + + clear_browser_session + + visit(root_path) + expect(current_path).to eq root_path + end + end + + context 'when two-factor authentication is enabled' do + it 'remembers the user after a browser restart' do + stub_omniauth_config(provider) + user = create(:omniauth_user, :two_factor, extern_uid: 'my-uid', provider: provider.to_s) + login_via(provider.to_s, user, 'my-uid', remember_me: true) + enter_code(user.current_otp) + + clear_browser_session + + visit(root_path) + expect(current_path).to eq root_path + end + end + end + + context 'when "remember me" is not checked' do + context 'when two-factor authentication is disabled' do + it 'does not remember the user after a browser restart' do + stub_omniauth_config(provider) + user = create(:omniauth_user, extern_uid: 'my-uid', provider: provider.to_s) + login_via(provider.to_s, user, 'my-uid', remember_me: false) + + clear_browser_session + + visit(root_path) + expect(current_path).to eq new_user_session_path + end + end + + context 'when two-factor authentication is enabled' do + it 'does not remember the user after a browser restart' do + stub_omniauth_config(provider) + user = create(:omniauth_user, :two_factor, extern_uid: 'my-uid', provider: provider.to_s) + login_via(provider.to_s, user, 'my-uid', remember_me: false) + enter_code(user.current_otp) + + clear_browser_session + + visit(root_path) + expect(current_path).to eq new_user_session_path + end + end + end + end + end +end diff --git a/spec/features/participants_autocomplete_spec.rb b/spec/features/participants_autocomplete_spec.rb index b8966cf621c..a66d0f4abad 100644 --- a/spec/features/participants_autocomplete_spec.rb +++ b/spec/features/participants_autocomplete_spec.rb @@ -29,7 +29,7 @@ feature 'Member autocomplete', :js do context 'adding a new note on a Issue' do let(:noteable) { create(:issue, author: author, project: project) } before do - visit namespace_project_issue_path(project.namespace, project, noteable) + visit project_issue_path(project, noteable) end include_examples "open suggestions when typing @" @@ -42,7 +42,7 @@ feature 'Member autocomplete', :js do target_project: project, author: author) end before do - visit namespace_project_merge_request_path(project.namespace, project, noteable) + visit project_merge_request_path(project, noteable) end include_examples "open suggestions when typing @" @@ -56,7 +56,7 @@ feature 'Member autocomplete', :js do before do allow_any_instance_of(Commit).to receive(:author).and_return(author) - visit namespace_project_commit_path(project.namespace, project, noteable) + visit project_commit_path(project, noteable) end include_examples "open suggestions when typing @" diff --git a/spec/features/projects/activity/rss_spec.rb b/spec/features/projects/activity/rss_spec.rb index 84c81d43448..97925bc2ebf 100644 --- a/spec/features/projects/activity/rss_spec.rb +++ b/spec/features/projects/activity/rss_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' feature 'Project Activity RSS' do let(:project) { create(:empty_project, visibility_level: Gitlab::VisibilityLevel::PUBLIC) } - let(:path) { activity_namespace_project_path(project.namespace, project) } + let(:path) { activity_project_path(project) } before do create(:issue, project: project) diff --git a/spec/features/projects/artifacts/browse_spec.rb b/spec/features/projects/artifacts/browse_spec.rb index 68375956273..a34c0c4cecd 100644 --- a/spec/features/projects/artifacts/browse_spec.rb +++ b/spec/features/projects/artifacts/browse_spec.rb @@ -6,7 +6,7 @@ feature 'Browse artifact', :js, feature: true do let(:job) { create(:ci_build, :artifacts, pipeline: pipeline) } def browse_path(path) - browse_namespace_project_job_artifacts_path(project.namespace, project, job, path) + browse_project_job_artifacts_path(project, job, path) end context 'when visiting old URL' do diff --git a/spec/features/projects/artifacts/download_spec.rb b/spec/features/projects/artifacts/download_spec.rb index dd9454840ee..b76f2be880e 100644 --- a/spec/features/projects/artifacts/download_spec.rb +++ b/spec/features/projects/artifacts/download_spec.rb @@ -22,7 +22,7 @@ feature 'Download artifact', :js, feature: true do context 'via job id' do let(:download_url) do - download_namespace_project_job_artifacts_path(project.namespace, project, job) + download_project_job_artifacts_path(project, job) end it_behaves_like 'downloading' @@ -30,7 +30,7 @@ feature 'Download artifact', :js, feature: true do context 'via branch name and job name' do let(:download_url) do - latest_succeeded_namespace_project_artifacts_path(project.namespace, project, "#{pipeline.ref}/download", job: job.name) + latest_succeeded_project_artifacts_path(project, "#{pipeline.ref}/download", job: job.name) end it_behaves_like 'downloading' @@ -44,7 +44,7 @@ feature 'Download artifact', :js, feature: true do context 'via job id' do let(:download_url) do - download_namespace_project_job_artifacts_path(project.namespace, project, job) + download_project_job_artifacts_path(project, job) end it_behaves_like 'downloading' @@ -52,7 +52,7 @@ feature 'Download artifact', :js, feature: true do context 'via branch name and job name' do let(:download_url) do - latest_succeeded_namespace_project_artifacts_path(project.namespace, project, "#{pipeline.ref}/download", job: job.name) + latest_succeeded_project_artifacts_path(project, "#{pipeline.ref}/download", job: job.name) end it_behaves_like 'downloading' diff --git a/spec/features/projects/artifacts/file_spec.rb b/spec/features/projects/artifacts/file_spec.rb index 860373e531b..6d48470ca3a 100644 --- a/spec/features/projects/artifacts/file_spec.rb +++ b/spec/features/projects/artifacts/file_spec.rb @@ -10,7 +10,7 @@ feature 'Artifact file', :js, feature: true do end def file_path(path) - file_namespace_project_job_artifacts_path(project.namespace, project, build, path) + file_project_job_artifacts_path(project, build, path) end context 'Text file' do diff --git a/spec/features/projects/artifacts/raw_spec.rb b/spec/features/projects/artifacts/raw_spec.rb index b589701729d..3f38d720a0f 100644 --- a/spec/features/projects/artifacts/raw_spec.rb +++ b/spec/features/projects/artifacts/raw_spec.rb @@ -6,7 +6,7 @@ feature 'Raw artifact', :js, feature: true do let(:job) { create(:ci_build, :artifacts, pipeline: pipeline) } def raw_path(path) - raw_namespace_project_job_artifacts_path(project.namespace, project, job, path) + raw_project_job_artifacts_path(project, job, path) end context 'when visiting old URL' do diff --git a/spec/features/projects/badges/coverage_spec.rb b/spec/features/projects/badges/coverage_spec.rb index 9624e1a71b0..efadb640096 100644 --- a/spec/features/projects/badges/coverage_spec.rb +++ b/spec/features/projects/badges/coverage_spec.rb @@ -70,8 +70,7 @@ feature 'test coverage badge' do end def show_test_coverage_badge(job: nil) - visit coverage_namespace_project_badges_path( - project.namespace, project, ref: :master, job: job, format: :svg) + visit coverage_project_badges_path(project, ref: :master, job: job, format: :svg) end def expect_coverage_badge(coverage) diff --git a/spec/features/projects/badges/list_spec.rb b/spec/features/projects/badges/list_spec.rb index 348748152bb..cbd44c49d04 100644 --- a/spec/features/projects/badges/list_spec.rb +++ b/spec/features/projects/badges/list_spec.rb @@ -6,7 +6,7 @@ feature 'list of badges' do project = create(:project) project.team << [user, :master] gitlab_sign_in(user) - visit namespace_project_pipelines_settings_path(project.namespace, project) + visit project_pipelines_settings_path(project) end scenario 'user wants to see build status badge' do diff --git a/spec/features/projects/blobs/blob_line_permalink_updater_spec.rb b/spec/features/projects/blobs/blob_line_permalink_updater_spec.rb index d94204230f6..7564338b301 100644 --- a/spec/features/projects/blobs/blob_line_permalink_updater_spec.rb +++ b/spec/features/projects/blobs/blob_line_permalink_updater_spec.rb @@ -13,14 +13,14 @@ feature 'Blob button line permalinks (BlobLinePermalinkUpdater)', feature: true, end def visit_blob(fragment = nil) - visit namespace_project_blob_path(project.namespace, project, tree_join('master', path), anchor: fragment) + visit project_blob_path(project, tree_join('master', path), anchor: fragment) end describe 'Click "Permalink" button' do it 'works with no initial line number fragment hash' do visit_blob - expect(find('.js-data-file-blob-permalink-url')['href']).to eq(get_absolute_url(namespace_project_blob_path(project.namespace, project, tree_join(sha, path)))) + expect(find('.js-data-file-blob-permalink-url')['href']).to eq(get_absolute_url(project_blob_path(project, tree_join(sha, path)))) end it 'maintains intitial fragment hash' do @@ -28,7 +28,7 @@ feature 'Blob button line permalinks (BlobLinePermalinkUpdater)', feature: true, visit_blob(fragment) - expect(find('.js-data-file-blob-permalink-url')['href']).to eq(get_absolute_url(namespace_project_blob_path(project.namespace, project, tree_join(sha, path), anchor: fragment))) + expect(find('.js-data-file-blob-permalink-url')['href']).to eq(get_absolute_url(project_blob_path(project, tree_join(sha, path), anchor: fragment))) end it 'changes fragment hash if line number clicked' do @@ -39,7 +39,7 @@ feature 'Blob button line permalinks (BlobLinePermalinkUpdater)', feature: true, find('#L3').click find("##{ending_fragment}").click - expect(find('.js-data-file-blob-permalink-url')['href']).to eq(get_absolute_url(namespace_project_blob_path(project.namespace, project, tree_join(sha, path), anchor: ending_fragment))) + expect(find('.js-data-file-blob-permalink-url')['href']).to eq(get_absolute_url(project_blob_path(project, tree_join(sha, path), anchor: ending_fragment))) end it 'with initial fragment hash, changes fragment hash if line number clicked' do @@ -51,7 +51,7 @@ feature 'Blob button line permalinks (BlobLinePermalinkUpdater)', feature: true, find('#L3').click find("##{ending_fragment}").click - expect(find('.js-data-file-blob-permalink-url')['href']).to eq(get_absolute_url(namespace_project_blob_path(project.namespace, project, tree_join(sha, path), anchor: ending_fragment))) + expect(find('.js-data-file-blob-permalink-url')['href']).to eq(get_absolute_url(project_blob_path(project, tree_join(sha, path), anchor: ending_fragment))) end end @@ -59,7 +59,7 @@ feature 'Blob button line permalinks (BlobLinePermalinkUpdater)', feature: true, it 'works with no initial line number fragment hash' do visit_blob - expect(find('.js-blob-blame-link')['href']).to eq(get_absolute_url(namespace_project_blame_path(project.namespace, project, tree_join('master', path)))) + expect(find('.js-blob-blame-link')['href']).to eq(get_absolute_url(project_blame_path(project, tree_join('master', path)))) end it 'maintains intitial fragment hash' do @@ -67,7 +67,7 @@ feature 'Blob button line permalinks (BlobLinePermalinkUpdater)', feature: true, visit_blob(fragment) - expect(find('.js-blob-blame-link')['href']).to eq(get_absolute_url(namespace_project_blame_path(project.namespace, project, tree_join('master', path), anchor: fragment))) + expect(find('.js-blob-blame-link')['href']).to eq(get_absolute_url(project_blame_path(project, tree_join('master', path), anchor: fragment))) end it 'changes fragment hash if line number clicked' do @@ -78,7 +78,7 @@ feature 'Blob button line permalinks (BlobLinePermalinkUpdater)', feature: true, find('#L3').click find("##{ending_fragment}").click - expect(find('.js-blob-blame-link')['href']).to eq(get_absolute_url(namespace_project_blame_path(project.namespace, project, tree_join('master', path), anchor: ending_fragment))) + expect(find('.js-blob-blame-link')['href']).to eq(get_absolute_url(project_blame_path(project, tree_join('master', path), anchor: ending_fragment))) end it 'with initial fragment hash, changes fragment hash if line number clicked' do @@ -90,7 +90,7 @@ feature 'Blob button line permalinks (BlobLinePermalinkUpdater)', feature: true, find('#L3').click find("##{ending_fragment}").click - expect(find('.js-blob-blame-link')['href']).to eq(get_absolute_url(namespace_project_blame_path(project.namespace, project, tree_join('master', path), anchor: ending_fragment))) + expect(find('.js-blob-blame-link')['href']).to eq(get_absolute_url(project_blame_path(project, tree_join('master', path), anchor: ending_fragment))) end end end diff --git a/spec/features/projects/blobs/blob_show_spec.rb b/spec/features/projects/blobs/blob_show_spec.rb index 71ffa352f80..3427f639930 100644 --- a/spec/features/projects/blobs/blob_show_spec.rb +++ b/spec/features/projects/blobs/blob_show_spec.rb @@ -4,7 +4,7 @@ feature 'File blob', :js, feature: true do let(:project) { create(:project, :public) } def visit_blob(path, anchor: nil, ref: 'master') - visit namespace_project_blob_path(project.namespace, project, File.join(ref, path), anchor: anchor) + visit project_blob_path(project, File.join(ref, path), anchor: anchor) wait_for_requests end diff --git a/spec/features/projects/blobs/edit_spec.rb b/spec/features/projects/blobs/edit_spec.rb index d0bc032ee93..c4e53293be0 100644 --- a/spec/features/projects/blobs/edit_spec.rb +++ b/spec/features/projects/blobs/edit_spec.rb @@ -26,7 +26,7 @@ feature 'Editing file blob', feature: true, js: true do context 'from MR diff' do before do - visit diffs_namespace_project_merge_request_path(project.namespace, project, merge_request) + visit diffs_project_merge_request_path(project, merge_request) edit_and_commit end @@ -37,7 +37,7 @@ feature 'Editing file blob', feature: true, js: true do context 'from blob file path' do before do - visit namespace_project_blob_path(project.namespace, project, tree_join(branch, file_path)) + visit project_blob_path(project, tree_join(branch, file_path)) edit_and_commit end @@ -55,7 +55,7 @@ feature 'Editing file blob', feature: true, js: true do before do project.team << [user, :developer] - visit namespace_project_edit_blob_path(project.namespace, project, tree_join(branch, file_path)) + visit project_edit_blob_path(project, tree_join(branch, file_path)) end it 'redirects to sign in and returns' do @@ -63,7 +63,7 @@ feature 'Editing file blob', feature: true, js: true do gitlab_sign_in(user) - expect(page).to have_current_path(namespace_project_edit_blob_path(project.namespace, project, tree_join(branch, file_path))) + expect(page).to have_current_path(project_edit_blob_path(project, tree_join(branch, file_path))) end end @@ -71,7 +71,7 @@ feature 'Editing file blob', feature: true, js: true do let(:user) { create(:user) } before do - visit namespace_project_edit_blob_path(project.namespace, project, tree_join(branch, file_path)) + visit project_edit_blob_path(project, tree_join(branch, file_path)) end it 'redirects to sign in and returns' do @@ -79,7 +79,7 @@ feature 'Editing file blob', feature: true, js: true do gitlab_sign_in(user) - expect(page).to have_current_path(namespace_project_blob_path(project.namespace, project, tree_join(branch, file_path))) + expect(page).to have_current_path(project_blob_path(project, tree_join(branch, file_path))) end end end @@ -97,18 +97,18 @@ feature 'Editing file blob', feature: true, js: true do context 'on some branch' do before do - visit namespace_project_edit_blob_path(project.namespace, project, tree_join(branch, file_path)) + visit project_edit_blob_path(project, tree_join(branch, file_path)) end it 'shows blob editor with same branch' do - expect(page).to have_current_path(namespace_project_edit_blob_path(project.namespace, project, tree_join(branch, file_path))) + expect(page).to have_current_path(project_edit_blob_path(project, tree_join(branch, file_path))) expect(find('.js-branch-name').value).to eq(branch) end end context 'with protected branch' do before do - visit namespace_project_edit_blob_path(project.namespace, project, tree_join(protected_branch, file_path)) + visit project_edit_blob_path(project, tree_join(protected_branch, file_path)) end it 'shows blob editor with patch branch' do @@ -123,11 +123,11 @@ feature 'Editing file blob', feature: true, js: true do before do project.team << [user, :master] gitlab_sign_in(user) - visit namespace_project_edit_blob_path(project.namespace, project, tree_join(branch, file_path)) + visit project_edit_blob_path(project, tree_join(branch, file_path)) end it 'shows blob editor with same branch' do - expect(page).to have_current_path(namespace_project_edit_blob_path(project.namespace, project, tree_join(branch, file_path))) + expect(page).to have_current_path(project_edit_blob_path(project, tree_join(branch, file_path))) expect(find('.js-branch-name').value).to eq(branch) end end diff --git a/spec/features/projects/blobs/shortcuts_blob_spec.rb b/spec/features/projects/blobs/shortcuts_blob_spec.rb index 30e2d587267..9cacda84378 100644 --- a/spec/features/projects/blobs/shortcuts_blob_spec.rb +++ b/spec/features/projects/blobs/shortcuts_blob_spec.rb @@ -12,7 +12,7 @@ feature 'Blob shortcuts', feature: true do end def visit_blob(fragment = nil) - visit namespace_project_blob_path(project.namespace, project, tree_join('master', path), anchor: fragment) + visit project_blob_path(project, tree_join('master', path), anchor: fragment) end describe 'pressing "y"' do @@ -21,7 +21,7 @@ feature 'Blob shortcuts', feature: true do find('body').native.send_key('y') - expect(page).to have_current_path(get_absolute_url(namespace_project_blob_path(project.namespace, project, tree_join(sha, path))), url: true) + expect(page).to have_current_path(get_absolute_url(project_blob_path(project, tree_join(sha, path))), url: true) end it 'maintains fragment hash when redirecting' do @@ -30,7 +30,7 @@ feature 'Blob shortcuts', feature: true do find('body').native.send_key('y') - expect(page).to have_current_path(get_absolute_url(namespace_project_blob_path(project.namespace, project, tree_join(sha, path), anchor: fragment)), url: true) + expect(page).to have_current_path(get_absolute_url(project_blob_path(project, tree_join(sha, path), anchor: fragment)), url: true) end end end diff --git a/spec/features/projects/branches/download_buttons_spec.rb b/spec/features/projects/branches/download_buttons_spec.rb index d8c4d475a2c..52323c21112 100644 --- a/spec/features/projects/branches/download_buttons_spec.rb +++ b/spec/features/projects/branches/download_buttons_spec.rb @@ -29,13 +29,11 @@ feature 'Download buttons in branches page', feature: true do describe 'when checking branches' do context 'with artifacts' do before do - visit namespace_project_branches_path(project.namespace, project) + visit project_branches_path(project) end scenario 'shows download artifacts button' do - href = latest_succeeded_namespace_project_artifacts_path( - project.namespace, project, 'binary-encoding/download', - job: 'build') + href = latest_succeeded_project_artifacts_path(project, 'binary-encoding/download', job: 'build') expect(page).to have_link "Download '#{build.name}'", href: href end diff --git a/spec/features/projects/branches/new_branch_ref_dropdown_spec.rb b/spec/features/projects/branches/new_branch_ref_dropdown_spec.rb index 406fa52e723..ab9af8fa603 100644 --- a/spec/features/projects/branches/new_branch_ref_dropdown_spec.rb +++ b/spec/features/projects/branches/new_branch_ref_dropdown_spec.rb @@ -9,7 +9,7 @@ describe 'New Branch Ref Dropdown', :js, :feature do project.add_master(user) gitlab_sign_in(user) - visit new_namespace_project_branch_path(project.namespace, project) + visit new_project_branch_path(project) end it 'filters a list of branches and tags' do diff --git a/spec/features/projects/branches_spec.rb b/spec/features/projects/branches_spec.rb index 0050864d305..4fae324d8d5 100644 --- a/spec/features/projects/branches_spec.rb +++ b/spec/features/projects/branches_spec.rb @@ -19,7 +19,7 @@ describe 'Branches', feature: true do describe 'Initial branches page' do it 'shows all the branches' do - visit namespace_project_branches_path(project.namespace, project) + visit project_branches_path(project) repository.branches_sorted_by(:name).first(20).each do |branch| expect(page).to have_content("#{branch.name}") @@ -28,7 +28,7 @@ describe 'Branches', feature: true do end it 'sorts the branches by name' do - visit namespace_project_branches_path(project.namespace, project) + visit project_branches_path(project) click_button "Name" # Open sorting dropdown click_link "Name" @@ -40,7 +40,7 @@ describe 'Branches', feature: true do end it 'sorts the branches by last updated' do - visit namespace_project_branches_path(project.namespace, project) + visit project_branches_path(project) click_button "Name" # Open sorting dropdown click_link "Last updated" @@ -52,7 +52,7 @@ describe 'Branches', feature: true do end it 'sorts the branches by oldest updated' do - visit namespace_project_branches_path(project.namespace, project) + visit project_branches_path(project) click_button "Name" # Open sorting dropdown click_link "Oldest updated" @@ -64,17 +64,17 @@ describe 'Branches', feature: true do end it 'avoids a N+1 query in branches index' do - control_count = ActiveRecord::QueryRecorder.new { visit namespace_project_branches_path(project.namespace, project) }.count + control_count = ActiveRecord::QueryRecorder.new { visit project_branches_path(project) }.count %w(one two three four five).each { |ref| repository.add_branch(user, ref, 'master') } - expect { visit namespace_project_branches_path(project.namespace, project) }.not_to exceed_query_limit(control_count) + expect { visit project_branches_path(project) }.not_to exceed_query_limit(control_count) end end describe 'Find branches' do it 'shows filtered branches', js: true do - visit namespace_project_branches_path(project.namespace, project) + visit project_branches_path(project) fill_in 'branch-search', with: 'fix' find('#branch-search').native.send_keys(:enter) @@ -86,7 +86,7 @@ describe 'Branches', feature: true do describe 'Delete unprotected branch' do it 'removes branch after confirmation', js: true do - visit namespace_project_branches_path(project.namespace, project) + visit project_branches_path(project) fill_in 'branch-search', with: 'fix' @@ -104,7 +104,7 @@ describe 'Branches', feature: true do describe 'Delete protected branch' do before do project.add_user(user, :master) - visit namespace_project_protected_branches_path(project.namespace, project) + visit project_protected_branches_path(project) set_protected_branch_name('fix') click_on "Protect" @@ -114,7 +114,7 @@ describe 'Branches', feature: true do end it 'does not allow devleoper to removes protected branch', js: true do - visit namespace_project_branches_path(project.namespace, project) + visit project_branches_path(project) fill_in 'branch-search', with: 'fix' find('#branch-search').native.send_keys(:enter) @@ -132,7 +132,7 @@ describe 'Branches', feature: true do describe 'Delete protected branch' do before do - visit namespace_project_protected_branches_path(project.namespace, project) + visit project_protected_branches_path(project) set_protected_branch_name('fix') click_on "Protect" @@ -141,7 +141,7 @@ describe 'Branches', feature: true do end it 'removes branch after modal confirmation', js: true do - visit namespace_project_branches_path(project.namespace, project) + visit project_branches_path(project) fill_in 'branch-search', with: 'fix' find('#branch-search').native.send_keys(:enter) @@ -164,7 +164,7 @@ describe 'Branches', feature: true do context 'logged out' do before do - visit namespace_project_branches_path(project.namespace, project) + visit project_branches_path(project) end it 'does not show merge request button' do diff --git a/spec/features/projects/commit/builds_spec.rb b/spec/features/projects/commit/builds_spec.rb index e5b1f95f2b9..69eeb8e285e 100644 --- a/spec/features/projects/commit/builds_spec.rb +++ b/spec/features/projects/commit/builds_spec.rb @@ -17,7 +17,7 @@ feature 'project commit pipelines', js: true do end scenario 'user views commit pipelines page' do - visit pipelines_namespace_project_commit_path(project.namespace, project, project.commit.sha) + visit pipelines_project_commit_path(project, project.commit.sha) page.within('.table-holder') do expect(page).to have_content project.pipelines[0].status # pipeline status diff --git a/spec/features/projects/commit/cherry_pick_spec.rb b/spec/features/projects/commit/cherry_pick_spec.rb index 0d3fa72fbf5..2d18add82b5 100644 --- a/spec/features/projects/commit/cherry_pick_spec.rb +++ b/spec/features/projects/commit/cherry_pick_spec.rb @@ -10,7 +10,7 @@ describe 'Cherry-pick Commits' do before do sign_in(user) project.team << [user, :master] - visit namespace_project_commit_path(project.namespace, project, master_pickable_commit.id) + visit project_commit_path(project, master_pickable_commit.id) end context "I cherry-pick a commit" do @@ -43,7 +43,7 @@ describe 'Cherry-pick Commits' do uncheck 'create_merge_request' click_button 'Cherry-pick' end - visit namespace_project_commit_path(project.namespace, project, master_pickable_commit.id) + visit project_commit_path(project, master_pickable_commit.id) find("a[href='#modal-cherry-pick-commit']").click page.within('#modal-cherry-pick-commit') do uncheck 'create_merge_request' diff --git a/spec/features/projects/commit/mini_pipeline_graph_spec.rb b/spec/features/projects/commit/mini_pipeline_graph_spec.rb index 570a7ae7b16..c8222326e91 100644 --- a/spec/features/projects/commit/mini_pipeline_graph_spec.rb +++ b/spec/features/projects/commit/mini_pipeline_graph_spec.rb @@ -22,7 +22,7 @@ feature 'Mini Pipeline Graph in Commit View', :js, :feature do before do build.run - visit namespace_project_commit_path(project.namespace, project, project.commit.id) + visit project_commit_path(project, project.commit.id) end it 'should display a mini pipeline graph' do @@ -43,7 +43,7 @@ feature 'Mini Pipeline Graph in Commit View', :js, :feature do context 'when commit does not have pipelines' do before do - visit namespace_project_commit_path(project.namespace, project, project.commit.id) + visit project_commit_path(project, project.commit.id) end it 'should not display a mini pipeline graph' do diff --git a/spec/features/projects/commit/rss_spec.rb b/spec/features/projects/commit/rss_spec.rb index f7548a56984..152c0d7c8de 100644 --- a/spec/features/projects/commit/rss_spec.rb +++ b/spec/features/projects/commit/rss_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' feature 'Project Commits RSS' do let(:project) { create(:project, :repository, visibility_level: Gitlab::VisibilityLevel::PUBLIC) } - let(:path) { namespace_project_commits_path(project.namespace, project, :master) } + let(:path) { project_commits_path(project, :master) } context 'when signed in' do before do diff --git a/spec/features/projects/compare_spec.rb b/spec/features/projects/compare_spec.rb index 4743d69fb75..c3adfa87c44 100644 --- a/spec/features/projects/compare_spec.rb +++ b/spec/features/projects/compare_spec.rb @@ -7,7 +7,7 @@ describe "Compare", js: true do before do project.team << [user, :master] gitlab_sign_in user - visit namespace_project_compare_index_path(project.namespace, project, from: "master", to: "master") + visit project_compare_index_path(project, from: "master", to: "master") end describe "branches" do diff --git a/spec/features/projects/deploy_keys_spec.rb b/spec/features/projects/deploy_keys_spec.rb index a31960639fe..a310d14be10 100644 --- a/spec/features/projects/deploy_keys_spec.rb +++ b/spec/features/projects/deploy_keys_spec.rb @@ -15,7 +15,7 @@ describe 'Project deploy keys', :js, :feature do end it 'removes association between project and deploy key' do - visit namespace_project_settings_repository_path(project.namespace, project) + visit project_settings_repository_path(project) page.within(find('.deploy-keys')) do expect(page).to have_selector('.deploy-keys li', count: 1) diff --git a/spec/features/projects/developer_views_empty_project_instructions_spec.rb b/spec/features/projects/developer_views_empty_project_instructions_spec.rb index a943f1e6a08..290dc1a2f79 100644 --- a/spec/features/projects/developer_views_empty_project_instructions_spec.rb +++ b/spec/features/projects/developer_views_empty_project_instructions_spec.rb @@ -47,7 +47,7 @@ feature 'Developer views empty project instructions', feature: true do end def visit_project - visit namespace_project_path(project.namespace, project) + visit project_path(project) end def select_protocol(protocol) diff --git a/spec/features/projects/diffs/diff_show_spec.rb b/spec/features/projects/diffs/diff_show_spec.rb index 48b7f1e0f34..b528b283495 100644 --- a/spec/features/projects/diffs/diff_show_spec.rb +++ b/spec/features/projects/diffs/diff_show_spec.rb @@ -4,7 +4,7 @@ feature 'Diff file viewer', :js, feature: true do let(:project) { create(:project, :public, :repository) } def visit_commit(sha, anchor: nil) - visit namespace_project_commit_path(project.namespace, project, sha, anchor: anchor) + visit project_commit_path(project, sha, anchor: anchor) wait_for_requests end diff --git a/spec/features/projects/edit_spec.rb b/spec/features/projects/edit_spec.rb index ca202b95a44..78c1a1f1d1a 100644 --- a/spec/features/projects/edit_spec.rb +++ b/spec/features/projects/edit_spec.rb @@ -8,7 +8,7 @@ feature 'Project edit', feature: true, js: true do project.team << [user, :master] gitlab_sign_in(user) - visit edit_namespace_project_path(project.namespace, project) + visit edit_project_path(project) end context 'feature visibility' do diff --git a/spec/features/projects/environments/environment_metrics_spec.rb b/spec/features/projects/environments/environment_metrics_spec.rb index a98a69a0fd6..841514ac707 100644 --- a/spec/features/projects/environments/environment_metrics_spec.rb +++ b/spec/features/projects/environments/environment_metrics_spec.rb @@ -32,8 +32,6 @@ feature 'Environment > Metrics', :feature do end def visit_environment(environment) - visit namespace_project_environment_path(environment.project.namespace, - environment.project, - environment) + visit project_environment_path(environment.project, environment) end end diff --git a/spec/features/projects/environments/environment_spec.rb b/spec/features/projects/environments/environment_spec.rb index 7d565555f1f..e3f40f8e661 100644 --- a/spec/features/projects/environments/environment_spec.rb +++ b/spec/features/projects/environments/environment_spec.rb @@ -114,7 +114,7 @@ feature 'Environment', :feature do before do # Stub #terminals as it causes js-enabled feature specs to render the page incorrectly allow_any_instance_of(Environment).to receive(:terminals) { nil } - visit terminal_namespace_project_environment_path(project.namespace, project, environment) + visit terminal_project_environment_path(project, environment) end it 'displays a web terminal' do @@ -194,9 +194,7 @@ feature 'Environment', :feature do name: 'staging-1.0/review', state: :available) - visit folder_namespace_project_environments_path(project.namespace, - project, - id: 'staging-1.0') + visit folder_project_environments_path(project, id: 'staging-1.0') end it 'renders a correct environment folder' do @@ -221,7 +219,7 @@ feature 'Environment', :feature do end scenario 'user deletes the branch with running environment' do - visit namespace_project_branches_path(project.namespace, project, search: 'feature') + visit project_branches_path(project, search: 'feature') remove_branch_with_hooks(project, user, 'feature') do page.within('.js-branch-feature') { find('a.btn-remove').click } @@ -249,12 +247,10 @@ feature 'Environment', :feature do end def visit_environment(environment) - visit namespace_project_environment_path(environment.project.namespace, - environment.project, - environment) + visit project_environment_path(environment.project, environment) end def have_terminal_button - have_link(nil, href: terminal_namespace_project_environment_path(project.namespace, project, environment)) + have_link(nil, href: terminal_project_environment_path(project, environment)) end end diff --git a/spec/features/projects/environments/environments_spec.rb b/spec/features/projects/environments/environments_spec.rb index cf4d996a32d..af3af3eb965 100644 --- a/spec/features/projects/environments/environments_spec.rb +++ b/spec/features/projects/environments/environments_spec.rb @@ -29,7 +29,7 @@ feature 'Environments page', :feature, :js do describe 'in available tab page' do it 'should show one environment' do - visit namespace_project_environments_path(project.namespace, project, scope: 'available') + visit project_environments_path(project, scope: 'available') expect(page).to have_css('.environments-container') expect(page.all('.environment-name').length).to eq(1) end @@ -37,7 +37,7 @@ feature 'Environments page', :feature, :js do describe 'in stopped tab page' do it 'should show no environments' do - visit namespace_project_environments_path(project.namespace, project, scope: 'stopped') + visit project_environments_path(project, scope: 'stopped') expect(page).to have_css('.environments-container') expect(page).to have_content('You don\'t have any environments right now') end @@ -49,7 +49,7 @@ feature 'Environments page', :feature, :js do describe 'in available tab page' do it 'should show no environments' do - visit namespace_project_environments_path(project.namespace, project, scope: 'available') + visit project_environments_path(project, scope: 'available') expect(page).to have_css('.environments-container') expect(page).to have_content('You don\'t have any environments right now') end @@ -57,7 +57,7 @@ feature 'Environments page', :feature, :js do describe 'in stopped tab page' do it 'should show one environment' do - visit namespace_project_environments_path(project.namespace, project, scope: 'stopped') + visit project_environments_path(project, scope: 'stopped') expect(page).to have_css('.environments-container') expect(page.all('.environment-name').length).to eq(1) end @@ -277,10 +277,10 @@ feature 'Environments page', :feature, :js do end def have_terminal_button - have_link(nil, href: terminal_namespace_project_environment_path(project.namespace, project, environment)) + have_link(nil, href: terminal_project_environment_path(project, environment)) end def visit_environments(project) - visit namespace_project_environments_path(project.namespace, project) + visit project_environments_path(project) end end diff --git a/spec/features/projects/features_visibility_spec.rb b/spec/features/projects/features_visibility_spec.rb index db2790a4bce..45b0c8d1a18 100644 --- a/spec/features/projects/features_visibility_spec.rb +++ b/spec/features/projects/features_visibility_spec.rb @@ -17,7 +17,7 @@ describe 'Edit Project Settings', feature: true do tools.each do |tool_name, shortcut_name| describe "feature #{tool_name}" do it 'toggles visibility' do - visit edit_namespace_project_path(project.namespace, project) + visit edit_project_path(project) select 'Disabled', from: "project_project_feature_attributes_#{tool_name}_access_level" click_button 'Save changes' @@ -44,7 +44,7 @@ describe 'Edit Project Settings', feature: true do project.project_feature.update(issues_access_level: ProjectFeature::DISABLED) allow_any_instance_of(Project).to receive(:external_issue_tracker).and_return(JiraService.new) - visit namespace_project_path(project.namespace, project) + visit project_path(project) expect(page).to have_selector(".shortcuts-issues") end @@ -52,7 +52,7 @@ describe 'Edit Project Settings', feature: true do context "pipelines subtabs" do it "shows builds when enabled" do - visit namespace_project_pipelines_path(project.namespace, project) + visit project_pipelines_path(project) expect(page).to have_selector(".shortcuts-builds") end @@ -60,7 +60,7 @@ describe 'Edit Project Settings', feature: true do it "hides builds when disabled" do allow(Ability).to receive(:allowed?).with(member, :read_builds, project).and_return(false) - visit namespace_project_pipelines_path(project.namespace, project) + visit project_pipelines_path(project) expect(page).not_to have_selector(".shortcuts-builds") end @@ -73,11 +73,11 @@ describe 'Edit Project Settings', feature: true do let(:tools) do { - builds: namespace_project_job_path(project.namespace, project, job), - issues: namespace_project_issues_path(project.namespace, project), - wiki: namespace_project_wiki_path(project.namespace, project, :home), - snippets: namespace_project_snippets_path(project.namespace, project), - merge_requests: namespace_project_merge_requests_path(project.namespace, project) + builds: project_job_path(project, job), + issues: project_issues_path(project), + wiki: project_wiki_path(project, :home), + snippets: project_snippets_path(project), + merge_requests: project_merge_requests_path(project) } end @@ -157,7 +157,7 @@ describe 'Edit Project Settings', feature: true do before do project.team << [member, :master] gitlab_sign_in(member) - visit edit_namespace_project_path(project.namespace, project) + visit edit_project_path(project) end it "disables repository related features" do @@ -174,7 +174,7 @@ describe 'Edit Project Settings', feature: true do click_button "Save changes" wait_for_requests - visit namespace_project_path(project.namespace, project) + visit project_path(project) expect(page).to have_content "Customize your workflow!" end @@ -187,7 +187,7 @@ describe 'Edit Project Settings', feature: true do click_button "Save changes" wait_for_requests - visit activity_namespace_project_path(project.namespace, project) + visit activity_project_path(project) page.within(".event-filter") do expect(page).to have_selector("a", count: 2) @@ -205,7 +205,7 @@ describe 'Edit Project Settings', feature: true do expect(page).to have_content("Comments") end - visit edit_namespace_project_path(project.namespace, project) + visit edit_project_path(project) select "Disabled", from: "project_project_feature_attributes_merge_requests_access_level" @@ -213,7 +213,7 @@ describe 'Edit Project Settings', feature: true do expect(page).to have_content("Comments") end - visit edit_namespace_project_path(project.namespace, project) + visit edit_project_path(project) select "Disabled", from: "project_project_feature_attributes_repository_access_level" @@ -221,14 +221,14 @@ describe 'Edit Project Settings', feature: true do expect(page).not_to have_content("Comments") end - visit edit_namespace_project_path(project.namespace, project) + visit edit_project_path(project) end def save_changes_and_check_activity_tab click_button "Save changes" wait_for_requests - visit activity_namespace_project_path(project.namespace, project) + visit activity_project_path(project) page.within(".event-filter") do yield @@ -243,7 +243,7 @@ describe 'Edit Project Settings', feature: true do before do project.team << [member, :guest] gitlab_sign_in(member) - visit namespace_project_path(project.namespace, project) + visit project_path(project) end it "does not show project statistic for guest" do diff --git a/spec/features/projects/files/browse_files_spec.rb b/spec/features/projects/files/browse_files_spec.rb index 34aef958ec6..ac2b926f4de 100644 --- a/spec/features/projects/files/browse_files_spec.rb +++ b/spec/features/projects/files/browse_files_spec.rb @@ -7,7 +7,7 @@ feature 'user browses project', feature: true, js: true do before do project.team << [user, :master] gitlab_sign_in(user) - visit namespace_project_tree_path(project.namespace, project, project.default_branch) + visit project_tree_path(project, project.default_branch) end scenario "can see blame of '.gitignore'" do diff --git a/spec/features/projects/files/creating_a_file_spec.rb b/spec/features/projects/files/creating_a_file_spec.rb index 2a1cc01fe68..1196994ac3a 100644 --- a/spec/features/projects/files/creating_a_file_spec.rb +++ b/spec/features/projects/files/creating_a_file_spec.rb @@ -7,7 +7,7 @@ feature 'User wants to create a file', feature: true do background do project.team << [user, :master] gitlab_sign_in user - visit namespace_project_new_blob_path(project.namespace, project, project.default_branch) + visit project_new_blob_path(project, project.default_branch) end def submit_new_file(options) @@ -30,11 +30,6 @@ feature 'User wants to create a file', feature: true do expect(page).to have_content 'The file has been successfully created' end - scenario 'file name contains invalid characters' do - submit_new_file(file_name: '\\') - expect(page).to have_content 'Path can contain only' - end - scenario 'file name contains directory traversal' do submit_new_file(file_name: '../README.md') expect(page).to have_content 'Path cannot include directory traversal' diff --git a/spec/features/projects/files/dockerfile_dropdown_spec.rb b/spec/features/projects/files/dockerfile_dropdown_spec.rb index 4f1b8588462..783d98dafa7 100644 --- a/spec/features/projects/files/dockerfile_dropdown_spec.rb +++ b/spec/features/projects/files/dockerfile_dropdown_spec.rb @@ -9,7 +9,7 @@ feature 'User wants to add a Dockerfile file', feature: true do gitlab_sign_in user - visit namespace_project_new_blob_path(project.namespace, project, 'master', file_name: 'Dockerfile') + visit project_new_blob_path(project, 'master', file_name: 'Dockerfile') end scenario 'user can see Dockerfile dropdown' do diff --git a/spec/features/projects/files/download_buttons_spec.rb b/spec/features/projects/files/download_buttons_spec.rb index 60182bfebe9..4f4fab8a6e5 100644 --- a/spec/features/projects/files/download_buttons_spec.rb +++ b/spec/features/projects/files/download_buttons_spec.rb @@ -29,14 +29,11 @@ feature 'Download buttons in files tree', feature: true do describe 'when files tree' do context 'with artifacts' do before do - visit namespace_project_tree_path( - project.namespace, project, project.default_branch) + visit project_tree_path(project, project.default_branch) end scenario 'shows download artifacts button' do - href = latest_succeeded_namespace_project_artifacts_path( - project.namespace, project, "#{project.default_branch}/download", - job: 'build') + href = latest_succeeded_project_artifacts_path(project, "#{project.default_branch}/download", job: 'build') expect(page).to have_link "Download '#{build.name}'", href: href end diff --git a/spec/features/projects/files/edit_file_soft_wrap_spec.rb b/spec/features/projects/files/edit_file_soft_wrap_spec.rb index 6e361ac4312..83aea070901 100644 --- a/spec/features/projects/files/edit_file_soft_wrap_spec.rb +++ b/spec/features/projects/files/edit_file_soft_wrap_spec.rb @@ -6,7 +6,7 @@ feature 'User uses soft wrap whilst editing file', feature: true, js: true do project = create(:project) project.team << [user, :master] gitlab_sign_in user - visit namespace_project_new_blob_path(project.namespace, project, 'master', file_name: 'test_file-name') + visit project_new_blob_path(project, 'master', file_name: 'test_file-name') editor = find('.file-editor.code') editor.click editor.send_keys 'Touch water with paw then recoil in horror chase dog then diff --git a/spec/features/projects/files/editing_a_file_spec.rb b/spec/features/projects/files/editing_a_file_spec.rb index e97ff5fded7..c9b0dbd0ffb 100644 --- a/spec/features/projects/files/editing_a_file_spec.rb +++ b/spec/features/projects/files/editing_a_file_spec.rb @@ -18,7 +18,7 @@ feature 'User wants to edit a file', feature: true do background do project.team << [user, :master] gitlab_sign_in user - visit namespace_project_edit_blob_path(project.namespace, project, + visit project_edit_blob_path(project, File.join(project.default_branch, '.gitignore')) end diff --git a/spec/features/projects/files/files_sort_submodules_with_folders_spec.rb b/spec/features/projects/files/files_sort_submodules_with_folders_spec.rb index 83a837fba44..07b4aa80f4b 100644 --- a/spec/features/projects/files/files_sort_submodules_with_folders_spec.rb +++ b/spec/features/projects/files/files_sort_submodules_with_folders_spec.rb @@ -7,7 +7,7 @@ feature 'User views files page', feature: true do before do project.team << [user, :master] gitlab_sign_in user - visit namespace_project_tree_path(project.namespace, project, project.repository.root_ref) + visit project_tree_path(project, project.repository.root_ref) end scenario 'user sees folders and submodules sorted together, followed by files' do diff --git a/spec/features/projects/files/find_file_keyboard_spec.rb b/spec/features/projects/files/find_file_keyboard_spec.rb index 6a914820ac9..087eef5d407 100644 --- a/spec/features/projects/files/find_file_keyboard_spec.rb +++ b/spec/features/projects/files/find_file_keyboard_spec.rb @@ -8,7 +8,7 @@ feature 'Find file keyboard shortcuts', feature: true, js: true do project.team << [user, :master] gitlab_sign_in user - visit namespace_project_find_file_path(project.namespace, project, project.repository.root_ref) + visit project_find_file_path(project, project.repository.root_ref) wait_for_requests end diff --git a/spec/features/projects/files/find_files_spec.rb b/spec/features/projects/files/find_files_spec.rb index 166ec5c921b..d2ccc9a0732 100644 --- a/spec/features/projects/files/find_files_spec.rb +++ b/spec/features/projects/files/find_files_spec.rb @@ -10,20 +10,13 @@ feature 'Find files button in the tree header', feature: true do end scenario 'project main screen' do - visit namespace_project_path( - project.namespace, - project - ) + visit project_path(project) expect(page).to have_selector('.tree-controls .shortcuts-find-file') end scenario 'project tree screen' do - visit namespace_project_tree_path( - project.namespace, - project, - project.default_branch - ) + visit project_tree_path(project, project.default_branch) expect(page).to have_selector('.tree-controls .shortcuts-find-file') end diff --git a/spec/features/projects/files/gitignore_dropdown_spec.rb b/spec/features/projects/files/gitignore_dropdown_spec.rb index 7f02ec6b73d..23c145d0a11 100644 --- a/spec/features/projects/files/gitignore_dropdown_spec.rb +++ b/spec/features/projects/files/gitignore_dropdown_spec.rb @@ -6,7 +6,7 @@ feature 'User wants to add a .gitignore file', feature: true do project = create(:project) project.team << [user, :master] gitlab_sign_in user - visit namespace_project_new_blob_path(project.namespace, project, 'master', file_name: '.gitignore') + visit project_new_blob_path(project, 'master', file_name: '.gitignore') end scenario 'user can see .gitignore dropdown' do diff --git a/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb b/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb index f4b17c2518c..0539b77e3dd 100644 --- a/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb +++ b/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb @@ -6,7 +6,7 @@ feature 'User wants to add a .gitlab-ci.yml file', feature: true do project = create(:project) project.team << [user, :master] gitlab_sign_in user - visit namespace_project_new_blob_path(project.namespace, project, 'master', file_name: '.gitlab-ci.yml') + visit project_new_blob_path(project, 'master', file_name: '.gitlab-ci.yml') end scenario 'user can see .gitlab-ci.yml dropdown' do diff --git a/spec/features/projects/files/project_owner_creates_license_file_spec.rb b/spec/features/projects/files/project_owner_creates_license_file_spec.rb index 7daf016dd22..3a4ed3d8cf0 100644 --- a/spec/features/projects/files/project_owner_creates_license_file_spec.rb +++ b/spec/features/projects/files/project_owner_creates_license_file_spec.rb @@ -8,11 +8,11 @@ feature 'project owner creates a license file', feature: true, js: true do message: 'Remove LICENSE', branch_name: 'master') project.team << [project_master, :master] gitlab_sign_in(project_master) - visit namespace_project_path(project.namespace, project) + visit project_path(project) end scenario 'project master creates a license file manually from a template' do - visit namespace_project_tree_path(project.namespace, project, project.repository.root_ref) + visit project_tree_path(project, project.repository.root_ref) find('.add-to-tree').click click_link 'New file' @@ -30,7 +30,7 @@ feature 'project owner creates a license file', feature: true, js: true do click_button 'Commit changes' expect(current_path).to eq( - namespace_project_blob_path(project.namespace, project, 'master/LICENSE')) + project_blob_path(project, 'master/LICENSE')) expect(page).to have_content('MIT License') expect(page).to have_content("Copyright (c) #{Time.now.year} #{project.namespace.human_name}") end @@ -40,7 +40,7 @@ feature 'project owner creates a license file', feature: true, js: true do expect(page).to have_content('New file') expect(current_path).to eq( - namespace_project_new_blob_path(project.namespace, project, 'master')) + project_new_blob_path(project, 'master')) expect(find('#file_name').value).to eq('LICENSE') expect(page).to have_selector('.license-selector') @@ -54,7 +54,7 @@ feature 'project owner creates a license file', feature: true, js: true do click_button 'Commit changes' expect(current_path).to eq( - namespace_project_blob_path(project.namespace, project, 'master/LICENSE')) + project_blob_path(project, 'master/LICENSE')) expect(page).to have_content('MIT License') expect(page).to have_content("Copyright (c) #{Time.now.year} #{project.namespace.human_name}") end diff --git a/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb b/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb index eab19d52030..77f97826427 100644 --- a/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb +++ b/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb @@ -9,13 +9,13 @@ feature 'project owner sees a link to create a license file in empty project', f end scenario 'project master creates a license file from a template' do - visit namespace_project_path(project.namespace, project) + visit project_path(project) click_link 'Create empty bare repository' click_on 'LICENSE' expect(page).to have_content('New file') expect(current_path).to eq( - namespace_project_new_blob_path(project.namespace, project, 'master')) + project_new_blob_path(project, 'master')) expect(find('#file_name').value).to eq('LICENSE') expect(page).to have_selector('.license-selector') @@ -31,7 +31,7 @@ feature 'project owner sees a link to create a license file in empty project', f click_button 'Commit changes' expect(current_path).to eq( - namespace_project_blob_path(project.namespace, project, 'master/LICENSE')) + project_blob_path(project, 'master/LICENSE')) expect(page).to have_content('MIT License') expect(page).to have_content("Copyright (c) #{Time.now.year} #{project.namespace.human_name}") end diff --git a/spec/features/projects/files/template_type_dropdown_spec.rb b/spec/features/projects/files/template_type_dropdown_spec.rb index 028a0919640..53b673538e5 100644 --- a/spec/features/projects/files/template_type_dropdown_spec.rb +++ b/spec/features/projects/files/template_type_dropdown_spec.rb @@ -31,7 +31,7 @@ feature 'Template type dropdown selector', js: true do context 'editing a matching file' do before do - visit namespace_project_edit_blob_path(project.namespace, project, File.join(project.default_branch, 'LICENSE')) + visit project_edit_blob_path(project, File.join(project.default_branch, 'LICENSE')) end scenario 'displayed' do @@ -61,7 +61,7 @@ feature 'Template type dropdown selector', js: true do context 'creating a matching file' do before do - visit namespace_project_new_blob_path(project.namespace, project, 'master', file_name: '.gitignore') + visit project_new_blob_path(project, 'master', file_name: '.gitignore') end scenario 'is displayed' do @@ -79,7 +79,7 @@ feature 'Template type dropdown selector', js: true do context 'creating a file' do before do - visit namespace_project_new_blob_path(project.namespace, project, project.default_branch) + visit project_new_blob_path(project, project.default_branch) end scenario 'type selector is shown' do @@ -129,7 +129,7 @@ def check_type_selector_toggle_text(template_type) end def create_and_edit_file(file_name) - visit namespace_project_new_blob_path(project.namespace, project, 'master', file_name: file_name) + visit project_new_blob_path(project, 'master', file_name: file_name) click_button "Commit changes" - visit namespace_project_edit_blob_path(project.namespace, project, File.join(project.default_branch, file_name)) + visit project_edit_blob_path(project, File.join(project.default_branch, file_name)) end diff --git a/spec/features/projects/files/undo_template_spec.rb b/spec/features/projects/files/undo_template_spec.rb index 4ccd123f46e..e18ff42942f 100644 --- a/spec/features/projects/files/undo_template_spec.rb +++ b/spec/features/projects/files/undo_template_spec.rb @@ -11,7 +11,7 @@ feature 'Template Undo Button', js: true do context 'editing a matching file and applying a template' do before do - visit namespace_project_edit_blob_path(project.namespace, project, File.join(project.default_branch, "LICENSE")) + visit project_edit_blob_path(project, File.join(project.default_branch, "LICENSE")) select_file_template('.js-license-selector', 'Apache License 2.0') end @@ -22,7 +22,7 @@ feature 'Template Undo Button', js: true do context 'creating a non-matching file' do before do - visit namespace_project_new_blob_path(project.namespace, project, 'master') + visit project_new_blob_path(project, 'master') select_file_template_type('LICENSE') select_file_template('.js-license-selector', 'Apache License 2.0') end diff --git a/spec/features/projects/gfm_autocomplete_load_spec.rb b/spec/features/projects/gfm_autocomplete_load_spec.rb index aa4ed217a34..a8661ad4d24 100644 --- a/spec/features/projects/gfm_autocomplete_load_spec.rb +++ b/spec/features/projects/gfm_autocomplete_load_spec.rb @@ -6,7 +6,7 @@ describe 'GFM autocomplete loading', feature: true, js: true do before do gitlab_sign_in :admin - visit namespace_project_path(project.namespace, project) + visit project_path(project) end it 'does not load on project#show' do @@ -14,7 +14,7 @@ describe 'GFM autocomplete loading', feature: true, js: true do end it 'loads on new issue page' do - visit new_namespace_project_issue_path(project.namespace, project) + visit new_project_issue_path(project) expect(evaluate_script('gl.GfmAutoComplete.dataSources')).not_to eq({}) end diff --git a/spec/features/projects/group_links_spec.rb b/spec/features/projects/group_links_spec.rb index 778f5d61ae3..64415ffe57f 100644 --- a/spec/features/projects/group_links_spec.rb +++ b/spec/features/projects/group_links_spec.rb @@ -14,7 +14,7 @@ feature 'Project group links', :feature, :js do context 'setting an expiration date for a group link' do before do - visit namespace_project_settings_members_path(project.namespace, project) + visit project_settings_members_path(project) click_on 'share-with-group-tab' @@ -43,7 +43,7 @@ feature 'Project group links', :feature, :js do end it 'does not show ancestors', :nested_groups do - visit namespace_project_settings_members_path(project.namespace, project) + visit project_settings_members_path(project) click_on 'share-with-group-tab' click_link 'Search for a group' @@ -61,7 +61,7 @@ feature 'Project group links', :feature, :js do group.add_owner(master) group_two.add_owner(master) - visit namespace_project_settings_members_path(project.namespace, project) + visit project_settings_members_path(project) execute_script 'GroupsSelect.PER_PAGE = 1;' open_select2 '#link_group_id' end diff --git a/spec/features/projects/guest_navigation_menu_spec.rb b/spec/features/projects/guest_navigation_menu_spec.rb index e1f7f06c113..f6e24a0aa31 100644 --- a/spec/features/projects/guest_navigation_menu_spec.rb +++ b/spec/features/projects/guest_navigation_menu_spec.rb @@ -11,7 +11,7 @@ describe 'Guest navigation menu' do end it 'shows allowed tabs only' do - visit namespace_project_path(project.namespace, project) + visit project_path(project) within('.layout-nav') do expect(page).to have_content 'Project' @@ -25,7 +25,7 @@ describe 'Guest navigation menu' do end it 'does not show fork button' do - visit namespace_project_path(project.namespace, project) + visit project_path(project) within('.count-buttons') do expect(page).not_to have_link 'Fork' @@ -33,7 +33,7 @@ describe 'Guest navigation menu' do end it 'does not show clone path' do - visit namespace_project_path(project.namespace, project) + visit project_path(project) within('.project-repo-buttons') do expect(page).not_to have_selector '.project-clone-holder' @@ -49,7 +49,7 @@ describe 'Guest navigation menu' do end it 'does not show the project file list landing page' do - visit namespace_project_path(project.namespace, project) + visit project_path(project) expect(page).not_to have_selector '.project-stats' expect(page).not_to have_selector '.project-last-commit' @@ -58,7 +58,7 @@ describe 'Guest navigation menu' do end it 'shows the customize workflow when issues and wiki are disabled' do - visit namespace_project_path(project.namespace, project) + visit project_path(project) expect(page).to have_selector '.project-show-customize_workflow' end @@ -66,7 +66,7 @@ describe 'Guest navigation menu' do it 'shows the wiki when enabled' do project.project_feature.update!(wiki_access_level: ProjectFeature::PRIVATE) - visit namespace_project_path(project.namespace, project) + visit project_path(project) expect(page).to have_selector '.project-show-wiki' end @@ -74,7 +74,7 @@ describe 'Guest navigation menu' do it 'shows the issues when enabled' do project.project_feature.update!(issues_access_level: ProjectFeature::PRIVATE) - visit namespace_project_path(project.namespace, project) + visit project_path(project) expect(page).to have_selector '.issues-list' end diff --git a/spec/features/projects/import_export/export_file_spec.rb b/spec/features/projects/import_export/export_file_spec.rb index b5c64777934..b7f0ad9197e 100644 --- a/spec/features/projects/import_export/export_file_spec.rb +++ b/spec/features/projects/import_export/export_file_spec.rb @@ -37,13 +37,13 @@ feature 'Import/Export - project export integration test', feature: true, js: tr end scenario 'exports a project successfully' do - visit edit_namespace_project_path(project.namespace, project) + visit edit_project_path(project) expect(page).to have_content('Export project') click_link 'Export project' - visit edit_namespace_project_path(project.namespace, project) + visit edit_project_path(project) expect(page).to have_content('Download export') diff --git a/spec/features/projects/import_export/namespace_export_file_spec.rb b/spec/features/projects/import_export/namespace_export_file_spec.rb index b0a68f0d61f..f12b28f05fc 100644 --- a/spec/features/projects/import_export/namespace_export_file_spec.rb +++ b/spec/features/projects/import_export/namespace_export_file_spec.rb @@ -48,13 +48,13 @@ feature 'Import/Export - Namespace export file cleanup', feature: true, js: true end def setup_export_project - visit edit_namespace_project_path(project.namespace, project) + visit edit_project_path(project) expect(page).to have_content('Export project') click_link 'Export project' - visit edit_namespace_project_path(project.namespace, project) + visit edit_project_path(project) expect(page).to have_content('Download export') end diff --git a/spec/features/projects/issuable_templates_spec.rb b/spec/features/projects/issuable_templates_spec.rb index 26a09985312..83d1dfd91a9 100644 --- a/spec/features/projects/issuable_templates_spec.rb +++ b/spec/features/projects/issuable_templates_spec.rb @@ -28,7 +28,7 @@ feature 'issuable templates', feature: true, js: true do longtemplate_content, message: 'added issue template', branch_name: 'master') - visit edit_namespace_project_issue_path project.namespace, project, issue + visit edit_project_issue_path project, issue fill_in :'issue[title]', with: 'test issue title' end @@ -81,7 +81,7 @@ feature 'issuable templates', feature: true, js: true do template_content, message: 'added issue template', branch_name: 'master') - visit edit_namespace_project_issue_path project.namespace, project, issue + visit edit_project_issue_path project, issue fill_in :'issue[title]', with: 'test issue title' fill_in :'issue[description]', with: prior_description end @@ -105,7 +105,7 @@ feature 'issuable templates', feature: true, js: true do template_content, message: 'added merge request template', branch_name: 'master') - visit edit_namespace_project_merge_request_path project.namespace, project, merge_request + visit edit_project_merge_request_path project, merge_request fill_in :'merge_request[title]', with: 'test merge request title' end @@ -135,7 +135,7 @@ feature 'issuable templates', feature: true, js: true do template_content, message: 'added merge request template', branch_name: 'master') - visit edit_namespace_project_merge_request_path project.namespace, project, merge_request + visit edit_project_merge_request_path project, merge_request fill_in :'merge_request[title]', with: 'test merge request title' end diff --git a/spec/features/projects/issues/list_spec.rb b/spec/features/projects/issues/list_spec.rb index b2db07a75ef..380ade24a32 100644 --- a/spec/features/projects/issues/list_spec.rb +++ b/spec/features/projects/issues/list_spec.rb @@ -13,7 +13,7 @@ feature 'Issues List' do scenario 'user does not see create new list button' do create(:issue, project: project) - visit namespace_project_issues_path(project.namespace, project) + visit project_issues_path(project) expect(page).not_to have_selector('.js-new-board-list') end diff --git a/spec/features/projects/issues/rss_spec.rb b/spec/features/projects/issues/rss_spec.rb index 38733d39932..d68606ab545 100644 --- a/spec/features/projects/issues/rss_spec.rb +++ b/spec/features/projects/issues/rss_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' feature 'Project Issues RSS' do let(:project) { create(:empty_project, visibility_level: Gitlab::VisibilityLevel::PUBLIC) } - let(:path) { namespace_project_issues_path(project.namespace, project) } + let(:path) { project_issues_path(project) } before do create(:issue, project: project) diff --git a/spec/features/projects/jobs_spec.rb b/spec/features/projects/jobs_spec.rb index 070cdbf1cef..e52151e9585 100644 --- a/spec/features/projects/jobs_spec.rb +++ b/spec/features/projects/jobs_spec.rb @@ -5,7 +5,6 @@ feature 'Jobs', :feature do let(:user) { create(:user) } let(:user_access_level) { :developer } let(:project) { create(:project) } - let(:namespace) { project.namespace } let(:pipeline) { create(:ci_pipeline, project: project) } let(:job) { create(:ci_build, :trace, pipeline: pipeline) } @@ -25,7 +24,7 @@ feature 'Jobs', :feature do context "Pending scope" do before do - visit namespace_project_jobs_path(project.namespace, project, scope: :pending) + visit project_jobs_path(project, scope: :pending) end it "shows Pending tab jobs" do @@ -40,7 +39,7 @@ feature 'Jobs', :feature do context "Running scope" do before do job.run! - visit namespace_project_jobs_path(project.namespace, project, scope: :running) + visit project_jobs_path(project, scope: :running) end it "shows Running tab jobs" do @@ -55,7 +54,7 @@ feature 'Jobs', :feature do context "Finished scope" do before do job.run! - visit namespace_project_jobs_path(project.namespace, project, scope: :finished) + visit project_jobs_path(project, scope: :finished) end it "shows Finished tab jobs" do @@ -68,7 +67,7 @@ feature 'Jobs', :feature do context "All jobs" do before do project.builds.running_or_pending.each(&:success) - visit namespace_project_jobs_path(project.namespace, project) + visit project_jobs_path(project) end it "shows All tab jobs" do @@ -82,7 +81,7 @@ feature 'Jobs', :feature do context "when visiting old URL" do let(:jobs_url) do - namespace_project_jobs_path(project.namespace, project) + project_jobs_path(project) end before do @@ -98,7 +97,7 @@ feature 'Jobs', :feature do describe "POST /:project/jobs/:id/cancel_all" do before do job.run! - visit namespace_project_jobs_path(project.namespace, project) + visit project_jobs_path(project) click_link "Cancel running" end @@ -117,7 +116,7 @@ feature 'Jobs', :feature do let(:job) { create(:ci_build, :success, pipeline: pipeline) } before do - visit namespace_project_job_path(project.namespace, project, job) + visit project_job_path(project, job) end it 'shows status name', :js do @@ -140,7 +139,7 @@ feature 'Jobs', :feature do let(:job) { create(:ci_build, :success, pipeline: pipeline) } before do - visit namespace_project_job_path(project.namespace, project, job) + visit project_job_path(project, job) end it 'shows retry button' do @@ -157,7 +156,7 @@ feature 'Jobs', :feature do let(:job) { create(:ci_build, :failed, pipeline: pipeline) } before do - visit namespace_project_job_path(namespace, project, job) + visit project_job_path(project, job) end it 'shows New issue button' do @@ -166,10 +165,10 @@ feature 'Jobs', :feature do it 'links to issues/new with the title and description filled in' do button_title = "Build Failed ##{job.id}" - job_path = namespace_project_job_path(namespace, project, job) + job_path = project_job_path(project, job) options = { issue: { title: button_title, description: job_path } } - href = new_namespace_project_issue_path(namespace, project, options) + href = new_project_issue_path(project, options) page.within('.header-action-buttons') do expect(find('.js-new-issue')['href']).to include(href) @@ -180,7 +179,7 @@ feature 'Jobs', :feature do context "Job from other project" do before do - visit namespace_project_job_path(project.namespace, project, job2) + visit project_job_path(project, job2) end it { expect(page.status_code).to eq(404) } @@ -189,7 +188,7 @@ feature 'Jobs', :feature do context "Download artifacts" do before do job.update_attributes(artifacts_file: artifacts_file) - visit namespace_project_job_path(project.namespace, project, job) + visit project_job_path(project, job) end it 'has button to download artifacts' do @@ -202,7 +201,7 @@ feature 'Jobs', :feature do job.update_attributes(artifacts_file: artifacts_file, artifacts_expire_at: expire_at) - visit namespace_project_job_path(project.namespace, project, job) + visit project_job_path(project, job) end context 'no expire date defined' do @@ -248,7 +247,7 @@ feature 'Jobs', :feature do context "when visiting old URL" do let(:job_url) do - namespace_project_job_path(project.namespace, project, job) + project_job_path(project, job) end before do @@ -264,7 +263,7 @@ feature 'Jobs', :feature do before do job.run! - visit namespace_project_job_path(project.namespace, project, job) + visit project_job_path(project, job) end it do @@ -276,7 +275,7 @@ feature 'Jobs', :feature do before do job.run! - visit namespace_project_job_path(project.namespace, project, job) + visit project_job_path(project, job) end context 'when job has an initial trace' do @@ -300,7 +299,7 @@ feature 'Jobs', :feature do end before do - visit namespace_project_job_path(project.namespace, project, job) + visit project_job_path(project, job) end it 'shows variable key and value after click', js: true do @@ -325,7 +324,7 @@ feature 'Jobs', :feature do let(:job) { create(:ci_build, :success, environment: environment.name, deployments: [deployment], pipeline: pipeline) } it 'shows a link for the job' do - visit namespace_project_job_path(project.namespace, project, job) + visit project_job_path(project, job) expect(page).to have_link environment.name end @@ -335,7 +334,7 @@ feature 'Jobs', :feature do let(:job) { create(:ci_build, :failed, environment: environment.name, pipeline: pipeline) } it 'shows a link for the job' do - visit namespace_project_job_path(project.namespace, project, job) + visit project_job_path(project, job) expect(page).to have_link environment.name end @@ -346,7 +345,7 @@ feature 'Jobs', :feature do let(:job) { create(:ci_build, :success, environment: environment.name, pipeline: pipeline) } it 'shows a link to latest deployment' do - visit namespace_project_job_path(project.namespace, project, job) + visit project_job_path(project, job) expect(page).to have_link('latest deployment') end @@ -358,7 +357,7 @@ feature 'Jobs', :feature do context "Job from project" do before do job.run! - visit namespace_project_job_path(project.namespace, project, job) + visit project_job_path(project, job) find('.js-cancel-job').click() end @@ -373,7 +372,7 @@ feature 'Jobs', :feature do context "Job from project", :js do before do job.run! - visit namespace_project_job_path(project.namespace, project, job) + visit project_job_path(project, job) find('.js-cancel-job').click() find('.js-retry-button').trigger('click') end @@ -394,7 +393,7 @@ feature 'Jobs', :feature do gitlab_sign_out_direct gitlab_sign_in(create(:user)) - visit namespace_project_job_path(project.namespace, project, job) + visit project_job_path(project, job) end it 'does not show the Retry button' do @@ -408,14 +407,14 @@ feature 'Jobs', :feature do describe "GET /:project/jobs/:id/download" do before do job.update_attributes(artifacts_file: artifacts_file) - visit namespace_project_job_path(project.namespace, project, job) + visit project_job_path(project, job) click_link 'Download' end context "Build from other project" do before do job2.update_attributes(artifacts_file: artifacts_file) - visit download_namespace_project_job_artifacts_path(project.namespace, project, job2) + visit download_project_job_artifacts_path(project, job2) end it { expect(page.status_code).to eq(404) } @@ -428,7 +427,7 @@ feature 'Jobs', :feature do before do Capybara.current_session.driver.headers = { 'X-Sendfile-Type' => 'X-Sendfile' } job.run! - visit namespace_project_job_path(project.namespace, project, job) + visit project_job_path(project, job) find('.js-raw-link-controller').click() end @@ -443,7 +442,7 @@ feature 'Jobs', :feature do before do Capybara.current_session.driver.headers = { 'X-Sendfile-Type' => 'X-Sendfile' } job2.run! - visit raw_namespace_project_job_path(project.namespace, project, job2) + visit raw_project_job_path(project, job2) end it 'sends the right headers' do @@ -467,7 +466,7 @@ feature 'Jobs', :feature do .to receive(:paths) .and_return([existing_file]) - visit namespace_project_job_path(namespace, project, job) + visit project_job_path(project, job) find('.js-raw-link-controller').click end @@ -485,7 +484,7 @@ feature 'Jobs', :feature do .to receive(:paths) .and_return([]) - visit namespace_project_job_path(namespace, project, job) + visit project_job_path(project, job) end it 'sends the right headers' do @@ -496,7 +495,7 @@ feature 'Jobs', :feature do context "when visiting old URL" do let(:raw_job_url) do - raw_namespace_project_job_path(project.namespace, project, job) + raw_project_job_path(project, job) end before do @@ -512,7 +511,7 @@ feature 'Jobs', :feature do describe "GET /:project/jobs/:id/trace.json" do context "Job from project" do before do - visit trace_namespace_project_job_path(project.namespace, project, job, format: :json) + visit trace_project_job_path(project, job, format: :json) end it { expect(page.status_code).to eq(200) } @@ -520,7 +519,7 @@ feature 'Jobs', :feature do context "Job from other project" do before do - visit trace_namespace_project_job_path(project.namespace, project, job2, format: :json) + visit trace_project_job_path(project, job2, format: :json) end it { expect(page.status_code).to eq(404) } @@ -530,7 +529,7 @@ feature 'Jobs', :feature do describe "GET /:project/jobs/:id/status" do context "Job from project" do before do - visit status_namespace_project_job_path(project.namespace, project, job) + visit status_project_job_path(project, job) end it { expect(page.status_code).to eq(200) } @@ -538,7 +537,7 @@ feature 'Jobs', :feature do context "Job from other project" do before do - visit status_namespace_project_job_path(project.namespace, project, job2) + visit status_project_job_path(project, job2) end it { expect(page.status_code).to eq(404) } diff --git a/spec/features/projects/labels/issues_sorted_by_priority_spec.rb b/spec/features/projects/labels/issues_sorted_by_priority_spec.rb index 2c47758f30e..89e31a72869 100644 --- a/spec/features/projects/labels/issues_sorted_by_priority_spec.rb +++ b/spec/features/projects/labels/issues_sorted_by_priority_spec.rb @@ -29,7 +29,7 @@ feature 'Issue prioritization', feature: true do issue_1.labels << label_5 gitlab_sign_in user - visit namespace_project_issues_path(project.namespace, project, sort: 'label_priority') + visit project_issues_path(project, sort: 'label_priority') # Ensure we are indicating that issues are sorted by priority expect(page).to have_selector('.dropdown-toggle', text: 'Label priority') @@ -68,7 +68,7 @@ feature 'Issue prioritization', feature: true do issue_6.labels << label_5 # 8 - No priority gitlab_sign_in user - visit namespace_project_issues_path(project.namespace, project, sort: 'label_priority') + visit project_issues_path(project, sort: 'label_priority') expect(page).to have_selector('.dropdown-toggle', text: 'Label priority') diff --git a/spec/features/projects/labels/subscription_spec.rb b/spec/features/projects/labels/subscription_spec.rb index 584dc294f05..04617bfe03e 100644 --- a/spec/features/projects/labels/subscription_spec.rb +++ b/spec/features/projects/labels/subscription_spec.rb @@ -14,7 +14,7 @@ feature 'Labels subscription', feature: true do end scenario 'users can subscribe/unsubscribe to labels', js: true do - visit namespace_project_labels_path(project.namespace, project) + visit project_labels_path(project) expect(page).to have_content('bug') expect(page).to have_content('feature') @@ -55,7 +55,7 @@ feature 'Labels subscription', feature: true do context 'when not signed in' do it 'users can not subscribe/unsubscribe to labels' do - visit namespace_project_labels_path(project.namespace, project) + visit project_labels_path(project) expect(page).to have_content 'bug' expect(page).to have_content 'feature' diff --git a/spec/features/projects/labels/update_prioritization_spec.rb b/spec/features/projects/labels/update_prioritization_spec.rb index 589bfb9fbc9..034613ea6be 100644 --- a/spec/features/projects/labels/update_prioritization_spec.rb +++ b/spec/features/projects/labels/update_prioritization_spec.rb @@ -18,7 +18,7 @@ feature 'Prioritize labels', feature: true do end scenario 'user can prioritize a group label', js: true do - visit namespace_project_labels_path(project.namespace, project) + visit project_labels_path(project) expect(page).to have_content('Star labels to start sorting by priority') @@ -37,7 +37,7 @@ feature 'Prioritize labels', feature: true do scenario 'user can unprioritize a group label', js: true do create(:label_priority, project: project, label: feature, priority: 1) - visit namespace_project_labels_path(project.namespace, project) + visit project_labels_path(project) page.within('.prioritized-labels') do expect(page).to have_content('feature') @@ -53,7 +53,7 @@ feature 'Prioritize labels', feature: true do end scenario 'user can prioritize a project label', js: true do - visit namespace_project_labels_path(project.namespace, project) + visit project_labels_path(project) expect(page).to have_content('Star labels to start sorting by priority') @@ -72,7 +72,7 @@ feature 'Prioritize labels', feature: true do scenario 'user can unprioritize a project label', js: true do create(:label_priority, project: project, label: bug, priority: 1) - visit namespace_project_labels_path(project.namespace, project) + visit project_labels_path(project) page.within('.prioritized-labels') do expect(page).to have_content('bug') @@ -92,7 +92,7 @@ feature 'Prioritize labels', feature: true do create(:label_priority, project: project, label: bug, priority: 1) create(:label_priority, project: project, label: feature, priority: 2) - visit namespace_project_labels_path(project.namespace, project) + visit project_labels_path(project) expect(page).to have_content 'bug' expect(page).to have_content 'feature' @@ -122,7 +122,7 @@ feature 'Prioritize labels', feature: true do gitlab_sign_in guest - visit namespace_project_labels_path(project.namespace, project) + visit project_labels_path(project) expect(page).to have_content 'bug' expect(page).to have_content 'wontfix' @@ -133,7 +133,7 @@ feature 'Prioritize labels', feature: true do context 'as a non signed in user' do it 'does not prioritize labels' do - visit namespace_project_labels_path(project.namespace, project) + visit project_labels_path(project) expect(page).to have_content 'bug' expect(page).to have_content 'wontfix' diff --git a/spec/features/projects/main/download_buttons_spec.rb b/spec/features/projects/main/download_buttons_spec.rb index 514453db472..b14e0f089f0 100644 --- a/spec/features/projects/main/download_buttons_spec.rb +++ b/spec/features/projects/main/download_buttons_spec.rb @@ -29,13 +29,11 @@ feature 'Download buttons in project main page', feature: true do describe 'when checking project main page' do context 'with artifacts' do before do - visit namespace_project_path(project.namespace, project) + visit project_path(project) end scenario 'shows download artifacts button' do - href = latest_succeeded_namespace_project_artifacts_path( - project.namespace, project, "#{project.default_branch}/download", - job: 'build') + href = latest_succeeded_project_artifacts_path(project, "#{project.default_branch}/download", job: 'build') expect(page).to have_link "Download '#{build.name}'", href: href end diff --git a/spec/features/projects/main/rss_spec.rb b/spec/features/projects/main/rss_spec.rb index fee8cfe2c33..5f48253dd06 100644 --- a/spec/features/projects/main/rss_spec.rb +++ b/spec/features/projects/main/rss_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' feature 'Project RSS' do let(:project) { create(:project, :repository, visibility_level: Gitlab::VisibilityLevel::PUBLIC) } - let(:path) { namespace_project_path(project.namespace, project) } + let(:path) { project_path(project) } context 'when signed in' do before do diff --git a/spec/features/projects/members/anonymous_user_sees_members_spec.rb b/spec/features/projects/members/anonymous_user_sees_members_spec.rb index d82cf53c690..4958d5594ac 100644 --- a/spec/features/projects/members/anonymous_user_sees_members_spec.rb +++ b/spec/features/projects/members/anonymous_user_sees_members_spec.rb @@ -11,10 +11,10 @@ feature 'Projects > Members > Anonymous user sees members', feature: true do end scenario "anonymous user visits the project's members page and sees the list of members" do - visit namespace_project_settings_members_path(project.namespace, project) + visit project_settings_members_path(project) expect(current_path).to eq( - namespace_project_settings_members_path(project.namespace, project)) + project_settings_members_path(project)) expect(page).to have_content(user.name) end end diff --git a/spec/features/projects/members/group_links_spec.rb b/spec/features/projects/members/group_links_spec.rb index 00d2a27597b..61cd7db15f5 100644 --- a/spec/features/projects/members/group_links_spec.rb +++ b/spec/features/projects/members/group_links_spec.rb @@ -10,7 +10,7 @@ feature 'Projects > Members > Anonymous user sees members', feature: true, js: t @group_link = create(:project_group_link, project: project, group: group) gitlab_sign_in(user) - visit namespace_project_settings_members_path(project.namespace, project) + visit project_settings_members_path(project) end it 'updates group access level' do @@ -22,7 +22,7 @@ feature 'Projects > Members > Anonymous user sees members', feature: true, js: t wait_for_requests - visit namespace_project_settings_members_path(project.namespace, project) + visit project_settings_members_path(project) expect(first('.group_member')).to have_content('Guest') end diff --git a/spec/features/projects/members/group_member_cannot_leave_group_project_spec.rb b/spec/features/projects/members/group_member_cannot_leave_group_project_spec.rb index 7e71dbc24c0..1c429202aba 100644 --- a/spec/features/projects/members/group_member_cannot_leave_group_project_spec.rb +++ b/spec/features/projects/members/group_member_cannot_leave_group_project_spec.rb @@ -8,7 +8,7 @@ feature 'Projects > Members > Group member cannot leave group project', feature: background do group.add_developer(user) gitlab_sign_in(user) - visit namespace_project_path(project.namespace, project) + visit project_path(project) end scenario 'user does not see a "Leave project" link' do diff --git a/spec/features/projects/members/group_member_cannot_request_access_to_his_group_project_spec.rb b/spec/features/projects/members/group_member_cannot_request_access_to_his_group_project_spec.rb index 60a5cd9ec63..7250a0d26fc 100644 --- a/spec/features/projects/members/group_member_cannot_request_access_to_his_group_project_spec.rb +++ b/spec/features/projects/members/group_member_cannot_request_access_to_his_group_project_spec.rb @@ -42,6 +42,6 @@ feature 'Projects > Members > Group member cannot request access to his group pr def login_and_visit_project_page(user) gitlab_sign_in(user) - visit namespace_project_path(project.namespace, project) + visit project_path(project) end end diff --git a/spec/features/projects/members/group_members_spec.rb b/spec/features/projects/members/group_members_spec.rb index 76fe6a00dab..0acf5134cce 100644 --- a/spec/features/projects/members/group_members_spec.rb +++ b/spec/features/projects/members/group_members_spec.rb @@ -19,7 +19,7 @@ feature 'Projects members', feature: true do context 'with a group invitee' do before do group_invitee - visit namespace_project_settings_members_path(project.namespace, project) + visit project_settings_members_path(project) end scenario 'does not appear in the project members page' do @@ -33,7 +33,7 @@ feature 'Projects members', feature: true do before do group_invitee project_invitee - visit namespace_project_settings_members_path(project.namespace, project) + visit project_settings_members_path(project) end scenario 'shows the project invitee, the project developer, and the group owner' do @@ -54,7 +54,7 @@ feature 'Projects members', feature: true do context 'with a group requester' do before do group.request_access(group_requester) - visit namespace_project_settings_members_path(project.namespace, project) + visit project_settings_members_path(project) end scenario 'does not appear in the project members page' do @@ -68,7 +68,7 @@ feature 'Projects members', feature: true do before do group.request_access(group_requester) project.request_access(project_requester) - visit namespace_project_settings_members_path(project.namespace, project) + visit project_settings_members_path(project) end scenario 'shows the project requester, the project developer, and the group owner' do diff --git a/spec/features/projects/members/group_requester_cannot_request_access_to_project_spec.rb b/spec/features/projects/members/group_requester_cannot_request_access_to_project_spec.rb index 66da28b07fe..5a28a7538f8 100644 --- a/spec/features/projects/members/group_requester_cannot_request_access_to_project_spec.rb +++ b/spec/features/projects/members/group_requester_cannot_request_access_to_project_spec.rb @@ -11,7 +11,7 @@ feature 'Projects > Members > Group requester cannot request access to project', gitlab_sign_in(user) visit group_path(group) perform_enqueued_jobs { click_link 'Request Access' } - visit namespace_project_path(project.namespace, project) + visit project_path(project) end scenario 'group requester does not see the request access / withdraw access request button' do diff --git a/spec/features/projects/members/list_spec.rb b/spec/features/projects/members/list_spec.rb index 9fdd7df0ee5..b62bf2f6293 100644 --- a/spec/features/projects/members/list_spec.rb +++ b/spec/features/projects/members/list_spec.rb @@ -85,6 +85,6 @@ feature 'Project members list', feature: true do end def visit_members_page - visit namespace_project_settings_members_path(project.namespace, project) + visit project_settings_members_path(project) end end diff --git a/spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb b/spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb index 21b48b7fdd1..ca2172bb905 100644 --- a/spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb +++ b/spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb @@ -16,7 +16,7 @@ feature 'Projects > Members > Master adds member with expiration date', feature: scenario 'expiration date is displayed in the members list' do travel_to Time.zone.parse('2016-08-06 08:00') do date = 4.days.from_now - visit namespace_project_project_members_path(project.namespace, project) + visit project_project_members_path(project) page.within '.users-project-form' do select2(new_member.id, from: '#user_ids', multiple: true) @@ -34,7 +34,7 @@ feature 'Projects > Members > Master adds member with expiration date', feature: travel_to Time.zone.parse('2016-08-06 08:00') do date = 3.days.from_now project.team.add_users([new_member.id], :developer, expires_at: Date.today.to_s(:medium)) - visit namespace_project_project_members_path(project.namespace, project) + visit project_project_members_path(project) page.within "#project_member_#{new_member.project_members.first.id}" do find('.js-access-expiration-date').set date.to_s(:medium) diff --git a/spec/features/projects/members/master_manages_access_requests_spec.rb b/spec/features/projects/members/master_manages_access_requests_spec.rb index bd445e27243..69c5927428c 100644 --- a/spec/features/projects/members/master_manages_access_requests_spec.rb +++ b/spec/features/projects/members/master_manages_access_requests_spec.rb @@ -12,13 +12,13 @@ feature 'Projects > Members > Master manages access requests', feature: true do end scenario 'master can see access requests' do - visit namespace_project_project_members_path(project.namespace, project) + visit project_project_members_path(project) expect_visible_access_request(project, user) end scenario 'master can grant access' do - visit namespace_project_project_members_path(project.namespace, project) + visit project_project_members_path(project) expect_visible_access_request(project, user) @@ -29,7 +29,7 @@ feature 'Projects > Members > Master manages access requests', feature: true do end scenario 'master can deny access' do - visit namespace_project_project_members_path(project.namespace, project) + visit project_project_members_path(project) expect_visible_access_request(project, user) diff --git a/spec/features/projects/members/member_cannot_request_access_to_his_project_spec.rb b/spec/features/projects/members/member_cannot_request_access_to_his_project_spec.rb index 703f5dff6b5..f0da201da85 100644 --- a/spec/features/projects/members/member_cannot_request_access_to_his_project_spec.rb +++ b/spec/features/projects/members/member_cannot_request_access_to_his_project_spec.rb @@ -7,7 +7,7 @@ feature 'Projects > Members > Member cannot request access to his project', feat background do project.team << [member, :developer] gitlab_sign_in(member) - visit namespace_project_path(project.namespace, project) + visit project_path(project) end scenario 'member does not see the request access button' do diff --git a/spec/features/projects/members/member_leaves_project_spec.rb b/spec/features/projects/members/member_leaves_project_spec.rb index 8e1788f7f2a..31d8bbdc0b6 100644 --- a/spec/features/projects/members/member_leaves_project_spec.rb +++ b/spec/features/projects/members/member_leaves_project_spec.rb @@ -7,7 +7,7 @@ feature 'Projects > Members > Member leaves project', feature: true do background do project.team << [user, :developer] gitlab_sign_in(user) - visit namespace_project_path(project.namespace, project) + visit project_path(project) end scenario 'user leaves project' do diff --git a/spec/features/projects/members/owner_cannot_leave_project_spec.rb b/spec/features/projects/members/owner_cannot_leave_project_spec.rb index 70e4bb19c0f..a1ccc6ddf65 100644 --- a/spec/features/projects/members/owner_cannot_leave_project_spec.rb +++ b/spec/features/projects/members/owner_cannot_leave_project_spec.rb @@ -5,7 +5,7 @@ feature 'Projects > Members > Owner cannot leave project', feature: true do background do gitlab_sign_in(project.owner) - visit namespace_project_path(project.namespace, project) + visit project_path(project) end scenario 'user does not see a "Leave project" link' do diff --git a/spec/features/projects/members/owner_cannot_request_access_to_his_project_spec.rb b/spec/features/projects/members/owner_cannot_request_access_to_his_project_spec.rb index 0cd7e3afeda..54f5d0d165b 100644 --- a/spec/features/projects/members/owner_cannot_request_access_to_his_project_spec.rb +++ b/spec/features/projects/members/owner_cannot_request_access_to_his_project_spec.rb @@ -5,7 +5,7 @@ feature 'Projects > Members > Owner cannot request access to his project', featu background do gitlab_sign_in(project.owner) - visit namespace_project_path(project.namespace, project) + visit project_path(project) end scenario 'owner does not see the request access button' do diff --git a/spec/features/projects/members/sorting_spec.rb b/spec/features/projects/members/sorting_spec.rb index 66d98ef8b90..7c02b49a0ab 100644 --- a/spec/features/projects/members/sorting_spec.rb +++ b/spec/features/projects/members/sorting_spec.rb @@ -84,7 +84,7 @@ feature 'Projects > Members > Sorting', feature: true do end def visit_members_list(sort:) - visit namespace_project_project_members_path(project.namespace.to_param, project, sort: sort) + visit project_project_members_path(project, sort: sort) end def first_member diff --git a/spec/features/projects/members/user_requests_access_spec.rb b/spec/features/projects/members/user_requests_access_spec.rb index 081009f2325..247cc0e6f2c 100644 --- a/spec/features/projects/members/user_requests_access_spec.rb +++ b/spec/features/projects/members/user_requests_access_spec.rb @@ -7,12 +7,12 @@ feature 'Projects > Members > User requests access', feature: true do background do gitlab_sign_in(user) - visit namespace_project_path(project.namespace, project) + visit project_path(project) end scenario 'request access feature is disabled' do project.update_attributes(request_access_enabled: false) - visit namespace_project_path(project.namespace, project) + visit project_path(project) expect(page).not_to have_content 'Request Access' end @@ -35,7 +35,7 @@ feature 'Projects > Members > User requests access', feature: true do project.project_feature.update!(repository_access_level: ProjectFeature::PRIVATE, builds_access_level: ProjectFeature::PRIVATE, merge_requests_access_level: ProjectFeature::PRIVATE) - visit namespace_project_path(project.namespace, project) + visit project_path(project) expect(page).to have_content 'Request Access' end @@ -49,7 +49,7 @@ feature 'Projects > Members > User requests access', feature: true do open_project_settings_menu click_link 'Members' - visit namespace_project_settings_members_path(project.namespace, project) + visit project_settings_members_path(project) page.within('.content') do expect(page).not_to have_content(user.name) end diff --git a/spec/features/projects/merge_request_button_spec.rb b/spec/features/projects/merge_request_button_spec.rb index 58054bbbbed..771dd7d3208 100644 --- a/spec/features/projects/merge_request_button_spec.rb +++ b/spec/features/projects/merge_request_button_spec.rb @@ -23,10 +23,9 @@ feature 'Merge Request button', feature: true do end it 'shows Create merge request button' do - href = namespace_project_new_merge_request_path(project.namespace, - project, - merge_request: { source_branch: 'feature', - target_branch: 'master' }) + href = project_new_merge_request_path(project, + merge_request: { source_branch: 'feature', + target_branch: 'master' }) visit url @@ -67,10 +66,9 @@ feature 'Merge Request button', feature: true do let(:user) { forked_project.owner } it 'shows Create merge request button' do - href = namespace_project_new_merge_request_path(forked_project.namespace, - forked_project, - merge_request: { source_branch: 'feature', - target_branch: 'master' }) + href = project_new_merge_request_path(forked_project, + merge_request: { source_branch: 'feature', + target_branch: 'master' }) visit fork_url @@ -85,24 +83,24 @@ feature 'Merge Request button', feature: true do context 'on branches page' do it_behaves_like 'Merge request button only shown when allowed' do let(:label) { 'Merge request' } - let(:url) { namespace_project_branches_path(project.namespace, project, search: 'feature') } - let(:fork_url) { namespace_project_branches_path(forked_project.namespace, forked_project, search: 'feature') } + let(:url) { project_branches_path(project, search: 'feature') } + let(:fork_url) { project_branches_path(forked_project, search: 'feature') } end end context 'on compare page' do it_behaves_like 'Merge request button only shown when allowed' do let(:label) { 'Create merge request' } - let(:url) { namespace_project_compare_path(project.namespace, project, from: 'master', to: 'feature') } - let(:fork_url) { namespace_project_compare_path(forked_project.namespace, forked_project, from: 'master', to: 'feature') } + let(:url) { project_compare_path(project, from: 'master', to: 'feature') } + let(:fork_url) { project_compare_path(forked_project, from: 'master', to: 'feature') } end end context 'on commits page' do it_behaves_like 'Merge request button only shown when allowed' do let(:label) { 'Create merge request' } - let(:url) { namespace_project_commits_path(project.namespace, project, 'feature') } - let(:fork_url) { namespace_project_commits_path(forked_project.namespace, forked_project, 'feature') } + let(:url) { project_commits_path(project, 'feature') } + let(:fork_url) { project_commits_path(forked_project, 'feature') } end end end diff --git a/spec/features/projects/merge_requests/list_spec.rb b/spec/features/projects/merge_requests/list_spec.rb index 7ce3156215a..ff4d22b3881 100644 --- a/spec/features/projects/merge_requests/list_spec.rb +++ b/spec/features/projects/merge_requests/list_spec.rb @@ -13,28 +13,28 @@ feature 'Merge Requests List' do scenario 'user does not see create new list button' do create(:merge_request, source_project: project) - visit namespace_project_merge_requests_path(project.namespace, project) + visit project_merge_requests_path(project) expect(page).not_to have_selector('.js-new-board-list') end it 'should show an empty state' do - visit namespace_project_merge_requests_path(project.namespace, project) + visit project_merge_requests_path(project) expect(page).to have_selector('.empty-state') end it 'empty state should have a create merge request button' do - visit namespace_project_merge_requests_path(project.namespace, project) + visit project_merge_requests_path(project) - expect(page).to have_link 'New merge request', href: namespace_project_new_merge_request_path(project.namespace, project) + expect(page).to have_link 'New merge request', href: project_new_merge_request_path(project) end context 'if there are merge requests' do before do create(:merge_request, assignee: user, source_project: project) - visit namespace_project_merge_requests_path(project.namespace, project) + visit project_merge_requests_path(project) end it 'should not show an empty state' do diff --git a/spec/features/projects/milestones/milestone_spec.rb b/spec/features/projects/milestones/milestone_spec.rb index a02e4118784..1913ef728d3 100644 --- a/spec/features/projects/milestones/milestone_spec.rb +++ b/spec/features/projects/milestones/milestone_spec.rb @@ -11,7 +11,7 @@ feature 'Project milestone', :feature do context 'when project has enabled issues' do before do - visit namespace_project_milestone_path(project.namespace, project, milestone) + visit project_milestone_path(project, milestone) end it 'shows issues tab' do @@ -38,7 +38,7 @@ feature 'Project milestone', :feature do context 'when project has disabled issues' do before do project.project_feature.update_attribute(:issues_access_level, ProjectFeature::DISABLED) - visit namespace_project_milestone_path(project.namespace, project, milestone) + visit project_milestone_path(project, milestone) end it 'hides issues tab' do @@ -68,7 +68,7 @@ feature 'Project milestone', :feature do before do create(:issue, project: project, milestone: milestone) - visit namespace_project_milestone_path(project.namespace, project, milestone) + visit project_milestone_path(project, milestone) end describe 'the collapsed sidebar' do diff --git a/spec/features/projects/milestones/milestones_sorting_spec.rb b/spec/features/projects/milestones/milestones_sorting_spec.rb index 2350089255d..1b74758445b 100644 --- a/spec/features/projects/milestones/milestones_sorting_spec.rb +++ b/spec/features/projects/milestones/milestones_sorting_spec.rb @@ -19,7 +19,7 @@ feature 'Milestones sorting', :feature, :js do end scenario 'visit project milestones and sort by due_date_asc' do - visit namespace_project_milestones_path(project.namespace, project) + visit project_milestones_path(project) expect(page).to have_button('Due soon') diff --git a/spec/features/projects/milestones/new_spec.rb b/spec/features/projects/milestones/new_spec.rb index 7403822c7fb..3c81db502bc 100644 --- a/spec/features/projects/milestones/new_spec.rb +++ b/spec/features/projects/milestones/new_spec.rb @@ -6,7 +6,7 @@ feature 'Creating a new project milestone', :feature, :js do before do login_as(user) - visit new_namespace_project_milestone_path(project.namespace, project) + visit new_project_milestone_path(project) end it 'description has autocomplete' do diff --git a/spec/features/projects/new_project_spec.rb b/spec/features/projects/new_project_spec.rb index 37d9a97033b..22fb1223739 100644 --- a/spec/features/projects/new_project_spec.rb +++ b/spec/features/projects/new_project_spec.rb @@ -1,13 +1,27 @@ -require "spec_helper" +require 'spec_helper' -feature "New project", feature: true do +feature 'New project' do let(:user) { create(:admin) } before do - gitlab_sign_in(user) + sign_in(user) end - context "Visibility level selector" do + it 'shows "New project" page' do + visit new_project_path + + expect(page).to have_content('Project path') + expect(page).to have_content('Project name') + + expect(page).to have_link('GitHub') + expect(page).to have_link('Bitbucket') + expect(page).to have_link('GitLab.com') + expect(page).to have_link('Google Code') + expect(page).to have_button('Repo by URL') + expect(page).to have_link('GitLab export') + end + + context 'Visibility level selector' do Gitlab::VisibilityLevel.options.each do |key, level| it "sets selector to #{key}" do stub_application_setting(default_project_visibility: level) @@ -28,20 +42,20 @@ feature "New project", feature: true do end end - context "Namespace selector" do - context "with user namespace" do + context 'Namespace selector' do + context 'with user namespace' do before do visit new_project_path end - it "selects the user namespace" do - namespace = find("#project_namespace_id") + it 'selects the user namespace' do + namespace = find('#project_namespace_id') expect(namespace.text).to eq user.username end end - context "with group namespace" do + context 'with group namespace' do let(:group) { create(:group, :private, owner: user) } before do @@ -49,13 +63,13 @@ feature "New project", feature: true do visit new_project_path(namespace_id: group.id) end - it "selects the group namespace" do - namespace = find("#project_namespace_id option[selected]") + it 'selects the group namespace' do + namespace = find('#project_namespace_id option[selected]') expect(namespace.text).to eq group.name end - context "on validation error" do + context 'on validation error' do before do fill_in('project_path', with: 'private-group-project') choose('Internal') @@ -64,15 +78,15 @@ feature "New project", feature: true do expect(page).to have_css '.project-edit-errors .alert.alert-danger' end - it "selects the group namespace" do - namespace = find("#project_namespace_id option[selected]") + it 'selects the group namespace' do + namespace = find('#project_namespace_id option[selected]') expect(namespace.text).to eq group.name end end end - context "with subgroup namespace" do + context 'with subgroup namespace' do let(:group) { create(:group, :private, owner: user) } let(:subgroup) { create(:group, parent: group) } @@ -81,8 +95,8 @@ feature "New project", feature: true do visit new_project_path(namespace_id: subgroup.id) end - it "selects the group namespace" do - namespace = find("#project_namespace_id option[selected]") + it 'selects the group namespace' do + namespace = find('#project_namespace_id option[selected]') expect(namespace.text).to eq subgroup.full_path end @@ -94,10 +108,45 @@ feature "New project", feature: true do visit new_project_path end - it 'does not autocomplete sensitive git repo URL' do - autocomplete = find('#project_import_url')['autocomplete'] + context 'from git repository url' do + before do + first('.import_git').click + end + + it 'does not autocomplete sensitive git repo URL' do + autocomplete = find('#project_import_url')['autocomplete'] + + expect(autocomplete).to eq('off') + end + + it 'shows import instructions' do + git_import_instructions = first('.js-toggle-content') - expect(autocomplete).to eq('off') + expect(git_import_instructions).to be_visible + expect(git_import_instructions).to have_content 'Git repository URL' + end + end + + context 'from GitHub' do + before do + first('.import_github').click + end + + it 'shows import instructions' do + expect(page).to have_content('Import Projects from GitHub') + expect(current_path).to eq new_import_github_path + end + end + + context 'from Google Code' do + before do + first('.import_google_code').click + end + + it 'shows import instructions' do + expect(page).to have_content('Import projects from Google Code') + expect(current_path).to eq new_import_google_code_path + end end end end diff --git a/spec/features/projects/no_password_spec.rb b/spec/features/projects/no_password_spec.rb index 30a16e38e3c..53ac18fa7cc 100644 --- a/spec/features/projects/no_password_spec.rb +++ b/spec/features/projects/no_password_spec.rb @@ -6,7 +6,7 @@ feature 'No Password Alert' do context 'with internal auth enabled' do before do sign_in(user) - visit namespace_project_path(project.namespace, project) + visit project_path(project) end context 'when user has a password' do @@ -37,7 +37,7 @@ feature 'No Password Alert' do context 'when user has no personal access tokens' do it 'has a personal access token alert' do gitlab_sign_in_via('saml', user, 'my-uid') - visit namespace_project_path(project.namespace, project) + visit project_path(project) expect(page).to have_content "You won't be able to pull or push project code via HTTP until you create a personal access token on your account" end @@ -47,7 +47,7 @@ feature 'No Password Alert' do it 'shows no alert' do create(:personal_access_token, user: user) gitlab_sign_in_via('saml', user, 'my-uid') - visit namespace_project_path(project.namespace, project) + visit project_path(project) expect(page).not_to have_content "You won't be able to pull or push project code via HTTP until you create a personal access token on your account" end @@ -59,7 +59,7 @@ feature 'No Password Alert' do before do sign_in(user) - visit namespace_project_path(project.namespace, project) + visit project_path(project) end it 'shows no alert' do diff --git a/spec/features/projects/pages_spec.rb b/spec/features/projects/pages_spec.rb index e9a3cfb7f60..e2cc38e276f 100644 --- a/spec/features/projects/pages_spec.rb +++ b/spec/features/projects/pages_spec.rb @@ -15,7 +15,7 @@ feature 'Pages', feature: true do shared_examples 'no pages deployed' do scenario 'does not see anything to destroy' do - visit namespace_project_pages_path(project.namespace, project) + visit project_pages_path(project) expect(page).not_to have_link('Remove pages') expect(page).not_to have_text('Only the project owner can remove pages') @@ -33,7 +33,7 @@ feature 'Pages', feature: true do end scenario 'sees "Remove pages" link' do - visit namespace_project_pages_path(project.namespace, project) + visit project_pages_path(project) expect(page).to have_link('Remove pages') end @@ -49,7 +49,7 @@ feature 'Pages', feature: true do end scenario 'sees "Only the project owner can remove pages" text' do - visit namespace_project_pages_path(project.namespace, project) + visit project_pages_path(project) expect(page).to have_text('Only the project owner can remove pages') end diff --git a/spec/features/projects/pipeline_schedules_spec.rb b/spec/features/projects/pipeline_schedules_spec.rb index dfb973c37e5..d8bb7ca9a83 100644 --- a/spec/features/projects/pipeline_schedules_spec.rb +++ b/spec/features/projects/pipeline_schedules_spec.rb @@ -135,15 +135,15 @@ feature 'Pipeline Schedules', :feature do end def visit_new_pipeline_schedule - visit new_namespace_project_pipeline_schedule_path(project.namespace, project, pipeline_schedule) + visit new_project_pipeline_schedule_path(project, pipeline_schedule) end def edit_pipeline_schedule - visit edit_namespace_project_pipeline_schedule_path(project.namespace, project, pipeline_schedule) + visit edit_project_pipeline_schedule_path(project, pipeline_schedule) end def visit_pipelines_schedules - visit namespace_project_pipeline_schedules_path(project.namespace, project, scope: scope) + visit project_pipeline_schedules_path(project, scope: scope) end def select_timezone diff --git a/spec/features/projects/pipelines/pipeline_spec.rb b/spec/features/projects/pipelines/pipeline_spec.rb index e182995922d..bd6750d2208 100644 --- a/spec/features/projects/pipelines/pipeline_spec.rb +++ b/spec/features/projects/pipelines/pipeline_spec.rb @@ -1,8 +1,6 @@ require 'spec_helper' describe 'Pipeline', :feature, :js do - include GitlabRoutingHelper - let(:project) { create(:empty_project) } let(:user) { create(:user) } @@ -48,7 +46,7 @@ describe 'Pipeline', :feature, :js do let(:pipeline) { create(:ci_pipeline, project: project, ref: 'master', sha: project.commit.id, user: user) } before do - visit namespace_project_pipeline_path(project.namespace, project, pipeline) + visit project_pipeline_path(project, pipeline) end it 'shows the pipeline graph' do @@ -194,7 +192,7 @@ describe 'Pipeline', :feature, :js do let(:pipeline) { create(:ci_pipeline, project: project, ref: 'master', sha: project.commit.id) } before do - visit builds_namespace_project_pipeline_path(project.namespace, project, pipeline) + visit builds_project_pipeline_path(project, pipeline) end it 'shows a list of jobs' do @@ -266,7 +264,7 @@ describe 'Pipeline', :feature, :js do describe 'GET /:project/pipelines/:id/failures' do let(:project) { create(:project) } let(:pipeline) { create(:ci_pipeline, project: project, ref: 'master', sha: project.commit.id) } - let(:pipeline_failures_page) { failures_namespace_project_pipeline_path(project.namespace, project, pipeline) } + let(:pipeline_failures_page) { failures_project_pipeline_path(project, pipeline) } let!(:failed_build) { create(:ci_build, :failed, pipeline: pipeline) } context 'with failed build' do diff --git a/spec/features/projects/pipelines/pipelines_spec.rb b/spec/features/projects/pipelines/pipelines_spec.rb index d36d073e022..a82a804e4c1 100644 --- a/spec/features/projects/pipelines/pipelines_spec.rb +++ b/spec/features/projects/pipelines/pipelines_spec.rb @@ -51,7 +51,7 @@ describe 'Pipelines', :feature, :js do context 'header tabs' do before do - visit namespace_project_pipelines_path(project.namespace, project) + visit project_pipelines_path(project) wait_for_requests end @@ -369,14 +369,14 @@ describe 'Pipelines', :feature, :js do end it 'should render pagination' do - visit namespace_project_pipelines_path(project.namespace, project) + visit project_pipelines_path(project) wait_for_requests expect(page).to have_selector('.gl-pagination') end it 'should render second page of pipelines' do - visit namespace_project_pipelines_path(project.namespace, project, page: '2') + visit project_pipelines_path(project, page: '2') wait_for_requests expect(page).to have_selector('.gl-pagination .page', count: 2) @@ -405,7 +405,7 @@ describe 'Pipelines', :feature, :js do create(:generic_commit_status, pipeline: pipeline, stage: 'external', name: 'jenkins', stage_idx: 3) - visit namespace_project_pipeline_path(project.namespace, project, pipeline) + visit project_pipeline_path(project, pipeline) wait_for_requests end @@ -440,7 +440,7 @@ describe 'Pipelines', :feature, :js do let(:project) { create(:project) } before do - visit new_namespace_project_pipeline_path(project.namespace, project) + visit new_project_pipeline_path(project) end context 'for valid commit', js: true do @@ -479,7 +479,7 @@ describe 'Pipelines', :feature, :js do let(:project) { create(:project) } before do - visit new_namespace_project_pipeline_path(project.namespace, project) + visit new_project_pipeline_path(project) end describe 'new pipeline page' do @@ -508,7 +508,7 @@ describe 'Pipelines', :feature, :js do context 'when user is not logged in' do before do - visit namespace_project_pipelines_path(project.namespace, project) + visit project_pipelines_path(project) end context 'when project is public' do @@ -526,7 +526,7 @@ describe 'Pipelines', :feature, :js do end def visit_project_pipelines(**query) - visit namespace_project_pipelines_path(project.namespace, project, query) + visit project_pipelines_path(project, query) wait_for_requests end end diff --git a/spec/features/projects/project_settings_spec.rb b/spec/features/projects/project_settings_spec.rb index baa38ff8cca..1f78f242399 100644 --- a/spec/features/projects/project_settings_spec.rb +++ b/spec/features/projects/project_settings_spec.rb @@ -12,7 +12,7 @@ describe 'Edit Project Settings', feature: true do describe 'Project settings section', js: true do it 'shows errors for invalid project name' do - visit edit_namespace_project_path(project.namespace, project) + visit edit_project_path(project) fill_in 'project_name_edit', with: 'foo&bar' click_button 'Save changes' expect(page).to have_field 'project_name_edit', with: 'foo&bar' @@ -21,7 +21,7 @@ describe 'Edit Project Settings', feature: true do end it 'shows a successful notice when the project is updated' do - visit edit_namespace_project_path(project.namespace, project) + visit edit_project_path(project) fill_in 'project_name_edit', with: 'hello world' click_button 'Save changes' expect(page).to have_content "Project 'hello world' was successfully updated." @@ -75,7 +75,7 @@ describe 'Edit Project Settings', feature: true do end specify 'the project is accessible via a redirect from the old path' do - old_path = namespace_project_path(project.namespace, project) + old_path = project_path(project) rename_project(project, path: 'bar') new_path = namespace_project_path(project.namespace, 'bar') visit old_path @@ -85,7 +85,7 @@ describe 'Edit Project Settings', feature: true do context 'and a new project is added with the same path' do it 'overrides the redirect' do - old_path = namespace_project_path(project.namespace, project) + old_path = project_path(project) rename_project(project, path: 'bar') new_project = create(:empty_project, namespace: user.namespace, path: 'gitlabhq', name: 'quz') visit old_path @@ -122,7 +122,7 @@ describe 'Edit Project Settings', feature: true do end specify 'the project is accessible via a redirect from the old path' do - old_path = namespace_project_path(project.namespace, project) + old_path = project_path(project) transfer_project(project, group) new_path = namespace_project_path(group, project) visit old_path @@ -132,7 +132,7 @@ describe 'Edit Project Settings', feature: true do context 'and a new project is added with the same path' do it 'overrides the redirect' do - old_path = namespace_project_path(project.namespace, project) + old_path = project_path(project) transfer_project(project, group) new_project = create(:empty_project, namespace: user.namespace, path: 'gitlabhq', name: 'quz') visit old_path @@ -144,7 +144,7 @@ describe 'Edit Project Settings', feature: true do end def rename_project(project, name: nil, path: nil) - visit edit_namespace_project_path(project.namespace, project) + visit edit_project_path(project) fill_in('project_name', with: name) if name fill_in('Path', with: path) if path click_button('Rename project') @@ -153,7 +153,7 @@ def rename_project(project, name: nil, path: nil) end def transfer_project(project, namespace) - visit edit_namespace_project_path(project.namespace, project) + visit edit_project_path(project) select2(namespace.id, from: '#new_namespace_id') click_button('Transfer project') confirm_transfer_modal diff --git a/spec/features/projects/ref_switcher_spec.rb b/spec/features/projects/ref_switcher_spec.rb index 016a992bdcf..342f083f25a 100644 --- a/spec/features/projects/ref_switcher_spec.rb +++ b/spec/features/projects/ref_switcher_spec.rb @@ -7,7 +7,7 @@ feature 'Ref switcher', feature: true, js: true do before do project.team << [user, :master] gitlab_sign_in(user) - visit namespace_project_tree_path(project.namespace, project, 'master') + visit project_tree_path(project, 'master') end it 'allow user to change ref by enter key' do diff --git a/spec/features/projects/services/jira_service_spec.rb b/spec/features/projects/services/jira_service_spec.rb index 8cd216c8fdb..9e4f420689c 100644 --- a/spec/features/projects/services/jira_service_spec.rb +++ b/spec/features/projects/services/jira_service_spec.rb @@ -26,7 +26,7 @@ feature 'Setup Jira service', :feature, :js do project.team << [user, :master] gitlab_sign_in(user) - visit namespace_project_settings_integrations_path(project.namespace, project) + visit project_settings_integrations_path(project) end describe 'user sets and activates Jira Service' do @@ -42,7 +42,7 @@ feature 'Setup Jira service', :feature, :js do wait_for_requests expect(page).to have_content('JIRA activated.') - expect(current_path).to eq(namespace_project_settings_integrations_path(project.namespace, project)) + expect(current_path).to eq(project_settings_integrations_path(project)) end end @@ -76,7 +76,7 @@ feature 'Setup Jira service', :feature, :js do wait_for_requests expect(page).to have_content('JIRA activated.') - expect(current_path).to eq(namespace_project_settings_integrations_path(project.namespace, project)) + expect(current_path).to eq(project_settings_integrations_path(project)) end end end @@ -89,7 +89,7 @@ feature 'Setup Jira service', :feature, :js do click_button('Save changes') expect(page).to have_content('JIRA settings saved, but not activated.') - expect(current_path).to eq(namespace_project_settings_integrations_path(project.namespace, project)) + expect(current_path).to eq(project_settings_integrations_path(project)) 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 d87985f1c92..aaa354903aa 100644 --- a/spec/features/projects/services/mattermost_slash_command_spec.rb +++ b/spec/features/projects/services/mattermost_slash_command_spec.rb @@ -10,7 +10,7 @@ feature 'Setup Mattermost slash commands', :feature, :js do stub_mattermost_setting(enabled: mattermost_enabled) project.team << [user, :master] gitlab_sign_in(user) - visit edit_namespace_project_service_path(project.namespace, project, service) + visit edit_project_service_path(project, service) end describe 'user visits the mattermost slash command config page' do @@ -30,7 +30,7 @@ feature 'Setup Mattermost slash commands', :feature, :js do fill_in 'service_token', with: token click_on 'Save changes' - expect(current_path).to eq(namespace_project_settings_integrations_path(project.namespace, project)) + expect(current_path).to eq(project_settings_integrations_path(project)) expect(page).to have_content('Mattermost slash commands settings saved, but not activated.') end @@ -41,7 +41,7 @@ feature 'Setup Mattermost slash commands', :feature, :js do check 'service_active' click_on 'Save changes' - expect(current_path).to eq(namespace_project_settings_integrations_path(project.namespace, project)) + expect(current_path).to eq(project_settings_integrations_path(project)) expect(page).to have_content('Mattermost slash commands activated.') end diff --git a/spec/features/projects/services/slack_service_spec.rb b/spec/features/projects/services/slack_service_spec.rb index 50707e6a49f..5e3c3b00476 100644 --- a/spec/features/projects/services/slack_service_spec.rb +++ b/spec/features/projects/services/slack_service_spec.rb @@ -13,7 +13,7 @@ feature 'Projects > Slack service > Setup events', feature: true do end scenario 'user can filter events by channel' do - visit edit_namespace_project_service_path(project.namespace, project, service) + visit edit_project_service_path(project, service) expect(page.find_field("service_push_channel").value).to have_content '1' expect(page.find_field("service_issue_channel").value).to have_content '2' diff --git a/spec/features/projects/services/slack_slash_command_spec.rb b/spec/features/projects/services/slack_slash_command_spec.rb index 3fae38c1799..aaa775ce51f 100644 --- a/spec/features/projects/services/slack_slash_command_spec.rb +++ b/spec/features/projects/services/slack_slash_command_spec.rb @@ -8,7 +8,7 @@ feature 'Slack slash commands', feature: true do background do project.team << [user, :master] gitlab_sign_in(user) - visit edit_namespace_project_service_path(project.namespace, project, service) + visit edit_project_service_path(project, service) end it 'shows a token placeholder' do @@ -25,7 +25,7 @@ feature 'Slack slash commands', feature: true do fill_in 'service_token', with: 'token' click_on 'Save' - expect(current_path).to eq(namespace_project_settings_integrations_path(project.namespace, project)) + expect(current_path).to eq(project_settings_integrations_path(project)) expect(page).to have_content('Slack slash commands settings saved, but not activated.') end @@ -34,7 +34,7 @@ feature 'Slack slash commands', feature: true do check 'service_active' click_on 'Save' - expect(current_path).to eq(namespace_project_settings_integrations_path(project.namespace, project)) + expect(current_path).to eq(project_settings_integrations_path(project)) expect(page).to have_content('Slack slash commands activated.') end diff --git a/spec/features/projects/settings/integration_settings_spec.rb b/spec/features/projects/settings/integration_settings_spec.rb index a59374b37ea..f708a3009f1 100644 --- a/spec/features/projects/settings/integration_settings_spec.rb +++ b/spec/features/projects/settings/integration_settings_spec.rb @@ -4,7 +4,7 @@ feature 'Integration settings', feature: true do let(:project) { create(:empty_project) } let(:user) { create(:user) } let(:role) { :developer } - let(:integrations_path) { namespace_project_settings_integrations_path(project.namespace, project) } + let(:integrations_path) { project_settings_integrations_path(project) } background do gitlab_sign_in(user) @@ -109,7 +109,7 @@ feature 'Integration settings', feature: true do scenario 'show list of hook logs' do hook_log - visit edit_namespace_project_hook_path(project.namespace, project, hook) + visit edit_project_hook_path(project, hook) expect(page).to have_content('Recent Deliveries') expect(page).to have_content(hook_log.url) @@ -117,7 +117,7 @@ feature 'Integration settings', feature: true do scenario 'show hook log details' do hook_log - visit edit_namespace_project_hook_path(project.namespace, project, hook) + visit edit_project_hook_path(project, hook) click_link 'View details' expect(page).to have_content("POST #{hook_log.url}") @@ -129,11 +129,11 @@ feature 'Integration settings', feature: true do WebMock.stub_request(:post, hook.url) hook_log - visit edit_namespace_project_hook_path(project.namespace, project, hook) + visit edit_project_hook_path(project, hook) click_link 'View details' click_link 'Resend Request' - expect(current_path).to eq(edit_namespace_project_hook_path(project.namespace, project, hook)) + expect(current_path).to eq(edit_project_hook_path(project, hook)) end end end diff --git a/spec/features/projects/settings/merge_requests_settings_spec.rb b/spec/features/projects/settings/merge_requests_settings_spec.rb index f2af14ceab2..451e2f3e04e 100644 --- a/spec/features/projects/settings/merge_requests_settings_spec.rb +++ b/spec/features/projects/settings/merge_requests_settings_spec.rb @@ -1,8 +1,6 @@ require 'spec_helper' feature 'Project settings > Merge Requests', feature: true, js: true do - include GitlabRoutingHelper - let(:project) { create(:empty_project, :public) } let(:user) { create(:user) } diff --git a/spec/features/projects/settings/pipelines_settings_spec.rb b/spec/features/projects/settings/pipelines_settings_spec.rb index c33fbd49d21..0d78feb2b93 100644 --- a/spec/features/projects/settings/pipelines_settings_spec.rb +++ b/spec/features/projects/settings/pipelines_settings_spec.rb @@ -1,8 +1,6 @@ require 'spec_helper' feature "Pipelines settings", feature: true do - include GitlabRoutingHelper - let(:project) { create(:empty_project) } let(:user) { create(:user) } let(:role) { :developer } @@ -10,7 +8,7 @@ feature "Pipelines settings", feature: true do background do gitlab_sign_in(user) project.team << [user, role] - visit namespace_project_pipelines_settings_path(project.namespace, project) + visit project_pipelines_settings_path(project) end context 'for developer' do diff --git a/spec/features/projects/settings/repository_settings_spec.rb b/spec/features/projects/settings/repository_settings_spec.rb index 35cd0d6e832..9cc04925a0a 100644 --- a/spec/features/projects/settings/repository_settings_spec.rb +++ b/spec/features/projects/settings/repository_settings_spec.rb @@ -14,7 +14,7 @@ feature 'Repository settings', feature: true do given(:role) { :developer } scenario 'is not allowed to view' do - visit namespace_project_settings_repository_path(project.namespace, project) + visit project_settings_repository_path(project) expect(page.status_code).to eq(404) end @@ -32,7 +32,7 @@ feature 'Repository settings', feature: true do project.deploy_keys << private_deploy_key project.deploy_keys << public_deploy_key - visit namespace_project_settings_repository_path(project.namespace, project) + visit project_settings_repository_path(project) expect(page.status_code).to eq(200) expect(page).to have_content('private_deploy_key') @@ -40,7 +40,7 @@ feature 'Repository settings', feature: true do end scenario 'add a new deploy key' do - visit namespace_project_settings_repository_path(project.namespace, project) + visit project_settings_repository_path(project) fill_in 'deploy_key_title', with: 'new_deploy_key' fill_in 'deploy_key_key', with: new_ssh_key @@ -53,7 +53,7 @@ feature 'Repository settings', feature: true do scenario 'edit an existing deploy key' do project.deploy_keys << private_deploy_key - visit namespace_project_settings_repository_path(project.namespace, project) + visit project_settings_repository_path(project) find('li', text: private_deploy_key.title).click_link('Edit') @@ -70,7 +70,7 @@ feature 'Repository settings', feature: true do project2.team << [user, role] project2.deploy_keys << private_deploy_key - visit namespace_project_settings_repository_path(project.namespace, project) + visit project_settings_repository_path(project) find('li', text: private_deploy_key.title).click_link('Edit') @@ -84,7 +84,7 @@ feature 'Repository settings', feature: true do scenario 'remove an existing deploy key' do project.deploy_keys << private_deploy_key - visit namespace_project_settings_repository_path(project.namespace, project) + visit project_settings_repository_path(project) find('li', text: private_deploy_key.title).click_button('Remove') diff --git a/spec/features/projects/settings/visibility_settings_spec.rb b/spec/features/projects/settings/visibility_settings_spec.rb index 18c71dee41b..a9a6441d4e8 100644 --- a/spec/features/projects/settings/visibility_settings_spec.rb +++ b/spec/features/projects/settings/visibility_settings_spec.rb @@ -7,7 +7,7 @@ feature 'Visibility settings', feature: true, js: true do context 'as owner' do before do gitlab_sign_in(user) - visit edit_namespace_project_path(project.namespace, project) + visit edit_project_path(project) end scenario 'project visibility select is available' do @@ -33,7 +33,7 @@ feature 'Visibility settings', feature: true, js: true do before do project.team << [master_user, :master] gitlab_sign_in(master_user) - visit edit_namespace_project_path(project.namespace, project) + visit edit_project_path(project) end scenario 'project visibility is locked' do diff --git a/spec/features/projects/shortcuts_spec.rb b/spec/features/projects/shortcuts_spec.rb index cec79277c33..682bea87c8a 100644 --- a/spec/features/projects/shortcuts_spec.rb +++ b/spec/features/projects/shortcuts_spec.rb @@ -8,7 +8,7 @@ feature 'Project shortcuts', feature: true do before do project.team << [user, :master] gitlab_sign_in user - visit namespace_project_path(project.namespace, project) + visit project_path(project) end describe 'pressing "i"' do diff --git a/spec/features/projects/snippets/create_snippet_spec.rb b/spec/features/projects/snippets/create_snippet_spec.rb index c75d6dbc307..37c11c0e88d 100644 --- a/spec/features/projects/snippets/create_snippet_spec.rb +++ b/spec/features/projects/snippets/create_snippet_spec.rb @@ -19,7 +19,7 @@ feature 'Create Snippet', :js, feature: true do project.team << [user, :master] gitlab_sign_in(user) - visit namespace_project_snippets_path(project.namespace, project) + visit project_snippets_path(project) click_on('New snippet') end @@ -77,7 +77,7 @@ feature 'Create Snippet', :js, feature: true do it 'shows a public snippet on the index page but not the New snippet button' do snippet = create(:project_snippet, :public, project: project) - visit namespace_project_snippets_path(project.namespace, project) + visit project_snippets_path(project) expect(page).to have_content(snippet.title) expect(page).not_to have_content('New snippet') diff --git a/spec/features/projects/snippets/show_spec.rb b/spec/features/projects/snippets/show_spec.rb index 9e73ba4123b..d401d09497f 100644 --- a/spec/features/projects/snippets/show_spec.rb +++ b/spec/features/projects/snippets/show_spec.rb @@ -15,7 +15,7 @@ feature 'Project snippet', :js, feature: true do let(:content) { project.repository.blob_at('master', 'files/ruby/popen.rb').data } before do - visit namespace_project_snippet_path(project.namespace, project, snippet) + visit project_snippet_path(project, snippet) wait_for_requests end @@ -46,7 +46,7 @@ feature 'Project snippet', :js, feature: true do context 'visiting directly' do before do - visit namespace_project_snippet_path(project.namespace, project, snippet) + visit project_snippet_path(project, snippet) wait_for_requests end @@ -118,7 +118,7 @@ feature 'Project snippet', :js, feature: true do context 'visiting with a line number anchor' do before do - visit namespace_project_snippet_path(project.namespace, project, snippet, anchor: 'L1') + visit project_snippet_path(project, snippet, anchor: 'L1') wait_for_requests end diff --git a/spec/features/projects/snippets_spec.rb b/spec/features/projects/snippets_spec.rb index 80dbffaffc7..8edef2eba13 100644 --- a/spec/features/projects/snippets_spec.rb +++ b/spec/features/projects/snippets_spec.rb @@ -10,7 +10,7 @@ describe 'Project snippets', :js, feature: true do before do allow(Snippet).to receive(:default_per_page).and_return(1) - visit namespace_project_snippets_path(project.namespace, project) + visit project_snippets_path(project) end it_behaves_like 'paginated snippets' @@ -18,7 +18,7 @@ describe 'Project snippets', :js, feature: true do context 'list content' do it 'contains all project snippets' do - visit namespace_project_snippets_path(project.namespace, project) + visit project_snippets_path(project) expect(page).to have_selector('.snippet-row', count: 2) @@ -30,7 +30,7 @@ describe 'Project snippets', :js, feature: true do context 'when submitting a note' do before do gitlab_sign_in :admin - visit namespace_project_snippet_path(project.namespace, project, snippets[0]) + visit project_snippet_path(project, snippets[0]) end it 'should have autocomplete' do diff --git a/spec/features/projects/sub_group_issuables_spec.rb b/spec/features/projects/sub_group_issuables_spec.rb index 63eb97d5a92..5bbad78d0bb 100644 --- a/spec/features/projects/sub_group_issuables_spec.rb +++ b/spec/features/projects/sub_group_issuables_spec.rb @@ -12,13 +12,13 @@ describe 'Subgroup Issuables', :feature, :js, :nested_groups do end it 'shows the full subgroup title when issues index page is empty' do - visit namespace_project_issues_path(project.namespace.to_param, project.to_param) + visit project_issues_path(project) expect_to_have_full_subgroup_title end it 'shows the full subgroup title when merge requests index page is empty' do - visit namespace_project_merge_requests_path(project.namespace.to_param, project.to_param) + visit project_merge_requests_path(project) expect_to_have_full_subgroup_title end diff --git a/spec/features/projects/tags/download_buttons_spec.rb b/spec/features/projects/tags/download_buttons_spec.rb index ca00a51aa3c..186876e454f 100644 --- a/spec/features/projects/tags/download_buttons_spec.rb +++ b/spec/features/projects/tags/download_buttons_spec.rb @@ -30,13 +30,11 @@ feature 'Download buttons in tags page', feature: true do describe 'when checking tags' do context 'with artifacts' do before do - visit namespace_project_tags_path(project.namespace, project) + visit project_tags_path(project) end scenario 'shows download artifacts button' do - href = latest_succeeded_namespace_project_artifacts_path( - project.namespace, project, "#{tag}/download", - job: 'build') + href = latest_succeeded_project_artifacts_path(project, "#{tag}/download", job: 'build') expect(page).to have_link "Download '#{build.name}'", href: href end diff --git a/spec/features/projects/tree/rss_spec.rb b/spec/features/projects/tree/rss_spec.rb index 135584e5bf8..4583374c931 100644 --- a/spec/features/projects/tree/rss_spec.rb +++ b/spec/features/projects/tree/rss_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' feature 'Project Tree RSS' do let(:project) { create(:project, :repository, visibility_level: Gitlab::VisibilityLevel::PUBLIC) } - let(:path) { namespace_project_tree_path(project.namespace, project, :master) } + let(:path) { project_tree_path(project, :master) } context 'when signed in' do before do diff --git a/spec/features/projects/user_create_dir_spec.rb b/spec/features/projects/user_create_dir_spec.rb index 5d0acad3832..01f288934bf 100644 --- a/spec/features/projects/user_create_dir_spec.rb +++ b/spec/features/projects/user_create_dir_spec.rb @@ -8,7 +8,7 @@ feature 'New directory creation', feature: true, js: true do background do gitlab_sign_in(user) project.team << [user, role] - visit namespace_project_tree_path(project.namespace, project, 'master') + visit project_tree_path(project, 'master') open_new_directory_modal fill_in 'dir_name', with: 'new_directory' end @@ -51,7 +51,7 @@ feature 'New directory creation', feature: true, js: true do expect(page).to have_content 'New Merge Request' expect(page).to have_content "From #{new_branch_name} into master" expect(page).to have_content 'Add new directory' - expect(current_path).to eq(namespace_project_new_merge_request_path(project.namespace, project)) + expect(current_path).to eq(project_new_merge_request_path(project)) end end end diff --git a/spec/features/projects/user_creates_project_spec.rb b/spec/features/projects/user_creates_project_spec.rb index 29f1eb8d73e..1c3791f63ac 100644 --- a/spec/features/projects/user_creates_project_spec.rb +++ b/spec/features/projects/user_creates_project_spec.rb @@ -18,7 +18,7 @@ feature 'User creates a project', js: true do project = Project.last - expect(current_path).to eq(namespace_project_path(project.namespace, project)) + expect(current_path).to eq(project_path(project)) expect(page).to have_content('Empty') expect(page).to have_content('git init') expect(page).to have_content('git remote') diff --git a/spec/features/projects/view_on_env_spec.rb b/spec/features/projects/view_on_env_spec.rb index f6a640b90b4..0c06aa25c06 100644 --- a/spec/features/projects/view_on_env_spec.rb +++ b/spec/features/projects/view_on_env_spec.rb @@ -52,7 +52,7 @@ describe 'View on environment', js: true do before do gitlab_sign_in(user) - visit diffs_namespace_project_merge_request_path(project.namespace, project, merge_request) + visit diffs_project_merge_request_path(project, merge_request) wait_for_requests end @@ -68,7 +68,7 @@ describe 'View on environment', js: true do before do gitlab_sign_in(user) - visit namespace_project_compare_path(project.namespace, project, from: 'master', to: branch_name) + visit project_compare_path(project, from: 'master', to: branch_name) wait_for_requests end @@ -82,7 +82,7 @@ describe 'View on environment', js: true do before do gitlab_sign_in(user) - visit namespace_project_compare_path(project.namespace, project, from: 'master', to: sha) + visit project_compare_path(project, from: 'master', to: sha) wait_for_requests end @@ -96,7 +96,7 @@ describe 'View on environment', js: true do before do gitlab_sign_in(user) - visit namespace_project_blob_path(project.namespace, project, File.join(branch_name, file_path)) + visit project_blob_path(project, File.join(branch_name, file_path)) wait_for_requests end @@ -110,7 +110,7 @@ describe 'View on environment', js: true do before do gitlab_sign_in(user) - visit namespace_project_blob_path(project.namespace, project, File.join(sha, file_path)) + visit project_blob_path(project, File.join(sha, file_path)) wait_for_requests end @@ -124,7 +124,7 @@ describe 'View on environment', js: true do before do gitlab_sign_in(user) - visit namespace_project_commit_path(project.namespace, project, sha) + visit project_commit_path(project, sha) wait_for_requests end diff --git a/spec/features/projects/wiki/markdown_preview_spec.rb b/spec/features/projects/wiki/markdown_preview_spec.rb index fd6c09943e3..d79ab809c7d 100644 --- a/spec/features/projects/wiki/markdown_preview_spec.rb +++ b/spec/features/projects/wiki/markdown_preview_spec.rb @@ -18,7 +18,7 @@ feature 'Projects > Wiki > User previews markdown changes', feature: true, js: t gitlab_sign_in(user) - visit namespace_project_path(project.namespace, project) + visit project_path(project) find('.shortcuts-wiki').trigger('click') end diff --git a/spec/features/projects/wiki/shortcuts_spec.rb b/spec/features/projects/wiki/shortcuts_spec.rb index ab0ed9b8204..d189f84da0e 100644 --- a/spec/features/projects/wiki/shortcuts_spec.rb +++ b/spec/features/projects/wiki/shortcuts_spec.rb @@ -9,7 +9,7 @@ feature 'Wiki shortcuts', :feature, :js do before do gitlab_sign_in(user) - visit namespace_project_wiki_path(project.namespace, project, wiki_page) + visit project_wiki_path(project, wiki_page) end scenario 'Visit edit wiki page using "e" keyboard shortcut' do diff --git a/spec/features/projects/wiki/user_creates_wiki_page_spec.rb b/spec/features/projects/wiki/user_creates_wiki_page_spec.rb index a477dcf7ee9..9d66f482c8d 100644 --- a/spec/features/projects/wiki/user_creates_wiki_page_spec.rb +++ b/spec/features/projects/wiki/user_creates_wiki_page_spec.rb @@ -1,20 +1,23 @@ require 'spec_helper' -feature 'Projects > Wiki > User creates wiki page', js: true, feature: true do +feature 'Projects > Wiki > User creates wiki page', :js do let(:user) { create(:user) } background do project.team << [user, :master] - gitlab_sign_in(user) + sign_in(user) - visit namespace_project_path(project.namespace, project) - find('.shortcuts-wiki').trigger('click') + visit project_path(project) end context 'in the user namespace' do let(:project) { create(:project, namespace: user.namespace) } context 'when wiki is empty' do + before do + find('.shortcuts-wiki').trigger('click') + end + scenario 'commit message field has value "Create home"' do expect(page).to have_field('wiki[message]', with: 'Create home') end @@ -67,10 +70,11 @@ feature 'Projects > Wiki > User creates wiki page', js: true, feature: true do context 'when wiki is not empty' do before do WikiPages::CreateService.new(project, user, title: 'home', content: 'Home page').execute + find('.shortcuts-wiki').trigger('click') end context 'via the "new wiki page" page' do - scenario 'when the wiki page has a single word name', js: true do + scenario 'when the wiki page has a single word name' do click_link 'New page' page.within '#modal-new-wiki' do @@ -91,7 +95,7 @@ feature 'Projects > Wiki > User creates wiki page', js: true, feature: true do expect(page).to have_content('My awesome wiki!') end - scenario 'when the wiki page has spaces in the name', js: true do + scenario 'when the wiki page has spaces in the name' do click_link 'New page' page.within '#modal-new-wiki' do @@ -112,7 +116,7 @@ feature 'Projects > Wiki > User creates wiki page', js: true, feature: true do expect(page).to have_content('My awesome wiki!') end - scenario 'when the wiki page has hyphens in the name', js: true do + scenario 'when the wiki page has hyphens in the name' do click_link 'New page' page.within '#modal-new-wiki' do @@ -134,7 +138,7 @@ feature 'Projects > Wiki > User creates wiki page', js: true, feature: true do end end - scenario 'content has autocomplete', :js do + scenario 'content has autocomplete' do click_link 'New page' page.within '#modal-new-wiki' do @@ -156,6 +160,10 @@ feature 'Projects > Wiki > User creates wiki page', js: true, feature: true do let(:project) { create(:project, namespace: create(:group, :public)) } context 'when wiki is empty' do + before do + find('.shortcuts-wiki').trigger('click') + end + scenario 'commit message field has value "Create home"' do expect(page).to have_field('wiki[message]', with: 'Create home') end @@ -175,9 +183,10 @@ feature 'Projects > Wiki > User creates wiki page', js: true, feature: true do context 'when wiki is not empty' do before do WikiPages::CreateService.new(project, user, title: 'home', content: 'Home page').execute + find('.shortcuts-wiki').trigger('click') end - scenario 'via the "new wiki page" page', js: true do + scenario 'via the "new wiki page" page' do click_link 'New page' page.within '#modal-new-wiki' do diff --git a/spec/features/projects/wiki/user_git_access_wiki_page_spec.rb b/spec/features/projects/wiki/user_git_access_wiki_page_spec.rb index 7d31122af35..749721b97eb 100644 --- a/spec/features/projects/wiki/user_git_access_wiki_page_spec.rb +++ b/spec/features/projects/wiki/user_git_access_wiki_page_spec.rb @@ -17,7 +17,7 @@ describe 'Projects > Wiki > User views Git access wiki page', :feature do end scenario 'Visit Wiki Page Current Commit' do - visit namespace_project_wiki_path(project.namespace, project, wiki_page) + visit project_wiki_path(project, wiki_page) click_link 'Clone repository' expect(page).to have_text("Clone repository #{project.wiki.path_with_namespace}") diff --git a/spec/features/projects/wiki/user_updates_wiki_page_spec.rb b/spec/features/projects/wiki/user_updates_wiki_page_spec.rb index 64a30438681..3b9f7ff96fb 100644 --- a/spec/features/projects/wiki/user_updates_wiki_page_spec.rb +++ b/spec/features/projects/wiki/user_updates_wiki_page_spec.rb @@ -8,7 +8,7 @@ feature 'Projects > Wiki > User updates wiki page', feature: true do WikiPages::CreateService.new(project, user, title: 'home', content: 'Home page').execute gitlab_sign_in(user) - visit namespace_project_wikis_path(project.namespace, project) + visit project_wikis_path(project) end context 'in the user namespace' do diff --git a/spec/features/projects/wiki/user_views_project_wiki_page_spec.rb b/spec/features/projects/wiki/user_views_project_wiki_page_spec.rb index 8a88ab247f3..8e3912d994e 100644 --- a/spec/features/projects/wiki/user_views_project_wiki_page_spec.rb +++ b/spec/features/projects/wiki/user_views_project_wiki_page_spec.rb @@ -26,18 +26,13 @@ feature 'Projects > Wiki > User views the wiki page', feature: true do end scenario 'Visit Wiki Page Current Commit' do - visit namespace_project_wiki_path(project.namespace, project, wiki_page) + visit project_wiki_path(project, wiki_page) expect(page).to have_selector('a.btn', text: 'Edit') end scenario 'Visit Wiki Page Historical Commit' do - visit namespace_project_wiki_path( - project.namespace, - project, - wiki_page, - version_id: old_page_version_id - ) + visit project_wiki_path(project, wiki_page, version_id: old_page_version_id) expect(page).not_to have_selector('a.btn', text: 'Edit') end diff --git a/spec/features/projects/wiki/user_views_wiki_in_project_page_spec.rb b/spec/features/projects/wiki/user_views_wiki_in_project_page_spec.rb index 36799925167..a305d27c7ec 100644 --- a/spec/features/projects/wiki/user_views_wiki_in_project_page_spec.rb +++ b/spec/features/projects/wiki/user_views_wiki_in_project_page_spec.rb @@ -27,14 +27,10 @@ describe 'Projects > Wiki > User views wiki in project page', feature: true do end it 'displays the correct URL for the link' do - visit namespace_project_path(project.namespace, project) + visit project_path(project) expect(page).to have_link( 'some link', - href: namespace_project_wiki_path( - project.namespace, - project, - 'other-page' - ) + href: project_wiki_path(project, 'other-page') ) end end diff --git a/spec/features/projects_spec.rb b/spec/features/projects_spec.rb index 7e8a703db93..361e3a6d8e5 100644 --- a/spec/features/projects_spec.rb +++ b/spec/features/projects_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' feature 'Project', feature: true do describe 'description' do let(:project) { create(:project, :repository) } - let(:path) { namespace_project_path(project.namespace, project) } + let(:path) { project_path(project) } before do gitlab_sign_in(:admin) @@ -41,7 +41,7 @@ feature 'Project', feature: true do before do gitlab_sign_in user create(:forked_project_link, forked_to_project: project) - visit edit_namespace_project_path(project.namespace, project) + visit edit_project_path(project) end it 'removes fork' do @@ -62,7 +62,7 @@ feature 'Project', feature: true do before do gitlab_sign_in(user) project.team << [user, :master] - visit edit_namespace_project_path(project.namespace, project) + visit edit_project_path(project) end it 'removes a project' do @@ -81,7 +81,7 @@ feature 'Project', feature: true do before do gitlab_sign_in(user) project.add_user(user, Gitlab::Access::MASTER) - visit namespace_project_path(project.namespace, project) + visit project_path(project) end it 'clicks toggle and shows dropdown', js: true do @@ -101,7 +101,7 @@ feature 'Project', feature: true do gitlab_sign_in(user) project.add_user(user, Gitlab::Access::MASTER) project2.add_user(user, Gitlab::Access::MASTER) - visit namespace_project_issue_path(project.namespace, project, issue) + visit project_issue_path(project, issue) end it 'clicks toggle and shows dropdown' do @@ -124,7 +124,7 @@ feature 'Project', feature: true do before do project.team << [user, :master] gitlab_sign_in user - visit namespace_project_path(project.namespace, project) + visit project_path(project) end it 'has working links to files' do diff --git a/spec/features/protected_branches_spec.rb b/spec/features/protected_branches_spec.rb index 20b8e10f0f7..952eb6c3643 100644 --- a/spec/features/protected_branches_spec.rb +++ b/spec/features/protected_branches_spec.rb @@ -16,7 +16,7 @@ feature 'Protected Branches', feature: true, js: true do describe "explicit protected branches" do it "allows creating explicit protected branches" do - visit namespace_project_protected_branches_path(project.namespace, project) + visit project_protected_branches_path(project) set_protected_branch_name('some-branch') click_on "Protect" @@ -29,7 +29,7 @@ feature 'Protected Branches', feature: true, js: true do commit = create(:commit, project: project) project.repository.add_branch(user, 'some-branch', commit.id) - visit namespace_project_protected_branches_path(project.namespace, project) + visit project_protected_branches_path(project) set_protected_branch_name('some-branch') click_on "Protect" @@ -37,7 +37,7 @@ feature 'Protected Branches', feature: true, js: true do end it "displays an error message if the named branch does not exist" do - visit namespace_project_protected_branches_path(project.namespace, project) + visit project_protected_branches_path(project) set_protected_branch_name('some-branch') click_on "Protect" @@ -47,7 +47,7 @@ feature 'Protected Branches', feature: true, js: true do describe "wildcard protected branches" do it "allows creating protected branches with a wildcard" do - visit namespace_project_protected_branches_path(project.namespace, project) + visit project_protected_branches_path(project) set_protected_branch_name('*-stable') click_on "Protect" @@ -60,7 +60,7 @@ feature 'Protected Branches', feature: true, js: true do project.repository.add_branch(user, 'production-stable', 'master') project.repository.add_branch(user, 'staging-stable', 'master') - visit namespace_project_protected_branches_path(project.namespace, project) + visit project_protected_branches_path(project) set_protected_branch_name('*-stable') click_on "Protect" @@ -72,11 +72,11 @@ feature 'Protected Branches', feature: true, js: true do project.repository.add_branch(user, 'staging-stable', 'master') project.repository.add_branch(user, 'development', 'master') - visit namespace_project_protected_branches_path(project.namespace, project) + visit project_protected_branches_path(project) set_protected_branch_name('*-stable') click_on "Protect" - visit namespace_project_protected_branches_path(project.namespace, project) + visit project_protected_branches_path(project) click_on "2 matching branches" within(".protected-branches-list") do diff --git a/spec/features/protected_tags_spec.rb b/spec/features/protected_tags_spec.rb index 73a80692154..4ffd97fb221 100644 --- a/spec/features/protected_tags_spec.rb +++ b/spec/features/protected_tags_spec.rb @@ -17,7 +17,7 @@ feature 'Projected Tags', feature: true, js: true do describe "explicit protected tags" do it "allows creating explicit protected tags" do - visit namespace_project_protected_tags_path(project.namespace, project) + visit project_protected_tags_path(project) set_protected_tag_name('some-tag') click_on "Protect" @@ -30,7 +30,7 @@ feature 'Projected Tags', feature: true, js: true do commit = create(:commit, project: project) project.repository.add_tag(user, 'some-tag', commit.id) - visit namespace_project_protected_tags_path(project.namespace, project) + visit project_protected_tags_path(project) set_protected_tag_name('some-tag') click_on "Protect" @@ -38,7 +38,7 @@ feature 'Projected Tags', feature: true, js: true do end it "displays an error message if the named tag does not exist" do - visit namespace_project_protected_tags_path(project.namespace, project) + visit project_protected_tags_path(project) set_protected_tag_name('some-tag') click_on "Protect" @@ -48,7 +48,7 @@ feature 'Projected Tags', feature: true, js: true do describe "wildcard protected tags" do it "allows creating protected tags with a wildcard" do - visit namespace_project_protected_tags_path(project.namespace, project) + visit project_protected_tags_path(project) set_protected_tag_name('*-stable') click_on "Protect" @@ -61,7 +61,7 @@ feature 'Projected Tags', feature: true, js: true do project.repository.add_tag(user, 'production-stable', 'master') project.repository.add_tag(user, 'staging-stable', 'master') - visit namespace_project_protected_tags_path(project.namespace, project) + visit project_protected_tags_path(project) set_protected_tag_name('*-stable') click_on "Protect" @@ -73,11 +73,11 @@ feature 'Projected Tags', feature: true, js: true do project.repository.add_tag(user, 'staging-stable', 'master') project.repository.add_tag(user, 'development', 'master') - visit namespace_project_protected_tags_path(project.namespace, project) + visit project_protected_tags_path(project) set_protected_tag_name('*-stable') click_on "Protect" - visit namespace_project_protected_tags_path(project.namespace, project) + visit project_protected_tags_path(project) click_on "2 matching tags" within(".protected-tags-list") do diff --git a/spec/features/reportable_note/commit_spec.rb b/spec/features/reportable_note/commit_spec.rb index 12049822753..2486f779753 100644 --- a/spec/features/reportable_note/commit_spec.rb +++ b/spec/features/reportable_note/commit_spec.rb @@ -15,7 +15,7 @@ describe 'Reportable note on commit', :feature, :js do let!(:note) { create(:note_on_commit, commit_id: sample_commit.id, project: project) } before do - visit namespace_project_commit_path(project.namespace, project, sample_commit.id) + visit project_commit_path(project, sample_commit.id) end it_behaves_like 'reportable note' @@ -25,7 +25,7 @@ describe 'Reportable note on commit', :feature, :js do let!(:note) { create(:diff_note_on_commit, commit_id: sample_commit.id, project: project) } before do - visit namespace_project_commit_path(project.namespace, project, sample_commit.id) + visit project_commit_path(project, sample_commit.id) end it_behaves_like 'reportable note' diff --git a/spec/features/reportable_note/issue_spec.rb b/spec/features/reportable_note/issue_spec.rb index ca2a7f41496..d283c2d3c8f 100644 --- a/spec/features/reportable_note/issue_spec.rb +++ b/spec/features/reportable_note/issue_spec.rb @@ -10,7 +10,7 @@ describe 'Reportable note on issue', :feature, :js do project.add_master(user) gitlab_sign_in(user) - visit namespace_project_issue_path(project.namespace, project, issue) + visit project_issue_path(project, issue) end it_behaves_like 'reportable note' diff --git a/spec/features/reportable_note/merge_request_spec.rb b/spec/features/reportable_note/merge_request_spec.rb index 8e75b4af3eb..fe25c894b85 100644 --- a/spec/features/reportable_note/merge_request_spec.rb +++ b/spec/features/reportable_note/merge_request_spec.rb @@ -9,7 +9,7 @@ describe 'Reportable note on merge request', :feature, :js do project.add_master(user) gitlab_sign_in(user) - visit namespace_project_merge_request_path(project.namespace, project, merge_request) + visit project_merge_request_path(project, merge_request) end context 'a normal note' do diff --git a/spec/features/reportable_note/snippets_spec.rb b/spec/features/reportable_note/snippets_spec.rb index 5bee4a31379..b3044d3d048 100644 --- a/spec/features/reportable_note/snippets_spec.rb +++ b/spec/features/reportable_note/snippets_spec.rb @@ -14,7 +14,7 @@ describe 'Reportable note on snippets', :feature, :js do let!(:note) { create(:note_on_project_snippet, noteable: snippet, project: project) } before do - visit namespace_project_snippet_path(project.namespace, project, snippet) + visit project_snippet_path(project, snippet) end it_behaves_like 'reportable note' diff --git a/spec/features/runners_spec.rb b/spec/features/runners_spec.rb index ea18879b4bf..00f59f8f197 100644 --- a/spec/features/runners_spec.rb +++ b/spec/features/runners_spec.rb @@ -1,8 +1,6 @@ require 'spec_helper' describe "Runners" do - include GitlabRoutingHelper - let(:user) { create(:user) } before do @@ -124,7 +122,7 @@ describe "Runners" do end scenario 'user checks default configuration' do - visit namespace_project_runner_path(project.namespace, project, runner) + visit project_runner_path(project, runner) expect(page).to have_content 'Can run untagged jobs Yes' end diff --git a/spec/features/search_spec.rb b/spec/features/search_spec.rb index 64469f999af..69b42193955 100644 --- a/spec/features/search_spec.rb +++ b/spec/features/search_spec.rb @@ -88,7 +88,7 @@ describe "Search", feature: true do end it 'finds comment' do - visit namespace_project_path(project.namespace, project) + visit project_path(project) page.within '.search' do fill_in 'search', with: note.note @@ -111,7 +111,7 @@ describe "Search", feature: true do project: project) # Must visit project dashboard since global search won't search # everything (e.g. comments, snippets, etc.) - visit namespace_project_path(project.namespace, project) + visit project_path(project) page.within '.search' do fill_in 'search', with: note.note @@ -125,7 +125,7 @@ describe "Search", feature: true do it 'finds a commit' do project = create(:project, :repository) { |p| p.add_reporter(user) } - visit namespace_project_path(project.namespace, project) + visit project_path(project) page.within '.search' do fill_in 'search', with: 'add' @@ -139,7 +139,7 @@ describe "Search", feature: true do it 'finds a code' do project = create(:project, :repository) { |p| p.add_reporter(user) } - visit namespace_project_path(project.namespace, project) + visit project_path(project) page.within '.search' do fill_in 'search', with: 'application.js' @@ -156,7 +156,7 @@ describe "Search", feature: true do describe 'Right header search field', feature: true do it 'allows enter key to search', js: true do - visit namespace_project_path(project.namespace, project) + visit project_path(project) fill_in 'search', with: 'gitlab' find('#search').native.send_keys(:enter) @@ -167,7 +167,7 @@ describe "Search", feature: true do describe 'Search in project page' do before do - visit namespace_project_path(project.namespace, project) + visit project_path(project) end it 'shows top right search form' do @@ -256,7 +256,7 @@ describe "Search", feature: true do click_button 'Search' - expect(page).to have_current_path(namespace_project_commit_path(project.namespace, project, '6d394385cf567f80a8fd85055db1ab4c5295806f')) + expect(page).to have_current_path(project_commit_path(project, '6d394385cf567f80a8fd85055db1ab4c5295806f')) end it 'redirects to single commit regardless of query case' do @@ -264,7 +264,7 @@ describe "Search", feature: true do click_button 'Search' - expect(page).to have_current_path(namespace_project_commit_path(project.namespace, project, '6d394385cf567f80a8fd85055db1ab4c5295806f')) + expect(page).to have_current_path(project_commit_path(project, '6d394385cf567f80a8fd85055db1ab4c5295806f')) end it 'holds on /search page when the only commit is found by message' do diff --git a/spec/features/security/project/internal_access_spec.rb b/spec/features/security/project/internal_access_spec.rb index 5e26b8bbed6..1000a0bdd89 100644 --- a/spec/features/security/project/internal_access_spec.rb +++ b/spec/features/security/project/internal_access_spec.rb @@ -13,7 +13,7 @@ describe "Internal Project Access", feature: true do end describe "GET /:project_path" do - subject { namespace_project_path(project.namespace, project) } + subject { project_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -27,7 +27,7 @@ describe "Internal Project Access", feature: true do end describe "GET /:project_path/tree/master" do - subject { namespace_project_tree_path(project.namespace, project, project.repository.root_ref) } + subject { project_tree_path(project, project.repository.root_ref) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -41,7 +41,7 @@ describe "Internal Project Access", feature: true do end describe "GET /:project_path/commits/master" do - subject { namespace_project_commits_path(project.namespace, project, project.repository.root_ref, limit: 1) } + subject { project_commits_path(project, project.repository.root_ref, limit: 1) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -55,7 +55,7 @@ describe "Internal Project Access", feature: true do end describe "GET /:project_path/commit/:sha" do - subject { namespace_project_commit_path(project.namespace, project, project.repository.commit) } + subject { project_commit_path(project, project.repository.commit) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -69,7 +69,7 @@ describe "Internal Project Access", feature: true do end describe "GET /:project_path/compare" do - subject { namespace_project_compare_index_path(project.namespace, project) } + subject { project_compare_index_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -83,7 +83,7 @@ describe "Internal Project Access", feature: true do end describe "GET /:project_path/settings/members" do - subject { namespace_project_settings_members_path(project.namespace, project) } + subject { project_settings_members_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -97,7 +97,7 @@ describe "Internal Project Access", feature: true do end describe "GET /:project_path/settings/ci_cd" do - subject { namespace_project_settings_ci_cd_path(project.namespace, project) } + subject { project_settings_ci_cd_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -111,7 +111,7 @@ describe "Internal Project Access", feature: true do end describe "GET /:project_path/settings/repository" do - subject { namespace_project_settings_repository_path(project.namespace, project) } + subject { project_settings_repository_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -126,7 +126,7 @@ describe "Internal Project Access", feature: true do describe "GET /:project_path/blob" do let(:commit) { project.repository.commit } - subject { namespace_project_blob_path(project.namespace, project, File.join(commit.id, '.gitignore')) } + subject { project_blob_path(project, File.join(commit.id, '.gitignore')) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -140,7 +140,7 @@ describe "Internal Project Access", feature: true do end describe "GET /:project_path/edit" do - subject { edit_namespace_project_path(project.namespace, project) } + subject { edit_project_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -154,7 +154,7 @@ describe "Internal Project Access", feature: true do end describe "GET /:project_path/deploy_keys" do - subject { namespace_project_deploy_keys_path(project.namespace, project) } + subject { project_deploy_keys_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -168,7 +168,7 @@ describe "Internal Project Access", feature: true do end describe "GET /:project_path/issues" do - subject { namespace_project_issues_path(project.namespace, project) } + subject { project_issues_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -183,7 +183,7 @@ describe "Internal Project Access", feature: true do describe "GET /:project_path/issues/:id/edit" do let(:issue) { create(:issue, project: project) } - subject { edit_namespace_project_issue_path(project.namespace, project, issue) } + subject { edit_project_issue_path(project, issue) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -197,7 +197,7 @@ describe "Internal Project Access", feature: true do end describe "GET /:project_path/snippets" do - subject { namespace_project_snippets_path(project.namespace, project) } + subject { project_snippets_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -211,7 +211,7 @@ describe "Internal Project Access", feature: true do end describe "GET /:project_path/snippets/new" do - subject { new_namespace_project_snippet_path(project.namespace, project) } + subject { new_project_snippet_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -225,7 +225,7 @@ describe "Internal Project Access", feature: true do end describe "GET /:project_path/merge_requests" do - subject { namespace_project_merge_requests_path(project.namespace, project) } + subject { project_merge_requests_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -239,7 +239,7 @@ describe "Internal Project Access", feature: true do end describe "GET /:project_path/merge_requests/new" do - subject { namespace_project_new_merge_request_path(project.namespace, project) } + subject { project_new_merge_request_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -253,7 +253,7 @@ describe "Internal Project Access", feature: true do end describe "GET /:project_path/branches" do - subject { namespace_project_branches_path(project.namespace, project) } + subject { project_branches_path(project) } before do # Speed increase @@ -272,7 +272,7 @@ describe "Internal Project Access", feature: true do end describe "GET /:project_path/tags" do - subject { namespace_project_tags_path(project.namespace, project) } + subject { project_tags_path(project) } before do # Speed increase @@ -291,7 +291,7 @@ describe "Internal Project Access", feature: true do end describe "GET /:project_path/settings/integrations" do - subject { namespace_project_settings_integrations_path(project.namespace, project) } + subject { project_settings_integrations_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -305,7 +305,7 @@ describe "Internal Project Access", feature: true do end describe "GET /:project_path/pipelines" do - subject { namespace_project_pipelines_path(project.namespace, project) } + subject { project_pipelines_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -320,7 +320,7 @@ describe "Internal Project Access", feature: true do describe "GET /:project_path/pipelines/:id" do let(:pipeline) { create(:ci_pipeline, project: project) } - subject { namespace_project_pipeline_path(project.namespace, project, pipeline) } + subject { project_pipeline_path(project, pipeline) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -334,7 +334,7 @@ describe "Internal Project Access", feature: true do end describe "GET /:project_path/builds" do - subject { namespace_project_jobs_path(project.namespace, project) } + subject { project_jobs_path(project) } context "when allowed for public and internal" do before do @@ -372,7 +372,7 @@ describe "Internal Project Access", feature: true do describe "GET /:project_path/builds/:id" do let(:pipeline) { create(:ci_pipeline, project: project) } let(:build) { create(:ci_build, pipeline: pipeline) } - subject { namespace_project_job_path(project.namespace, project, build.id) } + subject { project_job_path(project, build.id) } context "when allowed for public and internal" do before do @@ -410,7 +410,7 @@ describe "Internal Project Access", feature: true do describe 'GET /:project_path/builds/:id/trace' do let(:pipeline) { create(:ci_pipeline, project: project) } let(:build) { create(:ci_build, pipeline: pipeline) } - subject { trace_namespace_project_job_path(project.namespace, project, build.id) } + subject { trace_project_job_path(project, build.id) } context 'when allowed for public and internal' do before do @@ -446,7 +446,7 @@ describe "Internal Project Access", feature: true do end describe "GET /:project_path/pipeline_schedules" do - subject { namespace_project_pipeline_schedules_path(project.namespace, project) } + subject { project_pipeline_schedules_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -460,7 +460,7 @@ describe "Internal Project Access", feature: true do end describe "GET /:project_path/environments" do - subject { namespace_project_environments_path(project.namespace, project) } + subject { project_environments_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -475,7 +475,7 @@ describe "Internal Project Access", feature: true do describe "GET /:project_path/environments/:id" do let(:environment) { create(:environment, project: project) } - subject { namespace_project_environment_path(project.namespace, project, environment) } + subject { project_environment_path(project, environment) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -490,7 +490,7 @@ describe "Internal Project Access", feature: true do describe "GET /:project_path/environments/:id/deployments" do let(:environment) { create(:environment, project: project) } - subject { namespace_project_environment_deployments_path(project.namespace, project, environment) } + subject { project_environment_deployments_path(project, environment) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -504,7 +504,7 @@ describe "Internal Project Access", feature: true do end describe "GET /:project_path/environments/new" do - subject { new_namespace_project_environment_path(project.namespace, project) } + subject { new_project_environment_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -526,7 +526,7 @@ describe "Internal Project Access", feature: true do project.container_repositories << container_repository end - subject { namespace_project_container_registry_index_path(project.namespace, project) } + subject { project_container_registry_index_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } diff --git a/spec/features/security/project/private_access_spec.rb b/spec/features/security/project/private_access_spec.rb index b676c236758..94d759393ca 100644 --- a/spec/features/security/project/private_access_spec.rb +++ b/spec/features/security/project/private_access_spec.rb @@ -13,7 +13,7 @@ describe "Private Project Access", feature: true do end describe "GET /:project_path" do - subject { namespace_project_path(project.namespace, project) } + subject { project_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -27,7 +27,7 @@ describe "Private Project Access", feature: true do end describe "GET /:project_path/tree/master" do - subject { namespace_project_tree_path(project.namespace, project, project.repository.root_ref) } + subject { project_tree_path(project, project.repository.root_ref) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -41,7 +41,7 @@ describe "Private Project Access", feature: true do end describe "GET /:project_path/commits/master" do - subject { namespace_project_commits_path(project.namespace, project, project.repository.root_ref, limit: 1) } + subject { project_commits_path(project, project.repository.root_ref, limit: 1) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -55,7 +55,7 @@ describe "Private Project Access", feature: true do end describe "GET /:project_path/commit/:sha" do - subject { namespace_project_commit_path(project.namespace, project, project.repository.commit) } + subject { project_commit_path(project, project.repository.commit) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -69,7 +69,7 @@ describe "Private Project Access", feature: true do end describe "GET /:project_path/compare" do - subject { namespace_project_compare_index_path(project.namespace, project) } + subject { project_compare_index_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -83,7 +83,7 @@ describe "Private Project Access", feature: true do end describe "GET /:project_path/settings/members" do - subject { namespace_project_settings_members_path(project.namespace, project) } + subject { project_settings_members_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -97,7 +97,7 @@ describe "Private Project Access", feature: true do end describe "GET /:project_path/settings/ci_cd" do - subject { namespace_project_settings_ci_cd_path(project.namespace, project) } + subject { project_settings_ci_cd_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -111,7 +111,7 @@ describe "Private Project Access", feature: true do end describe "GET /:project_path/settings/repository" do - subject { namespace_project_settings_repository_path(project.namespace, project) } + subject { project_settings_repository_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -126,7 +126,7 @@ describe "Private Project Access", feature: true do describe "GET /:project_path/blob" do let(:commit) { project.repository.commit } - subject { namespace_project_blob_path(project.namespace, project, File.join(commit.id, '.gitignore'))} + subject { project_blob_path(project, File.join(commit.id, '.gitignore'))} it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -140,7 +140,7 @@ describe "Private Project Access", feature: true do end describe "GET /:project_path/edit" do - subject { edit_namespace_project_path(project.namespace, project) } + subject { edit_project_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -154,7 +154,7 @@ describe "Private Project Access", feature: true do end describe "GET /:project_path/deploy_keys" do - subject { namespace_project_deploy_keys_path(project.namespace, project) } + subject { project_deploy_keys_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -168,7 +168,7 @@ describe "Private Project Access", feature: true do end describe "GET /:project_path/issues" do - subject { namespace_project_issues_path(project.namespace, project) } + subject { project_issues_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -183,7 +183,7 @@ describe "Private Project Access", feature: true do describe "GET /:project_path/issues/:id/edit" do let(:issue) { create(:issue, project: project) } - subject { edit_namespace_project_issue_path(project.namespace, project, issue) } + subject { edit_project_issue_path(project, issue) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -197,7 +197,7 @@ describe "Private Project Access", feature: true do end describe "GET /:project_path/snippets" do - subject { namespace_project_snippets_path(project.namespace, project) } + subject { project_snippets_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -211,7 +211,7 @@ describe "Private Project Access", feature: true do end describe "GET /:project_path/merge_requests" do - subject { namespace_project_merge_requests_path(project.namespace, project) } + subject { project_merge_requests_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -225,7 +225,7 @@ describe "Private Project Access", feature: true do end describe "GET /:project_path/branches" do - subject { namespace_project_branches_path(project.namespace, project) } + subject { project_branches_path(project) } before do # Speed increase @@ -244,7 +244,7 @@ describe "Private Project Access", feature: true do end describe "GET /:project_path/tags" do - subject { namespace_project_tags_path(project.namespace, project) } + subject { project_tags_path(project) } before do # Speed increase @@ -263,7 +263,7 @@ describe "Private Project Access", feature: true do end describe "GET /:project_path/namespace/hooks" do - subject { namespace_project_settings_integrations_path(project.namespace, project) } + subject { project_settings_integrations_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -277,7 +277,7 @@ describe "Private Project Access", feature: true do end describe "GET /:project_path/pipelines" do - subject { namespace_project_pipelines_path(project.namespace, project) } + subject { project_pipelines_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -304,7 +304,7 @@ describe "Private Project Access", feature: true do describe "GET /:project_path/pipelines/:id" do let(:pipeline) { create(:ci_pipeline, project: project) } - subject { namespace_project_pipeline_path(project.namespace, project, pipeline) } + subject { project_pipeline_path(project, pipeline) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -330,7 +330,7 @@ describe "Private Project Access", feature: true do end describe "GET /:project_path/builds" do - subject { namespace_project_jobs_path(project.namespace, project) } + subject { project_jobs_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -358,7 +358,7 @@ describe "Private Project Access", feature: true do describe "GET /:project_path/builds/:id" do let(:pipeline) { create(:ci_pipeline, project: project) } let(:build) { create(:ci_build, pipeline: pipeline) } - subject { namespace_project_job_path(project.namespace, project, build.id) } + subject { project_job_path(project, build.id) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -391,7 +391,7 @@ describe "Private Project Access", feature: true do describe 'GET /:project_path/builds/:id/trace' do let(:pipeline) { create(:ci_pipeline, project: project) } let(:build) { create(:ci_build, pipeline: pipeline) } - subject { trace_namespace_project_job_path(project.namespace, project, build.id) } + subject { trace_project_job_path(project, build.id) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -421,7 +421,7 @@ describe "Private Project Access", feature: true do end describe "GET /:project_path/environments" do - subject { namespace_project_environments_path(project.namespace, project) } + subject { project_environments_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -436,7 +436,7 @@ describe "Private Project Access", feature: true do describe "GET /:project_path/environments/:id" do let(:environment) { create(:environment, project: project) } - subject { namespace_project_environment_path(project.namespace, project, environment) } + subject { project_environment_path(project, environment) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -451,7 +451,7 @@ describe "Private Project Access", feature: true do describe "GET /:project_path/environments/:id/deployments" do let(:environment) { create(:environment, project: project) } - subject { namespace_project_environment_deployments_path(project.namespace, project, environment) } + subject { project_environment_deployments_path(project, environment) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -465,7 +465,7 @@ describe "Private Project Access", feature: true do end describe "GET /:project_path/environments/new" do - subject { new_namespace_project_environment_path(project.namespace, project) } + subject { new_project_environment_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -479,7 +479,7 @@ describe "Private Project Access", feature: true do end describe "GET /:project_path/pipeline_schedules" do - subject { namespace_project_pipeline_schedules_path(project.namespace, project) } + subject { project_pipeline_schedules_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -493,7 +493,7 @@ describe "Private Project Access", feature: true do end describe "GET /:project_path/pipeline_schedules/new" do - subject { new_namespace_project_pipeline_schedule_path(project.namespace, project) } + subject { new_project_pipeline_schedule_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -507,7 +507,7 @@ describe "Private Project Access", feature: true do end describe "GET /:project_path/environments/new" do - subject { new_namespace_project_pipeline_schedule_path(project.namespace, project) } + subject { new_project_pipeline_schedule_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -529,7 +529,7 @@ describe "Private Project Access", feature: true do project.container_repositories << container_repository end - subject { namespace_project_container_registry_index_path(project.namespace, project) } + subject { project_container_registry_index_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } diff --git a/spec/features/security/project/public_access_spec.rb b/spec/features/security/project/public_access_spec.rb index 59655b0c31a..d45e1dbc09b 100644 --- a/spec/features/security/project/public_access_spec.rb +++ b/spec/features/security/project/public_access_spec.rb @@ -13,7 +13,7 @@ describe "Public Project Access", feature: true do end describe "GET /:project_path" do - subject { namespace_project_path(project.namespace, project) } + subject { project_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -27,7 +27,7 @@ describe "Public Project Access", feature: true do end describe "GET /:project_path/tree/master" do - subject { namespace_project_tree_path(project.namespace, project, project.repository.root_ref) } + subject { project_tree_path(project, project.repository.root_ref) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -41,7 +41,7 @@ describe "Public Project Access", feature: true do end describe "GET /:project_path/commits/master" do - subject { namespace_project_commits_path(project.namespace, project, project.repository.root_ref, limit: 1) } + subject { project_commits_path(project, project.repository.root_ref, limit: 1) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -55,7 +55,7 @@ describe "Public Project Access", feature: true do end describe "GET /:project_path/commit/:sha" do - subject { namespace_project_commit_path(project.namespace, project, project.repository.commit) } + subject { project_commit_path(project, project.repository.commit) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -69,7 +69,7 @@ describe "Public Project Access", feature: true do end describe "GET /:project_path/compare" do - subject { namespace_project_compare_index_path(project.namespace, project) } + subject { project_compare_index_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -83,7 +83,7 @@ describe "Public Project Access", feature: true do end describe "GET /:project_path/settings/members" do - subject { namespace_project_settings_members_path(project.namespace, project) } + subject { project_settings_members_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -97,7 +97,7 @@ describe "Public Project Access", feature: true do end describe "GET /:project_path/settings/ci_cd" do - subject { namespace_project_settings_ci_cd_path(project.namespace, project) } + subject { project_settings_ci_cd_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -111,7 +111,7 @@ describe "Public Project Access", feature: true do end describe "GET /:project_path/settings/repository" do - subject { namespace_project_settings_repository_path(project.namespace, project) } + subject { project_settings_repository_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -125,7 +125,7 @@ describe "Public Project Access", feature: true do end describe "GET /:project_path/pipelines" do - subject { namespace_project_pipelines_path(project.namespace, project) } + subject { project_pipelines_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -140,7 +140,7 @@ describe "Public Project Access", feature: true do describe "GET /:project_path/pipelines/:id" do let(:pipeline) { create(:ci_pipeline, project: project) } - subject { namespace_project_pipeline_path(project.namespace, project, pipeline) } + subject { project_pipeline_path(project, pipeline) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -154,7 +154,7 @@ describe "Public Project Access", feature: true do end describe "GET /:project_path/builds" do - subject { namespace_project_jobs_path(project.namespace, project) } + subject { project_jobs_path(project) } context "when allowed for public" do before do @@ -192,7 +192,7 @@ describe "Public Project Access", feature: true do describe "GET /:project_path/builds/:id" do let(:pipeline) { create(:ci_pipeline, project: project) } let(:build) { create(:ci_build, pipeline: pipeline) } - subject { namespace_project_job_path(project.namespace, project, build.id) } + subject { project_job_path(project, build.id) } context "when allowed for public" do before do @@ -230,7 +230,7 @@ describe "Public Project Access", feature: true do describe 'GET /:project_path/builds/:id/trace' do let(:pipeline) { create(:ci_pipeline, project: project) } let(:build) { create(:ci_build, pipeline: pipeline) } - subject { trace_namespace_project_job_path(project.namespace, project, build.id) } + subject { trace_project_job_path(project, build.id) } context 'when allowed for public' do before do @@ -266,7 +266,7 @@ describe "Public Project Access", feature: true do end describe "GET /:project_path/pipeline_schedules" do - subject { namespace_project_pipeline_schedules_path(project.namespace, project) } + subject { project_pipeline_schedules_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -280,7 +280,7 @@ describe "Public Project Access", feature: true do end describe "GET /:project_path/environments" do - subject { namespace_project_environments_path(project.namespace, project) } + subject { project_environments_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -295,7 +295,7 @@ describe "Public Project Access", feature: true do describe "GET /:project_path/environments/:id" do let(:environment) { create(:environment, project: project) } - subject { namespace_project_environment_path(project.namespace, project, environment) } + subject { project_environment_path(project, environment) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -310,7 +310,7 @@ describe "Public Project Access", feature: true do describe "GET /:project_path/environments/:id/deployments" do let(:environment) { create(:environment, project: project) } - subject { namespace_project_environment_deployments_path(project.namespace, project, environment) } + subject { project_environment_deployments_path(project, environment) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -324,7 +324,7 @@ describe "Public Project Access", feature: true do end describe "GET /:project_path/environments/new" do - subject { new_namespace_project_environment_path(project.namespace, project) } + subject { new_project_environment_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -340,7 +340,7 @@ describe "Public Project Access", feature: true do describe "GET /:project_path/blob" do let(:commit) { project.repository.commit } - subject { namespace_project_blob_path(project.namespace, project, File.join(commit.id, '.gitignore')) } + subject { project_blob_path(project, File.join(commit.id, '.gitignore')) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -353,7 +353,7 @@ describe "Public Project Access", feature: true do end describe "GET /:project_path/edit" do - subject { edit_namespace_project_path(project.namespace, project) } + subject { edit_project_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -367,7 +367,7 @@ describe "Public Project Access", feature: true do end describe "GET /:project_path/deploy_keys" do - subject { namespace_project_deploy_keys_path(project.namespace, project) } + subject { project_deploy_keys_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -381,7 +381,7 @@ describe "Public Project Access", feature: true do end describe "GET /:project_path/issues" do - subject { namespace_project_issues_path(project.namespace, project) } + subject { project_issues_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -396,7 +396,7 @@ describe "Public Project Access", feature: true do describe "GET /:project_path/issues/:id/edit" do let(:issue) { create(:issue, project: project) } - subject { edit_namespace_project_issue_path(project.namespace, project, issue) } + subject { edit_project_issue_path(project, issue) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -410,7 +410,7 @@ describe "Public Project Access", feature: true do end describe "GET /:project_path/snippets" do - subject { namespace_project_snippets_path(project.namespace, project) } + subject { project_snippets_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -424,7 +424,7 @@ describe "Public Project Access", feature: true do end describe "GET /:project_path/snippets/new" do - subject { new_namespace_project_snippet_path(project.namespace, project) } + subject { new_project_snippet_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -438,7 +438,7 @@ describe "Public Project Access", feature: true do end describe "GET /:project_path/merge_requests" do - subject { namespace_project_merge_requests_path(project.namespace, project) } + subject { project_merge_requests_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -452,7 +452,7 @@ describe "Public Project Access", feature: true do end describe "GET /:project_path/merge_requests/new" do - subject { namespace_project_new_merge_request_path(project.namespace, project) } + subject { project_new_merge_request_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -466,7 +466,7 @@ describe "Public Project Access", feature: true do end describe "GET /:project_path/branches" do - subject { namespace_project_branches_path(project.namespace, project) } + subject { project_branches_path(project) } before do # Speed increase @@ -485,7 +485,7 @@ describe "Public Project Access", feature: true do end describe "GET /:project_path/tags" do - subject { namespace_project_tags_path(project.namespace, project) } + subject { project_tags_path(project) } before do # Speed increase @@ -504,7 +504,7 @@ describe "Public Project Access", feature: true do end describe "GET /:project_path/settings/integrations" do - subject { namespace_project_settings_integrations_path(project.namespace, project) } + subject { project_settings_integrations_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -526,7 +526,7 @@ describe "Public Project Access", feature: true do project.container_repositories << container_repository end - subject { namespace_project_container_registry_index_path(project.namespace, project) } + subject { project_container_registry_index_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } diff --git a/spec/features/security/project/snippet/internal_access_spec.rb b/spec/features/security/project/snippet/internal_access_spec.rb index 2659b3ee3ec..2420caa88c4 100644 --- a/spec/features/security/project/snippet/internal_access_spec.rb +++ b/spec/features/security/project/snippet/internal_access_spec.rb @@ -9,7 +9,7 @@ describe "Internal Project Snippets Access", feature: true do let(:private_snippet) { create(:project_snippet, :private, project: project, author: project.owner) } describe "GET /:project_path/snippets" do - subject { namespace_project_snippets_path(project.namespace, project) } + subject { project_snippets_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -23,7 +23,7 @@ describe "Internal Project Snippets Access", feature: true do end describe "GET /:project_path/snippets/new" do - subject { new_namespace_project_snippet_path(project.namespace, project) } + subject { new_project_snippet_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -38,7 +38,7 @@ describe "Internal Project Snippets Access", feature: true do describe "GET /:project_path/snippets/:id" do context "for an internal snippet" do - subject { namespace_project_snippet_path(project.namespace, project, internal_snippet) } + subject { project_snippet_path(project, internal_snippet) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -52,7 +52,7 @@ describe "Internal Project Snippets Access", feature: true do end context "for a private snippet" do - subject { namespace_project_snippet_path(project.namespace, project, private_snippet) } + subject { project_snippet_path(project, private_snippet) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -68,7 +68,7 @@ describe "Internal Project Snippets Access", feature: true do describe "GET /:project_path/snippets/:id/raw" do context "for an internal snippet" do - subject { raw_namespace_project_snippet_path(project.namespace, project, internal_snippet) } + subject { raw_project_snippet_path(project, internal_snippet) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -82,7 +82,7 @@ describe "Internal Project Snippets Access", feature: true do end context "for a private snippet" do - subject { raw_namespace_project_snippet_path(project.namespace, project, private_snippet) } + subject { raw_project_snippet_path(project, private_snippet) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } diff --git a/spec/features/security/project/snippet/private_access_spec.rb b/spec/features/security/project/snippet/private_access_spec.rb index 6eb9f163bd5..0b8548a675b 100644 --- a/spec/features/security/project/snippet/private_access_spec.rb +++ b/spec/features/security/project/snippet/private_access_spec.rb @@ -8,7 +8,7 @@ describe "Private Project Snippets Access", feature: true do let(:private_snippet) { create(:project_snippet, :private, project: project, author: project.owner) } describe "GET /:project_path/snippets" do - subject { namespace_project_snippets_path(project.namespace, project) } + subject { project_snippets_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -22,7 +22,7 @@ describe "Private Project Snippets Access", feature: true do end describe "GET /:project_path/snippets/new" do - subject { new_namespace_project_snippet_path(project.namespace, project) } + subject { new_project_snippet_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -36,7 +36,7 @@ describe "Private Project Snippets Access", feature: true do end describe "GET /:project_path/snippets/:id for a private snippet" do - subject { namespace_project_snippet_path(project.namespace, project, private_snippet) } + subject { project_snippet_path(project, private_snippet) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -50,7 +50,7 @@ describe "Private Project Snippets Access", feature: true do end describe "GET /:project_path/snippets/:id/raw for a private snippet" do - subject { raw_namespace_project_snippet_path(project.namespace, project, private_snippet) } + subject { raw_project_snippet_path(project, private_snippet) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } diff --git a/spec/features/security/project/snippet/public_access_spec.rb b/spec/features/security/project/snippet/public_access_spec.rb index f3329d0bc96..153f8f964a6 100644 --- a/spec/features/security/project/snippet/public_access_spec.rb +++ b/spec/features/security/project/snippet/public_access_spec.rb @@ -10,7 +10,7 @@ describe "Public Project Snippets Access", feature: true do let(:private_snippet) { create(:project_snippet, :private, project: project, author: project.owner) } describe "GET /:project_path/snippets" do - subject { namespace_project_snippets_path(project.namespace, project) } + subject { project_snippets_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -24,7 +24,7 @@ describe "Public Project Snippets Access", feature: true do end describe "GET /:project_path/snippets/new" do - subject { new_namespace_project_snippet_path(project.namespace, project) } + subject { new_project_snippet_path(project) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -39,7 +39,7 @@ describe "Public Project Snippets Access", feature: true do describe "GET /:project_path/snippets/:id" do context "for a public snippet" do - subject { namespace_project_snippet_path(project.namespace, project, public_snippet) } + subject { project_snippet_path(project, public_snippet) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -53,7 +53,7 @@ describe "Public Project Snippets Access", feature: true do end context "for an internal snippet" do - subject { namespace_project_snippet_path(project.namespace, project, internal_snippet) } + subject { project_snippet_path(project, internal_snippet) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -67,7 +67,7 @@ describe "Public Project Snippets Access", feature: true do end context "for a private snippet" do - subject { namespace_project_snippet_path(project.namespace, project, private_snippet) } + subject { project_snippet_path(project, private_snippet) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -83,7 +83,7 @@ describe "Public Project Snippets Access", feature: true do describe "GET /:project_path/snippets/:id/raw" do context "for a public snippet" do - subject { raw_namespace_project_snippet_path(project.namespace, project, public_snippet) } + subject { raw_project_snippet_path(project, public_snippet) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -97,7 +97,7 @@ describe "Public Project Snippets Access", feature: true do end context "for an internal snippet" do - subject { raw_namespace_project_snippet_path(project.namespace, project, internal_snippet) } + subject { raw_project_snippet_path(project, internal_snippet) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } @@ -111,7 +111,7 @@ describe "Public Project Snippets Access", feature: true do end context "for a private snippet" do - subject { raw_namespace_project_snippet_path(project.namespace, project, private_snippet) } + subject { raw_project_snippet_path(project, private_snippet) } it { is_expected.to be_allowed_for(:admin) } it { is_expected.to be_allowed_for(:owner).of(project) } diff --git a/spec/features/snippets/create_snippet_spec.rb b/spec/features/snippets/user_creates_snippet_spec.rb index ac5c14ed427..57dec14b480 100644 --- a/spec/features/snippets/create_snippet_spec.rb +++ b/spec/features/snippets/user_creates_snippet_spec.rb @@ -1,10 +1,12 @@ require 'rails_helper' -feature 'Create Snippet', :js, feature: true do +feature 'User creates snippet', :js, feature: true do include DropzoneHelper + let(:user) { create(:user) } + before do - gitlab_sign_in :user + sign_in(user) visit new_snippet_path end diff --git a/spec/features/snippets/user_deletes_snippet_spec.rb b/spec/features/snippets/user_deletes_snippet_spec.rb new file mode 100644 index 00000000000..162c2c9e730 --- /dev/null +++ b/spec/features/snippets/user_deletes_snippet_spec.rb @@ -0,0 +1,19 @@ +require 'rails_helper' + +feature 'User deletes snippet', feature: true do + let(:user) { create(:user) } + let(:content) { 'puts "test"' } + let(:snippet) { create(:personal_snippet, :public, content: content, author: user) } + + before do + sign_in(user) + + visit snippet_path(snippet) + end + + it 'deletes the snippet' do + first(:link, 'Delete').click + + expect(page).not_to have_content(snippet.title) + end +end diff --git a/spec/features/snippets/edit_snippet_spec.rb b/spec/features/snippets/user_edits_snippet_spec.rb index 860e1b156d6..cff64423873 100644 --- a/spec/features/snippets/edit_snippet_spec.rb +++ b/spec/features/snippets/user_edits_snippet_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -feature 'Edit Snippet', :js, feature: true do +feature 'User edits snippet', :js, feature: true do include DropzoneHelper let(:file_name) { 'test.rb' } @@ -10,7 +10,7 @@ feature 'Edit Snippet', :js, feature: true do let(:snippet) { create(:personal_snippet, :public, file_name: file_name, content: content, author: user) } before do - gitlab_sign_in(user) + sign_in(user) visit edit_snippet_path(snippet) wait_for_requests @@ -27,7 +27,7 @@ feature 'Edit Snippet', :js, feature: true do it 'updates the snippet with files attached' do dropzone_file Rails.root.join('spec', 'fixtures', 'banana_sample.gif') - expect(page.find_field("personal_snippet_description").value).to have_content('banana_sample') + expect(page.find_field('personal_snippet_description').value).to have_content('banana_sample') click_button('Save changes') wait_for_requests @@ -35,4 +35,24 @@ feature 'Edit Snippet', :js, feature: true do link = find('a.no-attachment-icon img[alt="banana_sample"]')['src'] expect(link).to match(%r{/uploads/personal_snippet/#{snippet.id}/\h{32}/banana_sample\.gif\z}) end + + it 'updates the snippet to make it internal' do + choose 'Internal' + + click_button 'Save changes' + wait_for_requests + + expect(page).to have_no_xpath("//i[@class='fa fa-lock']") + expect(page).to have_xpath("//i[@class='fa fa-shield']") + end + + it 'updates the snippet to make it public' do + choose 'Public' + + click_button 'Save changes' + wait_for_requests + + expect(page).to have_no_xpath("//i[@class='fa fa-lock']") + expect(page).to have_xpath("//i[@class='fa fa-globe']") + end end diff --git a/spec/features/tags/master_creates_tag_spec.rb b/spec/features/tags/master_creates_tag_spec.rb index 52db3583dac..3bf5544a837 100644 --- a/spec/features/tags/master_creates_tag_spec.rb +++ b/spec/features/tags/master_creates_tag_spec.rb @@ -11,7 +11,7 @@ feature 'Master creates tag', feature: true do context 'from tag list' do before do - visit namespace_project_tags_path(project.namespace, project) + visit project_tags_path(project) end scenario 'with an invalid name displays an error' do @@ -36,7 +36,7 @@ feature 'Master creates tag', feature: true do create_tag_in_form(tag: 'v3.0', ref: 'master', message: "Awesome tag message\n\n- hello\n- world") expect(current_path).to eq( - namespace_project_tag_path(project.namespace, project, 'v3.0')) + project_tag_path(project, 'v3.0')) expect(page).to have_content 'v3.0' page.within 'pre.wrap' do expect(page).to have_content "Awesome tag message\n\n- hello\n- world" @@ -47,7 +47,7 @@ feature 'Master creates tag', feature: true do create_tag_in_form(tag: 'v4.0', ref: 'master', desc: "Awesome release notes\n\n- hello\n- world") expect(current_path).to eq( - namespace_project_tag_path(project.namespace, project, 'v4.0')) + project_tag_path(project, 'v4.0')) expect(page).to have_content 'v4.0' page.within '.description' do expect(page).to have_content 'Awesome release notes' @@ -72,7 +72,7 @@ feature 'Master creates tag', feature: true do context 'from new tag page' do before do - visit new_namespace_project_tag_path(project.namespace, project) + visit new_project_tag_path(project) end it 'description has autocomplete', :js do diff --git a/spec/features/tags/master_deletes_tag_spec.rb b/spec/features/tags/master_deletes_tag_spec.rb index 58f33e954f9..04f9cecd46d 100644 --- a/spec/features/tags/master_deletes_tag_spec.rb +++ b/spec/features/tags/master_deletes_tag_spec.rb @@ -7,7 +7,7 @@ feature 'Master deletes tag', feature: true do before do project.team << [user, :master] gitlab_sign_in(user) - visit namespace_project_tags_path(project.namespace, project) + visit project_tags_path(project) end context 'from the tags list page', js: true do @@ -24,12 +24,12 @@ feature 'Master deletes tag', feature: true do scenario 'deletes the tag' do click_on 'v1.0.0' expect(current_path).to eq( - namespace_project_tag_path(project.namespace, project, 'v1.0.0')) + project_tag_path(project, 'v1.0.0')) click_on 'Delete tag' expect(current_path).to eq( - namespace_project_tags_path(project.namespace, project)) + project_tags_path(project)) expect(page).not_to have_content 'v1.0.0' end end diff --git a/spec/features/tags/master_updates_tag_spec.rb b/spec/features/tags/master_updates_tag_spec.rb index 18c8c4c511c..092ffbb6d23 100644 --- a/spec/features/tags/master_updates_tag_spec.rb +++ b/spec/features/tags/master_updates_tag_spec.rb @@ -7,7 +7,7 @@ feature 'Master updates tag', feature: true do before do project.team << [user, :master] gitlab_sign_in(user) - visit namespace_project_tags_path(project.namespace, project) + visit project_tags_path(project) end context 'from the tags list page' do @@ -20,7 +20,7 @@ feature 'Master updates tag', feature: true do click_button 'Save changes' expect(current_path).to eq( - namespace_project_tag_path(project.namespace, project, 'v1.1.0')) + project_tag_path(project, 'v1.1.0')) expect(page).to have_content 'v1.1.0' expect(page).to have_content 'Awesome release notes' end @@ -45,7 +45,7 @@ feature 'Master updates tag', feature: true do click_button 'Save changes' expect(current_path).to eq( - namespace_project_tag_path(project.namespace, project, 'v1.1.0')) + project_tag_path(project, 'v1.1.0')) expect(page).to have_content 'v1.1.0' expect(page).to have_content 'Awesome release notes' end diff --git a/spec/features/tags/master_views_tags_spec.rb b/spec/features/tags/master_views_tags_spec.rb index 3c21fa06694..b1f3207eeea 100644 --- a/spec/features/tags/master_views_tags_spec.rb +++ b/spec/features/tags/master_views_tags_spec.rb @@ -11,13 +11,13 @@ feature 'Master views tags', feature: true do context 'when project has no tags' do let(:project) { create(:project_empty_repo) } before do - visit namespace_project_path(project.namespace, project) + visit project_path(project) click_on 'README' fill_in :commit_message, with: 'Add a README file', visible: true # Remove pre-receive hook so we can push without auth FileUtils.rm_f(File.join(project.repository.path, 'hooks', 'pre-receive')) click_button 'Commit changes' - visit namespace_project_tags_path(project.namespace, project) + visit project_tags_path(project) end scenario 'displays a specific message' do @@ -30,15 +30,15 @@ feature 'Master views tags', feature: true do let(:repository) { project.repository } before do - visit namespace_project_tags_path(project.namespace, project) + visit project_tags_path(project) end scenario 'avoids a N+1 query in branches index' do - control_count = ActiveRecord::QueryRecorder.new { visit namespace_project_tags_path(project.namespace, project) }.count + control_count = ActiveRecord::QueryRecorder.new { visit project_tags_path(project) }.count %w(one two three four five).each { |tag| repository.add_tag(user, tag, 'master', 'foo') } - expect { visit namespace_project_tags_path(project.namespace, project) }.not_to exceed_query_limit(control_count) + expect { visit project_tags_path(project) }.not_to exceed_query_limit(control_count) end scenario 'views the tags list page' do @@ -49,7 +49,7 @@ feature 'Master views tags', feature: true do click_on 'v1.0.0' expect(current_path).to eq( - namespace_project_tag_path(project.namespace, project, 'v1.0.0')) + project_tag_path(project, 'v1.0.0')) expect(page).to have_content 'v1.0.0' expect(page).to have_content 'This tag has no release notes.' end @@ -59,24 +59,24 @@ feature 'Master views tags', feature: true do click_on 'v1.0.0' expect(current_path).to eq( - namespace_project_tag_path(project.namespace, project, 'v1.0.0')) + project_tag_path(project, 'v1.0.0')) click_on 'Browse files' expect(current_path).to eq( - namespace_project_tree_path(project.namespace, project, 'v1.0.0')) + project_tree_path(project, 'v1.0.0')) end scenario 'has a button to browse commits' do click_on 'v1.0.0' expect(current_path).to eq( - namespace_project_tag_path(project.namespace, project, 'v1.0.0')) + project_tag_path(project, 'v1.0.0')) click_on 'Browse commits' expect(current_path).to eq( - namespace_project_commits_path(project.namespace, project, 'v1.0.0')) + project_commits_path(project, 'v1.0.0')) end end end diff --git a/spec/features/task_lists_spec.rb b/spec/features/task_lists_spec.rb index 51b1b8e2328..dfc362321aa 100644 --- a/spec/features/task_lists_spec.rb +++ b/spec/features/task_lists_spec.rb @@ -59,7 +59,7 @@ feature 'Task Lists', feature: true do end def visit_issue(project, issue) - visit namespace_project_issue_path(project.namespace, project, issue) + visit project_issue_path(project, issue) end describe 'for Issues', feature: true do @@ -98,7 +98,7 @@ feature 'Task Lists', feature: true do end it 'provides a summary on Issues#index' do - visit namespace_project_issues_path(project.namespace, project) + visit project_issues_path(project) expect(page).to have_content("2 of 6 tasks completed") end end @@ -116,7 +116,7 @@ feature 'Task Lists', feature: true do end it 'provides a summary on Issues#index' do - visit namespace_project_issues_path(project.namespace, project) + visit project_issues_path(project) expect(page).to have_content("0 of 1 task completed") end @@ -135,7 +135,7 @@ feature 'Task Lists', feature: true do end it 'provides a summary on Issues#index' do - visit namespace_project_issues_path(project.namespace, project) + visit project_issues_path(project) expect(page).to have_content("1 of 1 task completed") end @@ -242,7 +242,7 @@ feature 'Task Lists', feature: true do describe 'for Merge Requests' do def visit_merge_request(project, merge) - visit namespace_project_merge_request_path(project.namespace, project, merge) + visit project_merge_request_path(project, merge) end describe 'multiple tasks' do @@ -281,7 +281,7 @@ feature 'Task Lists', feature: true do end it 'provides a summary on MergeRequests#index' do - visit namespace_project_merge_requests_path(project.namespace, project) + visit project_merge_requests_path(project) expect(page).to have_content("2 of 6 tasks completed") end end @@ -298,7 +298,7 @@ feature 'Task Lists', feature: true do end it 'provides a summary on MergeRequests#index' do - visit namespace_project_merge_requests_path(project.namespace, project) + visit project_merge_requests_path(project) expect(page).to have_content("0 of 1 task completed") end end @@ -315,7 +315,7 @@ feature 'Task Lists', feature: true do end it 'provides a summary on MergeRequests#index' do - visit namespace_project_merge_requests_path(project.namespace, project) + visit project_merge_requests_path(project) expect(page).to have_content("1 of 1 task completed") end end diff --git a/spec/features/triggers_spec.rb b/spec/features/triggers_spec.rb index 5af2c0e9035..47d5f94f54e 100644 --- a/spec/features/triggers_spec.rb +++ b/spec/features/triggers_spec.rb @@ -14,7 +14,7 @@ feature 'Triggers', feature: true, js: true do @project.team << [user2, :master] @project.team << [guest_user, :guest] - visit namespace_project_settings_ci_cd_path(@project.namespace, @project) + visit project_settings_ci_cd_path(@project) end describe 'create trigger workflow' do @@ -42,7 +42,7 @@ feature 'Triggers', feature: true, js: true do scenario 'click on edit trigger opens edit trigger page' do create(:ci_trigger, owner: user, project: @project, description: trigger_title) - visit namespace_project_settings_ci_cd_path(@project.namespace, @project) + visit project_settings_ci_cd_path(@project) # See if edit page has correct descrption find('a[title="Edit"]').click @@ -51,7 +51,7 @@ feature 'Triggers', feature: true, js: true do scenario 'edit trigger and save' do create(:ci_trigger, owner: user, project: @project, description: trigger_title) - visit namespace_project_settings_ci_cd_path(@project.namespace, @project) + visit project_settings_ci_cd_path(@project) # See if edit page opens, then fill in new description and save find('a[title="Edit"]').click @@ -67,7 +67,7 @@ feature 'Triggers', feature: true, js: true do scenario 'edit "legacy" trigger and save' do # Create new trigger without owner association, i.e. Legacy trigger create(:ci_trigger, owner: nil, project: @project) - visit namespace_project_settings_ci_cd_path(@project.namespace, @project) + visit project_settings_ci_cd_path(@project) # See if the trigger can be edited and description is blank find('a[title="Edit"]').click @@ -84,7 +84,7 @@ feature 'Triggers', feature: true, js: true do describe 'trigger "Take ownership" workflow' do before(:each) do create(:ci_trigger, owner: user2, project: @project, description: trigger_title) - visit namespace_project_settings_ci_cd_path(@project.namespace, @project) + visit project_settings_ci_cd_path(@project) end scenario 'button "Take ownership" has correct alert' do @@ -106,7 +106,7 @@ feature 'Triggers', feature: true, js: true do describe 'trigger "Revoke" workflow' do before(:each) do create(:ci_trigger, owner: user2, project: @project, description: trigger_title) - visit namespace_project_settings_ci_cd_path(@project.namespace, @project) + visit project_settings_ci_cd_path(@project) end scenario 'button "Revoke" has correct alert' do @@ -131,7 +131,7 @@ feature 'Triggers', feature: true, js: true do scenario 'show "legacy" badge for legacy trigger' do create(:ci_trigger, owner: nil, project: @project) - visit namespace_project_settings_ci_cd_path(@project.namespace, @project) + visit project_settings_ci_cd_path(@project) # See if trigger without owner (i.e. legacy) shows "legacy" badge and is editable expect(page.find('.triggers-list')).to have_content 'legacy' @@ -140,7 +140,7 @@ feature 'Triggers', feature: true, js: true do scenario 'show "invalid" badge for trigger with owner having insufficient permissions' do create(:ci_trigger, owner: guest_user, project: @project, description: trigger_title) - visit namespace_project_settings_ci_cd_path(@project.namespace, @project) + visit project_settings_ci_cd_path(@project) # See if trigger without owner (i.e. legacy) shows "legacy" badge and is non-editable expect(page.find('.triggers-list')).to have_content 'invalid' @@ -150,7 +150,7 @@ feature 'Triggers', feature: true, js: true do scenario 'do not show "Edit" or full token for not owned trigger' do # Create trigger with user different from current_user create(:ci_trigger, owner: user2, project: @project, description: trigger_title) - visit namespace_project_settings_ci_cd_path(@project.namespace, @project) + visit project_settings_ci_cd_path(@project) # See if trigger not owned by current_user shows only first few token chars and doesn't have copy-to-clipboard button expect(page.find('.triggers-list')).to have_content(@project.triggers.first.token[0..3]) @@ -163,7 +163,7 @@ feature 'Triggers', feature: true, js: true do scenario 'show "Edit" and full token for owned trigger' do create(:ci_trigger, owner: user, project: @project, description: trigger_title) - visit namespace_project_settings_ci_cd_path(@project.namespace, @project) + visit project_settings_ci_cd_path(@project) # See if trigger shows full token and has copy-to-clipboard button expect(page.find('.triggers-list')).to have_content @project.triggers.first.token diff --git a/spec/features/uploads/user_uploads_file_to_note_spec.rb b/spec/features/uploads/user_uploads_file_to_note_spec.rb index 77a1012762d..736178897a6 100644 --- a/spec/features/uploads/user_uploads_file_to_note_spec.rb +++ b/spec/features/uploads/user_uploads_file_to_note_spec.rb @@ -9,7 +9,7 @@ feature 'User uploads file to note', feature: true do before do gitlab_sign_in(user) - visit namespace_project_issue_path(project.namespace, project, issue) + visit project_issue_path(project, issue) end context 'before uploading' do diff --git a/spec/features/user_can_display_performance_bar_spec.rb b/spec/features/user_can_display_performance_bar_spec.rb index 1bd7e038939..24fff1a3052 100644 --- a/spec/features/user_can_display_performance_bar_spec.rb +++ b/spec/features/user_can_display_performance_bar_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe 'User can display performacne bar', :js do +describe 'User can display performance bar', :js do shared_examples 'performance bar is disabled' do it 'does not show the performance bar by default' do expect(page).not_to have_css('#peek') @@ -27,8 +27,8 @@ describe 'User can display performacne bar', :js do find('body').native.send_keys('pb') end - it 'does not show the performance bar by default' do - expect(page).not_to have_css('#peek') + it 'shows the performance bar' do + expect(page).to have_css('#peek') end end end diff --git a/spec/features/variables_spec.rb b/spec/features/variables_spec.rb index 85085bf305a..1a2dedf27eb 100644 --- a/spec/features/variables_spec.rb +++ b/spec/features/variables_spec.rb @@ -10,7 +10,7 @@ describe 'Project variables', js: true do project.team << [user, :master] project.variables << variable - visit namespace_project_settings_ci_cd_path(project.namespace, project) + visit project_settings_ci_cd_path(project) end it 'shows list of variables' do diff --git a/spec/finders/labels_finder_spec.rb b/spec/finders/labels_finder_spec.rb index 1724cdba830..95d96354b77 100644 --- a/spec/finders/labels_finder_spec.rb +++ b/spec/finders/labels_finder_spec.rb @@ -49,12 +49,12 @@ describe LabelsFinder do end context 'filtering by group_id' do - it 'returns labels available for any project within the group' do + it 'returns labels available for any non-archived project within the group' do group_1.add_developer(user) - + project_1.archive! finder = described_class.new(user, group_id: group_1.id) - expect(finder.execute).to eq [group_label_2, project_label_1, group_label_1, project_label_5] + expect(finder.execute).to eq [group_label_2, group_label_1, project_label_5] end end diff --git a/spec/fixtures/config/kubeconfig-without-ca.yml b/spec/fixtures/config/kubeconfig-without-ca.yml new file mode 100644 index 00000000000..b2cb989d548 --- /dev/null +++ b/spec/fixtures/config/kubeconfig-without-ca.yml @@ -0,0 +1,18 @@ +--- +apiVersion: v1 +clusters: +- name: gitlab-deploy + cluster: + server: https://kube.domain.com +contexts: +- name: gitlab-deploy + context: + cluster: gitlab-deploy + namespace: NAMESPACE + user: gitlab-deploy +current-context: gitlab-deploy +kind: Config +users: +- name: gitlab-deploy + user: + token: TOKEN diff --git a/spec/fixtures/config/kubeconfig.yml b/spec/fixtures/config/kubeconfig.yml new file mode 100644 index 00000000000..c4e8e573c32 --- /dev/null +++ b/spec/fixtures/config/kubeconfig.yml @@ -0,0 +1,19 @@ +--- +apiVersion: v1 +clusters: +- name: gitlab-deploy + cluster: + server: https://kube.domain.com + certificate-authority-data: "UEVN\n" +contexts: +- name: gitlab-deploy + context: + cluster: gitlab-deploy + namespace: NAMESPACE + user: gitlab-deploy +current-context: gitlab-deploy +kind: Config +users: +- name: gitlab-deploy + user: + token: TOKEN diff --git a/spec/fixtures/markdown.md.erb b/spec/fixtures/markdown.md.erb index 51a3e91d201..58b43805705 100644 --- a/spec/fixtures/markdown.md.erb +++ b/spec/fixtures/markdown.md.erb @@ -166,9 +166,9 @@ References should be parseable even inside _<%= merge_request.to_reference %>_ e - Issue in another project: <%= xissue.to_reference(project) %> - Ignored in code: `<%= issue.to_reference %>` - Ignored in links: [Link to <%= issue.to_reference %>](#issue-link) -- Issue by URL: <%= urls.namespace_project_issue_url(issue.project.namespace, issue.project, issue) %> +- Issue by URL: <%= urls.project_issue_url(issue.project, issue) %> - Link to issue by reference: [Issue](<%= issue.to_reference %>) -- Link to issue by URL: [Issue](<%= urls.namespace_project_issue_url(issue.project.namespace, issue.project, issue) %>) +- Link to issue by URL: [Issue](<%= urls.project_issue_url(issue.project, issue) %>) #### MergeRequestReferenceFilter @@ -176,9 +176,9 @@ References should be parseable even inside _<%= merge_request.to_reference %>_ e - Merge request in another project: <%= xmerge_request.to_reference(project) %> - Ignored in code: `<%= merge_request.to_reference %>` - Ignored in links: [Link to <%= merge_request.to_reference %>](#merge-request-link) -- Merge request by URL: <%= urls.namespace_project_merge_request_url(merge_request.project.namespace, merge_request.project, merge_request) %> +- Merge request by URL: <%= urls.project_merge_request_url(merge_request.project, merge_request) %> - Link to merge request by reference: [Merge request](<%= merge_request.to_reference %>) -- Link to merge request by URL: [Merge request](<%= urls.namespace_project_merge_request_url(merge_request.project.namespace, merge_request.project, merge_request) %>) +- Link to merge request by URL: [Merge request](<%= urls.project_merge_request_url(merge_request.project, merge_request) %>) #### SnippetReferenceFilter @@ -186,9 +186,9 @@ References should be parseable even inside _<%= merge_request.to_reference %>_ e - Snippet in another project: <%= xsnippet.to_reference(project) %> - Ignored in code: `<%= snippet.to_reference %>` - Ignored in links: [Link to <%= snippet.to_reference %>](#snippet-link) -- Snippet by URL: <%= urls.namespace_project_snippet_url(snippet.project.namespace, snippet.project, snippet) %> +- Snippet by URL: <%= urls.project_snippet_url(snippet.project, snippet) %> - Link to snippet by reference: [Snippet](<%= snippet.to_reference %>) -- Link to snippet by URL: [Snippet](<%= urls.namespace_project_snippet_url(snippet.project.namespace, snippet.project, snippet) %>) +- Link to snippet by URL: [Snippet](<%= urls.project_snippet_url(snippet.project, snippet) %>) #### CommitRangeReferenceFilter @@ -196,9 +196,9 @@ References should be parseable even inside _<%= merge_request.to_reference %>_ e - Range in another project: <%= xcommit_range.to_reference(project) %> - Ignored in code: `<%= commit_range.to_reference %>` - Ignored in links: [Link to <%= commit_range.to_reference %>](#commit-range-link) -- Range by URL: <%= urls.namespace_project_compare_url(commit_range.project.namespace, commit_range.project, commit_range.to_param) %> +- Range by URL: <%= urls.project_compare_url(commit_range.project, commit_range.to_param) %> - Link to range by reference: [Range](<%= commit_range.to_reference %>) -- Link to range by URL: [Range](<%= urls.namespace_project_compare_url(commit_range.project.namespace, commit_range.project, commit_range.to_param) %>) +- Link to range by URL: [Range](<%= urls.project_compare_url(commit_range.project, commit_range.to_param) %>) #### CommitReferenceFilter @@ -206,9 +206,9 @@ References should be parseable even inside _<%= merge_request.to_reference %>_ e - Commit in another project: <%= xcommit.to_reference(project) %> - Ignored in code: `<%= commit.to_reference %>` - Ignored in links: [Link to <%= commit.to_reference %>](#commit-link) -- Commit by URL: <%= urls.namespace_project_commit_url(commit.project.namespace, commit.project, commit) %> +- Commit by URL: <%= urls.project_commit_url(commit.project, commit) %> - Link to commit by reference: [Commit](<%= commit.to_reference %>) -- Link to commit by URL: [Commit](<%= urls.namespace_project_commit_url(commit.project.namespace, commit.project, commit) %>) +- Link to commit by URL: [Commit](<%= urls.project_commit_url(commit.project, commit) %>) #### LabelReferenceFilter @@ -227,7 +227,7 @@ References should be parseable even inside _<%= merge_request.to_reference %>_ e - Milestone in another project: <%= xmilestone.to_reference(project) %> - Ignored in code: `<%= simple_milestone.to_reference %>` - Ignored in links: [Link to <%= simple_milestone.to_reference %>](#milestone-link) -- Milestone by URL: <%= urls.namespace_project_milestone_url(milestone.project.namespace, milestone.project, milestone) %> +- Milestone by URL: <%= urls.project_milestone_url(milestone.project, milestone) %> - Link to milestone by URL: [Milestone](<%= milestone.to_reference %>) ### Task Lists diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb index 56daeffde27..e0cad1da86a 100644 --- a/spec/helpers/application_helper_spec.rb +++ b/spec/helpers/application_helper_spec.rb @@ -76,7 +76,7 @@ describe ApplicationHelper do allow_any_instance_of(Project).to receive(:avatar_in_git).and_return(true) - avatar_url = "#{gitlab_host}#{namespace_project_avatar_path(project.namespace, project)}" + avatar_url = "#{gitlab_host}#{project_avatar_path(project)}" expect(helper.project_icon(project.full_path).to_s).to match(image_tag(avatar_url)) end end @@ -292,7 +292,7 @@ describe ApplicationHelper do let(:alternate_url) { 'http://company.example.com/getting-help' } before do - allow(current_application_settings).to receive(:help_page_support_url) { alternate_url } + stub_application_setting(help_page_support_url: alternate_url) end it 'returns the alternate support url' do diff --git a/spec/helpers/gitlab_routing_helper_spec.rb b/spec/helpers/gitlab_routing_helper_spec.rb index 14847d0a49e..7a522487a74 100644 --- a/spec/helpers/gitlab_routing_helper_spec.rb +++ b/spec/helpers/gitlab_routing_helper_spec.rb @@ -5,37 +5,37 @@ describe GitlabRoutingHelper do describe '#project_members_url' do let(:project) { build_stubbed(:empty_project) } - it { expect(project_members_url(project)).to eq namespace_project_project_members_url(project.namespace, project) } + it { expect(project_members_url(project)).to eq project_project_members_url(project) } end describe '#project_member_path' do let(:project_member) { create(:project_member) } - it { expect(project_member_path(project_member)).to eq namespace_project_project_member_path(project_member.source.namespace, project_member.source, project_member) } + it { expect(project_member_path(project_member)).to eq project_project_member_path(project_member.source, project_member) } end describe '#request_access_project_members_path' do let(:project) { build_stubbed(:empty_project) } - it { expect(request_access_project_members_path(project)).to eq request_access_namespace_project_project_members_path(project.namespace, project) } + it { expect(request_access_project_members_path(project)).to eq request_access_project_project_members_path(project) } end describe '#leave_project_members_path' do let(:project) { build_stubbed(:empty_project) } - it { expect(leave_project_members_path(project)).to eq leave_namespace_project_project_members_path(project.namespace, project) } + it { expect(leave_project_members_path(project)).to eq leave_project_project_members_path(project) } end describe '#approve_access_request_project_member_path' do let(:project_member) { create(:project_member) } - it { expect(approve_access_request_project_member_path(project_member)).to eq approve_access_request_namespace_project_project_member_path(project_member.source.namespace, project_member.source, project_member) } + it { expect(approve_access_request_project_member_path(project_member)).to eq approve_access_request_project_project_member_path(project_member.source, project_member) } end describe '#resend_invite_project_member_path' do let(:project_member) { create(:project_member) } - it { expect(resend_invite_project_member_path(project_member)).to eq resend_invite_namespace_project_project_member_path(project_member.source.namespace, project_member.source, project_member) } + it { expect(resend_invite_project_member_path(project_member)).to eq resend_invite_project_project_member_path(project_member.source, project_member) } end end diff --git a/spec/helpers/issues_helper_spec.rb b/spec/helpers/issues_helper_spec.rb index 00db98fd9d2..8f7f17a484f 100644 --- a/spec/helpers/issues_helper_spec.rb +++ b/spec/helpers/issues_helper_spec.rb @@ -137,7 +137,7 @@ describe IssuesHelper do let(:merge_request) { create(:merge_request) } it "links just the merge request" do - expected_path = namespace_project_merge_request_path(merge_request.project.namespace, merge_request.project, merge_request) + expected_path = project_merge_request_path(merge_request.project, merge_request) expect(link_to_discussions_to_resolve(merge_request, nil)).to include(expected_path) end diff --git a/spec/helpers/markup_helper_spec.rb b/spec/helpers/markup_helper_spec.rb index b4226f96a04..4b6a351cf70 100644 --- a/spec/helpers/markup_helper_spec.rb +++ b/spec/helpers/markup_helper_spec.rb @@ -25,17 +25,17 @@ describe MarkupHelper do let(:actual) { "#{merge_request.to_reference} -> #{commit.to_reference} -> #{issue.to_reference}" } it "links to the merge request" do - expected = namespace_project_merge_request_path(project.namespace, project, merge_request) + expected = project_merge_request_path(project, merge_request) expect(helper.markdown(actual)).to match(expected) end it "links to the commit" do - expected = namespace_project_commit_path(project.namespace, project, commit) + expected = project_commit_path(project, commit) expect(helper.markdown(actual)).to match(expected) end it "links to the issue" do - expected = namespace_project_issue_path(project.namespace, project, issue) + expected = project_issue_path(project, issue) expect(helper.markdown(actual)).to match(expected) end end @@ -46,7 +46,7 @@ describe MarkupHelper do let(:second_issue) { create(:issue, project: second_project) } it 'links to the issue' do - expected = namespace_project_issue_path(second_project.namespace, second_project, second_issue) + expected = project_issue_path(second_project, second_issue) expect(markdown(actual, project: second_project)).to match(expected) end end @@ -69,7 +69,7 @@ describe MarkupHelper do # First issue link expect(doc.css('a')[1].attr('href')) - .to eq namespace_project_issue_path(project.namespace, project, issues[0]) + .to eq project_issue_path(project, issues[0]) expect(doc.css('a')[1].text).to eq issues[0].to_reference # Internal commit link @@ -78,7 +78,7 @@ describe MarkupHelper do # Second issue link expect(doc.css('a')[3].attr('href')) - .to eq namespace_project_issue_path(project.namespace, project, issues[1]) + .to eq project_issue_path(project, issues[1]) expect(doc.css('a')[3].text).to eq issues[1].to_reference # Trailing commit link diff --git a/spec/helpers/milestones_helper_spec.rb b/spec/helpers/milestones_helper_spec.rb index 3cb809d42b5..b8f9c02a486 100644 --- a/spec/helpers/milestones_helper_spec.rb +++ b/spec/helpers/milestones_helper_spec.rb @@ -1,6 +1,42 @@ require 'spec_helper' describe MilestonesHelper do + describe '#milestones_filter_dropdown_path' do + let(:project) { create(:empty_project) } + let(:project2) { create(:empty_project) } + let(:group) { create(:group) } + + context 'when @project present' do + it 'returns project milestones JSON URL' do + assign(:project, project) + + expect(helper.milestones_filter_dropdown_path).to eq(project_milestones_path(project, :json)) + end + end + + context 'when @target_project present' do + it 'returns targeted project milestones JSON URL' do + assign(:target_project, project2) + + expect(helper.milestones_filter_dropdown_path).to eq(project_milestones_path(project2, :json)) + end + end + + context 'when @group present' do + it 'returns group milestones JSON URL' do + assign(:group, group) + + expect(helper.milestones_filter_dropdown_path).to eq(group_milestones_path(group, :json)) + end + end + + context 'when neither of @project/@target_project/@group present' do + it 'returns dashboard milestones JSON URL' do + expect(helper.milestones_filter_dropdown_path).to eq(dashboard_milestones_path(:json)) + end + end + end + describe "#milestone_date_range" do def result_for(*args) milestone_date_range(build(:milestone, *args)) diff --git a/spec/helpers/notes_helper_spec.rb b/spec/helpers/notes_helper_spec.rb index cc861af8533..56f252ba273 100644 --- a/spec/helpers/notes_helper_spec.rb +++ b/spec/helpers/notes_helper_spec.rb @@ -53,7 +53,7 @@ describe NotesHelper do let(:discussion) { create(:diff_note_on_merge_request, noteable: merge_request, project: project).to_discussion } it 'returns the diff path with the line code' do - expect(helper.discussion_path(discussion)).to eq(diffs_namespace_project_merge_request_path(project.namespace, project, merge_request, anchor: discussion.line_code)) + expect(helper.discussion_path(discussion)).to eq(diffs_project_merge_request_path(project, merge_request, anchor: discussion.line_code)) end end @@ -77,7 +77,7 @@ describe NotesHelper do end it 'returns the diff version path with the line code' do - expect(helper.discussion_path(discussion)).to eq(diffs_namespace_project_merge_request_path(project.namespace, project, merge_request, diff_id: merge_request_diff1, anchor: discussion.line_code)) + expect(helper.discussion_path(discussion)).to eq(diffs_project_merge_request_path(project, merge_request, diff_id: merge_request_diff1, anchor: discussion.line_code)) end end @@ -101,7 +101,7 @@ describe NotesHelper do end it 'returns the diff version comparison path with the line code' do - expect(helper.discussion_path(discussion)).to eq(diffs_namespace_project_merge_request_path(project.namespace, project, merge_request, diff_id: merge_request_diff3, start_sha: merge_request_diff1.head_commit_sha, anchor: discussion.line_code)) + expect(helper.discussion_path(discussion)).to eq(diffs_project_merge_request_path(project, merge_request, diff_id: merge_request_diff3, start_sha: merge_request_diff1.head_commit_sha, anchor: discussion.line_code)) end end @@ -129,7 +129,7 @@ describe NotesHelper do end it 'returns the diff path with the line code' do - expect(helper.discussion_path(discussion)).to eq(diffs_namespace_project_merge_request_path(project.namespace, project, merge_request, anchor: discussion.line_code)) + expect(helper.discussion_path(discussion)).to eq(diffs_project_merge_request_path(project, merge_request, anchor: discussion.line_code)) end end @@ -160,7 +160,7 @@ describe NotesHelper do let(:discussion) { create(:diff_note_on_commit, project: project).to_discussion } it 'returns the commit path with the line code' do - expect(helper.discussion_path(discussion)).to eq(namespace_project_commit_path(project.namespace, project, commit, anchor: discussion.line_code)) + expect(helper.discussion_path(discussion)).to eq(project_commit_path(project, commit, anchor: discussion.line_code)) end end @@ -168,7 +168,7 @@ describe NotesHelper do let(:discussion) { create(:legacy_diff_note_on_commit, project: project).to_discussion } it 'returns the commit path with the line code' do - expect(helper.discussion_path(discussion)).to eq(namespace_project_commit_path(project.namespace, project, commit, anchor: discussion.line_code)) + expect(helper.discussion_path(discussion)).to eq(project_commit_path(project, commit, anchor: discussion.line_code)) end end @@ -176,7 +176,7 @@ describe NotesHelper do let(:discussion) { create(:discussion_note_on_commit, project: project).to_discussion } it 'returns the commit path' do - expect(helper.discussion_path(discussion)).to eq(namespace_project_commit_path(project.namespace, project, commit)) + expect(helper.discussion_path(discussion)).to eq(project_commit_path(project, commit)) end end end diff --git a/spec/initializers/8_metrics_spec.rb b/spec/initializers/8_metrics_spec.rb index a507d7f7f2b..d4189f902fd 100644 --- a/spec/initializers/8_metrics_spec.rb +++ b/spec/initializers/8_metrics_spec.rb @@ -1,17 +1,25 @@ require 'spec_helper' -require_relative '../../config/initializers/8_metrics' describe 'instrument_classes', lib: true do let(:config) { double(:config) } + let(:unicorn_sampler) { double(:unicorn_sampler) } + let(:influx_sampler) { double(:influx_sampler) } + before do allow(config).to receive(:instrument_method) allow(config).to receive(:instrument_methods) allow(config).to receive(:instrument_instance_method) allow(config).to receive(:instrument_instance_methods) + allow(Gitlab::Metrics::UnicornSampler).to receive(:initialize_instance).and_return(unicorn_sampler) + allow(Gitlab::Metrics::InfluxSampler).to receive(:initialize_instance).and_return(influx_sampler) + allow(unicorn_sampler).to receive(:start) + allow(influx_sampler).to receive(:start) + allow(Gitlab::Application).to receive(:configure) end it 'can autoload and instrument all files' do + require_relative '../../config/initializers/8_metrics' expect { instrument_classes(config) }.not_to raise_error end end diff --git a/spec/javascripts/environments/environments_store_spec.js b/spec/javascripts/environments/environments_store_spec.js index 6e855530b21..f2c6ec24dd7 100644 --- a/spec/javascripts/environments/environments_store_spec.js +++ b/spec/javascripts/environments/environments_store_spec.js @@ -86,6 +86,16 @@ describe('Store', () => { store.toggleFolder(store.state.environments[1]); expect(store.state.environments[1].isOpen).toEqual(false); }); + + it('should keep folder open when environments are updated', () => { + store.storeEnvironments(serverData); + + store.toggleFolder(store.state.environments[1]); + expect(store.state.environments[1].isOpen).toEqual(true); + + store.storeEnvironments(serverData); + expect(store.state.environments[1].isOpen).toEqual(true); + }); }); describe('setfolderContent', () => { @@ -97,6 +107,17 @@ describe('Store', () => { expect(store.state.environments[1].children.length).toEqual(serverData.length); expect(store.state.environments[1].children[0].isChildren).toEqual(true); }); + + it('should keep folder content when environments are updated', () => { + store.storeEnvironments(serverData); + + store.setfolderContent(store.state.environments[1], serverData); + + expect(store.state.environments[1].children.length).toEqual(serverData.length); + // poll + store.storeEnvironments(serverData); + expect(store.state.environments[1].children.length).toEqual(serverData.length); + }); }); describe('store pagination', () => { diff --git a/spec/javascripts/fixtures/oauth_remember_me.html.haml b/spec/javascripts/fixtures/oauth_remember_me.html.haml new file mode 100644 index 00000000000..7886e995e57 --- /dev/null +++ b/spec/javascripts/fixtures/oauth_remember_me.html.haml @@ -0,0 +1,5 @@ +#oauth-container + %input#remember_me{ type: "checkbox" } + + %a.oauth-login.twitter{ href: "http://example.com/" } + %a.oauth-login.github{ href: "http://example.com/" } diff --git a/spec/javascripts/monitoring/mock_data.js b/spec/javascripts/monitoring/mock_data.js index 6f4cb989847..56d938e1fbe 100644 --- a/spec/javascripts/monitoring/mock_data.js +++ b/spec/javascripts/monitoring/mock_data.js @@ -13,7 +13,7 @@ const metricsGroupsAPIResponse = { 'queries': [ { 'query_range': 'avg(container_memory_usage_bytes{%{environment_filter}}) / 2^20', - 'label': 'Container memory', + 'y_label': 'Memory', 'unit': 'MiB', 'result': [ { @@ -2477,7 +2477,7 @@ export const singleRowMetrics = [ { 'title': 'CPU usage', 'weight': 1, - 'y_label': 'Values', + 'y_label': 'Memory', 'queries': [ { 'query_range': 'avg(rate(container_cpu_usage_seconds_total{%{environment_filter}}[2m])) * 100', diff --git a/spec/javascripts/monitoring/monitoring_column_spec.js b/spec/javascripts/monitoring/monitoring_column_spec.js index c8787f9708c..b3bc97adc9f 100644 --- a/spec/javascripts/monitoring/monitoring_column_spec.js +++ b/spec/javascripts/monitoring/monitoring_column_spec.js @@ -94,4 +94,15 @@ describe('MonitoringColumn', () => { done(); }); }); + + it('has a title for the y-axis that comes from the backend', () => { + const component = createComponent({ + columnData: singleRowMetrics[0], + classType: 'col-md-6', + updateAspectRatio: false, + deploymentData, + }); + + expect(component.yAxisLabel).toEqual(component.columnData.y_label); + }); }); diff --git a/spec/javascripts/oauth_remember_me_spec.js b/spec/javascripts/oauth_remember_me_spec.js new file mode 100644 index 00000000000..f90e0093d25 --- /dev/null +++ b/spec/javascripts/oauth_remember_me_spec.js @@ -0,0 +1,26 @@ +import OAuthRememberMe from '~/oauth_remember_me'; + +describe('OAuthRememberMe', () => { + preloadFixtures('static/oauth_remember_me.html.raw'); + + beforeEach(() => { + loadFixtures('static/oauth_remember_me.html.raw'); + + new OAuthRememberMe({ container: $('#oauth-container') }).bindEvents(); + }); + + it('adds the "remember_me" query parameter to all OAuth login buttons', () => { + $('#oauth-container #remember_me').click(); + + expect($('#oauth-container .oauth-login.twitter').attr('href')).toBe('http://example.com/?remember_me=1'); + expect($('#oauth-container .oauth-login.github').attr('href')).toBe('http://example.com/?remember_me=1'); + }); + + it('removes the "remember_me" query parameter from all OAuth login buttons', () => { + $('#oauth-container #remember_me').click(); + $('#oauth-container #remember_me').click(); + + expect($('#oauth-container .oauth-login.twitter').attr('href')).toBe('http://example.com/'); + expect($('#oauth-container .oauth-login.github').attr('href')).toBe('http://example.com/'); + }); +}); diff --git a/spec/javascripts/vue_mr_widget/components/mr_widget_pipeline_spec.js b/spec/javascripts/vue_mr_widget/components/mr_widget_pipeline_spec.js index 4b6f171c8d6..647b59520f8 100644 --- a/spec/javascripts/vue_mr_widget/components/mr_widget_pipeline_spec.js +++ b/spec/javascripts/vue_mr_widget/components/mr_widget_pipeline_spec.js @@ -76,28 +76,6 @@ describe('MRWidgetPipeline', () => { el = vm.$el; }); - afterEach(() => { - vm.$destroy(); - }); - - describe('without a pipeline', () => { - beforeEach(() => { - vm.mr = { pipeline: null }; - }); - - it('should render message with spinner', (done) => { - Vue.nextTick() - .then(() => { - expect(el.querySelector('.pipeline-id')).toBe(null); - expect(el.innerText.trim()).toBe('Waiting for pipeline...'); - expect(el.querySelectorAll('i.fa.fa-spinner.fa-spin').length).toBe(1); - done(); - }) - .then(done) - .catch(done.fail); - }); - }); - it('should render template elements correctly', () => { expect(el.classList.contains('mr-widget-heading')).toBeTruthy(); expect(el.querySelectorAll('.ci-status-icon.ci-status-icon-success').length).toEqual(1); @@ -115,47 +93,39 @@ describe('MRWidgetPipeline', () => { it('should list single stage', (done) => { pipeline.details.stages.splice(0, 1); - Vue.nextTick() - .then(() => { - expect(el.querySelectorAll('.stage-container button').length).toEqual(1); - expect(el.innerText).toContain('with stage'); - }) - .then(done) - .catch(done.fail); + Vue.nextTick(() => { + expect(el.querySelectorAll('.stage-container button').length).toEqual(1); + expect(el.innerText).toContain('with stage'); + done(); + }); }); it('should not have stages when there is no stage', (done) => { vm.mr.pipeline.details.stages = []; - Vue.nextTick() - .then(() => { - expect(el.querySelectorAll('.stage-container button').length).toEqual(0); - }) - .then(done) - .catch(done.fail); + Vue.nextTick(() => { + expect(el.querySelectorAll('.stage-container button').length).toEqual(0); + done(); + }); }); it('should not have coverage text when pipeline has no coverage info', (done) => { vm.mr.pipeline.coverage = null; - Vue.nextTick() - .then(() => { - expect(el.querySelector('.js-mr-coverage')).toEqual(null); - }) - .then(done) - .catch(done.fail); + Vue.nextTick(() => { + expect(el.querySelector('.js-mr-coverage')).toEqual(null); + done(); + }); }); it('should show CI error when there is a CI error', (done) => { vm.mr.ciStatus = null; - Vue.nextTick() - .then(() => { - expect(el.querySelectorAll('.js-ci-error').length).toEqual(1); - expect(el.innerText).toContain('Could not connect to the CI server'); - }) - .then(done) - .catch(done.fail); + Vue.nextTick(() => { + expect(el.querySelectorAll('.js-ci-error').length).toEqual(1); + expect(el.innerText).toContain('Could not connect to the CI server'); + done(); + }); }); }); }); diff --git a/spec/lib/banzai/filter/commit_range_reference_filter_spec.rb b/spec/lib/banzai/filter/commit_range_reference_filter_spec.rb index fc67c7ec3c4..60c27bc0d3c 100644 --- a/spec/lib/banzai/filter/commit_range_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/commit_range_reference_filter_spec.rb @@ -29,14 +29,14 @@ describe Banzai::Filter::CommitRangeReferenceFilter, lib: true do doc = reference_filter("See #{reference2}") expect(doc.css('a').first.attr('href')) - .to eq urls.namespace_project_compare_url(project.namespace, project, range2.to_param) + .to eq urls.project_compare_url(project, range2.to_param) end it 'links to a valid three-dot reference' do doc = reference_filter("See #{reference}") expect(doc.css('a').first.attr('href')) - .to eq urls.namespace_project_compare_url(project.namespace, project, range.to_param) + .to eq urls.project_compare_url(project, range.to_param) end it 'links to a valid short ID' do @@ -94,7 +94,7 @@ describe Banzai::Filter::CommitRangeReferenceFilter, lib: true do link = doc.css('a').first.attr('href') expect(link).not_to match %r(https?://) - expect(link).to eq urls.namespace_project_compare_url(project.namespace, project, from: commit1.id, to: commit2.id, only_path: true) + expect(link).to eq urls.project_compare_url(project, from: commit1.id, to: commit2.id, only_path: true) end end @@ -106,7 +106,7 @@ describe Banzai::Filter::CommitRangeReferenceFilter, lib: true do doc = reference_filter("See #{reference}") expect(doc.css('a').first.attr('href')) - .to eq urls.namespace_project_compare_url(project2.namespace, project2, range.to_param) + .to eq urls.project_compare_url(project2, range.to_param) end it 'link has valid text' do @@ -141,7 +141,7 @@ describe Banzai::Filter::CommitRangeReferenceFilter, lib: true do doc = reference_filter("See #{reference}") expect(doc.css('a').first.attr('href')) - .to eq urls.namespace_project_compare_url(project2.namespace, project2, range.to_param) + .to eq urls.project_compare_url(project2, range.to_param) end it 'link has valid text' do @@ -176,7 +176,7 @@ describe Banzai::Filter::CommitRangeReferenceFilter, lib: true do doc = reference_filter("See #{reference}") expect(doc.css('a').first.attr('href')) - .to eq urls.namespace_project_compare_url(project2.namespace, project2, range.to_param) + .to eq urls.project_compare_url(project2, range.to_param) end it 'link has valid text' do @@ -205,7 +205,7 @@ describe Banzai::Filter::CommitRangeReferenceFilter, lib: true do let(:namespace) { create(:namespace) } let(:project2) { create(:project, :public, :repository, namespace: namespace) } let(:range) { CommitRange.new("#{commit1.id}...master", project) } - let(:reference) { urls.namespace_project_compare_url(project2.namespace, project2, from: commit1.id, to: 'master') } + let(:reference) { urls.project_compare_url(project2, from: commit1.id, to: 'master') } before do range.project = project2 diff --git a/spec/lib/banzai/filter/commit_reference_filter_spec.rb b/spec/lib/banzai/filter/commit_reference_filter_spec.rb index c4d8d3b6682..f6893641481 100644 --- a/spec/lib/banzai/filter/commit_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/commit_reference_filter_spec.rb @@ -27,7 +27,7 @@ describe Banzai::Filter::CommitReferenceFilter, lib: true do expect(doc.css('a').first.text).to eq commit.short_id expect(doc.css('a').first.attr('href')) - .to eq urls.namespace_project_commit_url(project.namespace, project, reference) + .to eq urls.project_commit_url(project, reference) end end @@ -90,7 +90,7 @@ describe Banzai::Filter::CommitReferenceFilter, lib: true do link = doc.css('a').first.attr('href') expect(link).not_to match %r(https?://) - expect(link).to eq urls.namespace_project_commit_url(project.namespace, project, reference, only_path: true) + expect(link).to eq urls.project_commit_url(project, reference, only_path: true) end end @@ -175,13 +175,13 @@ describe Banzai::Filter::CommitReferenceFilter, lib: true do let(:namespace) { create(:namespace) } let(:project2) { create(:project, :public, :repository, namespace: namespace) } let(:commit) { project2.commit } - let(:reference) { urls.namespace_project_commit_url(project2.namespace, project2, commit.id) } + let(:reference) { urls.project_commit_url(project2, commit.id) } it 'links to a valid reference' do doc = reference_filter("See #{reference}") expect(doc.css('a').first.attr('href')) - .to eq urls.namespace_project_commit_url(project2.namespace, project2, commit.id) + .to eq urls.project_commit_url(project2, commit.id) end it 'links with adjacent text' do diff --git a/spec/lib/banzai/filter/label_reference_filter_spec.rb b/spec/lib/banzai/filter/label_reference_filter_spec.rb index cb3cf982351..8daef3ca691 100644 --- a/spec/lib/banzai/filter/label_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/label_reference_filter_spec.rb @@ -45,7 +45,7 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do link = doc.css('a').first.attr('href') expect(link).not_to match %r(https?://) - expect(link).to eq urls.namespace_project_issues_path(project.namespace, project, label_name: label.name) + expect(link).to eq urls.project_issues_path(project, label_name: label.name) end context 'project that does not exist referenced' do @@ -73,7 +73,7 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do doc = reference_filter("See #{reference}") expect(doc.css('a').first.attr('href')).to eq urls - .namespace_project_issues_url(project.namespace, project, label_name: label.name) + .project_issues_url(project, label_name: label.name) end it 'links with adjacent text' do @@ -96,7 +96,7 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do doc = reference_filter("See #{reference}") expect(doc.css('a').first.attr('href')).to eq urls - .namespace_project_issues_url(project.namespace, project, label_name: label.name) + .project_issues_url(project, label_name: label.name) expect(doc.text).to eq 'See gfm' end @@ -120,7 +120,7 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do doc = reference_filter("See #{reference}") expect(doc.css('a').first.attr('href')).to eq urls - .namespace_project_issues_url(project.namespace, project, label_name: label.name) + .project_issues_url(project, label_name: label.name) expect(doc.text).to eq 'See 2fa' end @@ -144,7 +144,7 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do doc = reference_filter("See #{reference}") expect(doc.css('a').first.attr('href')).to eq urls - .namespace_project_issues_url(project.namespace, project, label_name: label.name) + .project_issues_url(project, label_name: label.name) expect(doc.text).to eq 'See ?g.fm&' end @@ -169,7 +169,7 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do doc = reference_filter("See #{reference}") expect(doc.css('a').first.attr('href')).to eq urls - .namespace_project_issues_url(project.namespace, project, label_name: label.name) + .project_issues_url(project, label_name: label.name) expect(doc.text).to eq 'See gfm references' end @@ -193,7 +193,7 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do doc = reference_filter("See #{reference}") expect(doc.css('a').first.attr('href')).to eq urls - .namespace_project_issues_url(project.namespace, project, label_name: label.name) + .project_issues_url(project, label_name: label.name) expect(doc.text).to eq 'See 2 factor authentication' end @@ -217,7 +217,7 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do doc = reference_filter("See #{reference}") expect(doc.css('a').first.attr('href')).to eq urls - .namespace_project_issues_url(project.namespace, project, label_name: label.name) + .project_issues_url(project, label_name: label.name) expect(doc.text).to eq 'See g.fm & references?' end @@ -250,9 +250,9 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do doc = reference_filter("See #{references}") expect(doc.css('a').map { |a| a.attr('href') }).to match_array([ - urls.namespace_project_issues_url(project.namespace, project, label_name: bug.name), - urls.namespace_project_issues_url(project.namespace, project, label_name: feature_proposal.name), - urls.namespace_project_issues_url(project.namespace, project, label_name: technical_debt.name) + urls.project_issues_url(project, label_name: bug.name), + urls.project_issues_url(project, label_name: feature_proposal.name), + urls.project_issues_url(project, label_name: technical_debt.name) ]) expect(doc.text).to eq 'See bug, feature proposal, technical debt' end @@ -265,9 +265,9 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do doc = reference_filter("See #{references}") expect(doc.css('a').map { |a| a.attr('href') }).to match_array([ - urls.namespace_project_issues_url(project.namespace, project, label_name: bug.name), - urls.namespace_project_issues_url(project.namespace, project, label_name: feature_proposal.name), - urls.namespace_project_issues_url(project.namespace, project, label_name: technical_debt.name) + urls.project_issues_url(project, label_name: bug.name), + urls.project_issues_url(project, label_name: feature_proposal.name), + urls.project_issues_url(project, label_name: technical_debt.name) ]) expect(doc.text).to eq 'See bug feature proposal technical debt' end @@ -288,7 +288,7 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do doc = reference_filter("See #{reference}") expect(doc.css('a').first.attr('href')).to eq urls - .namespace_project_issues_url(project.namespace, project, label_name: label.name) + .project_issues_url(project, label_name: label.name) end it 'links with adjacent text' do @@ -325,7 +325,7 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do doc = reference_filter("See #{reference}", project: project) expect(doc.css('a').first.attr('href')).to eq urls - .namespace_project_issues_url(project.namespace, project, label_name: group_label.name) + .project_issues_url(project, label_name: group_label.name) expect(doc.text).to eq 'See gfm references' end @@ -348,7 +348,7 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do doc = reference_filter("See #{reference}", project: project) expect(doc.css('a').first.attr('href')).to eq urls - .namespace_project_issues_url(project.namespace, project, label_name: group_label.name) + .project_issues_url(project, label_name: group_label.name) expect(doc.text).to eq "See gfm references" end @@ -373,9 +373,7 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do it 'links to a valid reference' do expect(result.css('a').first.attr('href')) - .to eq urls.namespace_project_issues_url(project2.namespace, - project2, - label_name: label.name) + .to eq urls.project_issues_url(project2, label_name: label.name) end it 'has valid color' do @@ -407,9 +405,7 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do it 'links to a valid reference' do expect(result.css('a').first.attr('href')) - .to eq urls.namespace_project_issues_url(project2.namespace, - project2, - label_name: label.name) + .to eq urls.project_issues_url(project2, label_name: label.name) end it 'has valid color' do @@ -441,9 +437,7 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do it 'links to a valid reference' do expect(result.css('a').first.attr('href')) - .to eq urls.namespace_project_issues_url(project2.namespace, - project2, - label_name: label.name) + .to eq urls.project_issues_url(project2, label_name: label.name) end it 'has valid color' do @@ -477,9 +471,7 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do it 'points to referenced project issues page' do expect(result.css('a').first.attr('href')) - .to eq urls.namespace_project_issues_url(another_project.namespace, - another_project, - label_name: group_label.name) + .to eq urls.project_issues_url(another_project, label_name: group_label.name) end it 'has valid color' do @@ -514,9 +506,7 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do it 'points to referenced project issues page' do expect(result.css('a').first.attr('href')) - .to eq urls.namespace_project_issues_url(another_project.namespace, - another_project, - label_name: group_label.name) + .to eq urls.project_issues_url(another_project, label_name: group_label.name) end it 'has valid color' do @@ -550,9 +540,7 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do it 'points to referenced project issues page' do expect(result.css('a').first.attr('href')) - .to eq urls.namespace_project_issues_url(project.namespace, - project, - label_name: group_label.name) + .to eq urls.project_issues_url(project, label_name: group_label.name) end it 'has valid color' do @@ -584,9 +572,7 @@ describe Banzai::Filter::LabelReferenceFilter, lib: true do it 'points to referenced project issues page' do expect(result.css('a').first.attr('href')) - .to eq urls.namespace_project_issues_url(project.namespace, - project, - label_name: group_label.name) + .to eq urls.project_issues_url(project, label_name: group_label.name) end it 'has valid color' do diff --git a/spec/lib/banzai/filter/merge_request_reference_filter_spec.rb b/spec/lib/banzai/filter/merge_request_reference_filter_spec.rb index cd91681551e..1ad329b6452 100644 --- a/spec/lib/banzai/filter/merge_request_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/merge_request_reference_filter_spec.rb @@ -37,7 +37,7 @@ describe Banzai::Filter::MergeRequestReferenceFilter, lib: true do doc = reference_filter("See #{reference}") expect(doc.css('a').first.attr('href')).to eq urls - .namespace_project_merge_request_url(project.namespace, project, merge) + .project_merge_request_url(project, merge) end it 'links with adjacent text' do @@ -95,7 +95,7 @@ describe Banzai::Filter::MergeRequestReferenceFilter, lib: true do link = doc.css('a').first.attr('href') expect(link).not_to match %r(https?://) - expect(link).to eq urls.namespace_project_merge_request_url(project.namespace, project, merge, only_path: true) + expect(link).to eq urls.project_merge_request_url(project, merge, only_path: true) end end @@ -108,8 +108,7 @@ describe Banzai::Filter::MergeRequestReferenceFilter, lib: true do doc = reference_filter("See #{reference}") expect(doc.css('a').first.attr('href')) - .to eq urls.namespace_project_merge_request_url(project2.namespace, - project2, merge) + .to eq urls.project_merge_request_url(project2, merge) end it 'link has valid text' do @@ -142,8 +141,7 @@ describe Banzai::Filter::MergeRequestReferenceFilter, lib: true do doc = reference_filter("See #{reference}") expect(doc.css('a').first.attr('href')) - .to eq urls.namespace_project_merge_request_url(project2.namespace, - project2, merge) + .to eq urls.project_merge_request_url(project2, merge) end it 'link has valid text' do @@ -176,8 +174,7 @@ describe Banzai::Filter::MergeRequestReferenceFilter, lib: true do doc = reference_filter("See #{reference}") expect(doc.css('a').first.attr('href')) - .to eq urls.namespace_project_merge_request_url(project2.namespace, - project2, merge) + .to eq urls.project_merge_request_url(project2, merge) end it 'link has valid text' do @@ -203,7 +200,7 @@ describe Banzai::Filter::MergeRequestReferenceFilter, lib: true do let(:namespace) { create(:namespace, name: 'cross-reference') } let(:project2) { create(:empty_project, :public, namespace: namespace) } let(:merge) { create(:merge_request, source_project: project2, target_project: project2) } - let(:reference) { urls.namespace_project_merge_request_url(project2.namespace, project2, merge) + '/diffs#note_123' } + let(:reference) { urls.project_merge_request_url(project2, merge) + '/diffs#note_123' } it 'links to a valid reference' do doc = reference_filter("See #{reference}") diff --git a/spec/lib/banzai/filter/milestone_reference_filter_spec.rb b/spec/lib/banzai/filter/milestone_reference_filter_spec.rb index fe88b9cb73e..7fab5613afc 100644 --- a/spec/lib/banzai/filter/milestone_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/milestone_reference_filter_spec.rb @@ -45,7 +45,7 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do expect(link).not_to match %r(https?://) expect(link).to eq urls - .namespace_project_milestone_path(project.namespace, project, milestone) + .project_milestone_path(project, milestone) end context 'Integer-based references' do @@ -53,7 +53,7 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do doc = reference_filter("See #{reference}") expect(doc.css('a').first.attr('href')).to eq urls - .namespace_project_milestone_url(project.namespace, project, milestone) + .project_milestone_url(project, milestone) end it 'links with adjacent text' do @@ -76,7 +76,7 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do doc = reference_filter("See #{reference}") expect(doc.css('a').first.attr('href')).to eq urls - .namespace_project_milestone_url(project.namespace, project, milestone) + .project_milestone_url(project, milestone) expect(doc.text).to eq 'See gfm' end @@ -100,7 +100,7 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do doc = reference_filter("See #{reference}") expect(doc.css('a').first.attr('href')).to eq urls - .namespace_project_milestone_url(project.namespace, project, milestone) + .project_milestone_url(project, milestone) expect(doc.text).to eq 'See gfm references' end @@ -123,7 +123,7 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do doc = reference_filter("See #{reference}") expect(doc.css('a').first.attr('href')).to eq urls - .namespace_project_milestone_url(project.namespace, project, milestone) + .project_milestone_url(project, milestone) end it 'links with adjacent text' do @@ -157,9 +157,7 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do it 'points to referenced project milestone page' do expect(result.css('a').first.attr('href')).to eq urls - .namespace_project_milestone_url(another_project.namespace, - another_project, - milestone) + .project_milestone_url(another_project, milestone) end it 'link has valid text' do @@ -196,9 +194,7 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do it 'points to referenced project milestone page' do expect(result.css('a').first.attr('href')).to eq urls - .namespace_project_milestone_url(another_project.namespace, - another_project, - milestone) + .project_milestone_url(another_project, milestone) end it 'link has valid text' do @@ -235,9 +231,7 @@ describe Banzai::Filter::MilestoneReferenceFilter, lib: true do it 'points to referenced project milestone page' do expect(result.css('a').first.attr('href')).to eq urls - .namespace_project_milestone_url(another_project.namespace, - another_project, - milestone) + .project_milestone_url(another_project, milestone) end it 'link has valid text' do diff --git a/spec/lib/banzai/filter/snippet_reference_filter_spec.rb b/spec/lib/banzai/filter/snippet_reference_filter_spec.rb index e851120bc3a..9704db0c221 100644 --- a/spec/lib/banzai/filter/snippet_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/snippet_reference_filter_spec.rb @@ -23,7 +23,7 @@ describe Banzai::Filter::SnippetReferenceFilter, lib: true do doc = reference_filter("See #{reference}") expect(doc.css('a').first.attr('href')).to eq urls - .namespace_project_snippet_url(project.namespace, project, snippet) + .project_snippet_url(project, snippet) end it 'links with adjacent text' do @@ -75,7 +75,7 @@ describe Banzai::Filter::SnippetReferenceFilter, lib: true do link = doc.css('a').first.attr('href') expect(link).not_to match %r(https?://) - expect(link).to eq urls.namespace_project_snippet_url(project.namespace, project, snippet, only_path: true) + expect(link).to eq urls.project_snippet_url(project, snippet, only_path: true) end end @@ -89,7 +89,7 @@ describe Banzai::Filter::SnippetReferenceFilter, lib: true do doc = reference_filter("See #{reference}") expect(doc.css('a').first.attr('href')) - .to eq urls.namespace_project_snippet_url(project2.namespace, project2, snippet) + .to eq urls.project_snippet_url(project2, snippet) end it 'link has valid text' do @@ -122,7 +122,7 @@ describe Banzai::Filter::SnippetReferenceFilter, lib: true do doc = reference_filter("See #{reference}") expect(doc.css('a').first.attr('href')) - .to eq urls.namespace_project_snippet_url(project2.namespace, project2, snippet) + .to eq urls.project_snippet_url(project2, snippet) end it 'link has valid text' do @@ -155,7 +155,7 @@ describe Banzai::Filter::SnippetReferenceFilter, lib: true do doc = reference_filter("See #{reference}") expect(doc.css('a').first.attr('href')) - .to eq urls.namespace_project_snippet_url(project2.namespace, project2, snippet) + .to eq urls.project_snippet_url(project2, snippet) end it 'link has valid text' do @@ -181,13 +181,13 @@ describe Banzai::Filter::SnippetReferenceFilter, lib: true do let(:namespace) { create(:namespace, name: 'cross-reference') } let(:project2) { create(:empty_project, :public, namespace: namespace) } let(:snippet) { create(:project_snippet, project: project2) } - let(:reference) { urls.namespace_project_snippet_url(project2.namespace, project2, snippet) } + let(:reference) { urls.project_snippet_url(project2, snippet) } it 'links to a valid reference' do doc = reference_filter("See #{reference}") expect(doc.css('a').first.attr('href')) - .to eq urls.namespace_project_snippet_url(project2.namespace, project2, snippet) + .to eq urls.project_snippet_url(project2, snippet) end it 'links with adjacent text' do diff --git a/spec/lib/banzai/filter/user_reference_filter_spec.rb b/spec/lib/banzai/filter/user_reference_filter_spec.rb index edf3846b742..77561e00573 100644 --- a/spec/lib/banzai/filter/user_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/user_reference_filter_spec.rb @@ -43,7 +43,7 @@ describe Banzai::Filter::UserReferenceFilter, lib: true do expect(doc.css('a').length).to eq 1 expect(doc.css('a').first.attr('href')) - .to eq urls.namespace_project_url(project.namespace, project) + .to eq urls.project_url(project) end it 'includes a data-author attribute when there is an author' do diff --git a/spec/lib/banzai/pipeline/gfm_pipeline_spec.rb b/spec/lib/banzai/pipeline/gfm_pipeline_spec.rb index 2b8c76f2bb8..1eb90dc1847 100644 --- a/spec/lib/banzai/pipeline/gfm_pipeline_spec.rb +++ b/spec/lib/banzai/pipeline/gfm_pipeline_spec.rb @@ -22,11 +22,7 @@ describe Banzai::Pipeline::GfmPipeline do link = result.css('a').first expect(link['href']).to eq( - Gitlab::Routing.url_helpers.namespace_project_issue_path( - other_project.namespace, - other_project, - issue - ) + Gitlab::Routing.url_helpers.project_issue_path(other_project, issue) ) end end diff --git a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb index 482f03aa0cc..ef58ef1b0cd 100644 --- a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb +++ b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb @@ -878,7 +878,8 @@ module Ci expect(config_processor.builds_for_stage_and_ref("test", "master").first[:options][:cache]).to eq( paths: ["logs/", "binaries/"], untracked: true, - key: 'key' + key: 'key', + policy: 'pull-push' ) end @@ -896,7 +897,8 @@ module Ci expect(config_processor.builds_for_stage_and_ref("test", "master").first[:options][:cache]).to eq( paths: ["logs/", "binaries/"], untracked: true, - key: 'key' + key: 'key', + policy: 'pull-push' ) end @@ -915,7 +917,8 @@ module Ci expect(config_processor.builds_for_stage_and_ref("test", "master").first[:options][:cache]).to eq( paths: ["test/"], untracked: false, - key: 'local' + key: 'local', + policy: 'pull-push' ) end end diff --git a/spec/lib/gitlab/ci/config/entry/cache_spec.rb b/spec/lib/gitlab/ci/config/entry/cache_spec.rb index 878b1d6b862..8f711e02f9b 100644 --- a/spec/lib/gitlab/ci/config/entry/cache_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/cache_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' describe Gitlab::Ci::Config::Entry::Cache do - let(:entry) { described_class.new(config) } + subject(:entry) { described_class.new(config) } describe 'validations' do before do @@ -9,22 +9,44 @@ describe Gitlab::Ci::Config::Entry::Cache do end context 'when entry config value is correct' do + let(:policy) { nil } + let(:config) do { key: 'some key', untracked: true, - paths: ['some/path/'] } + paths: ['some/path/'], + policy: policy } end describe '#value' do it 'returns hash value' do - expect(entry.value).to eq config + expect(entry.value).to eq(key: 'some key', untracked: true, paths: ['some/path/'], policy: 'pull-push') end end describe '#valid?' do - it 'is valid' do - expect(entry).to be_valid - end + it { is_expected.to be_valid } + end + + context 'policy is pull-push' do + let(:policy) { 'pull-push' } + + it { is_expected.to be_valid } + it { expect(entry.value).to include(policy: 'pull-push') } + end + + context 'policy is push' do + let(:policy) { 'push' } + + it { is_expected.to be_valid } + it { expect(entry.value).to include(policy: 'push') } + end + + context 'policy is pull' do + let(:policy) { 'pull' } + + it { is_expected.to be_valid } + it { expect(entry.value).to include(policy: 'pull') } end context 'when key is missing' do @@ -44,12 +66,20 @@ describe Gitlab::Ci::Config::Entry::Cache do context 'when entry value is not correct' do describe '#errors' do + subject { entry.errors } context 'when is not a hash' do let(:config) { 'ls' } it 'reports errors with config value' do - expect(entry.errors) - .to include 'cache config should be a hash' + is_expected.to include 'cache config should be a hash' + end + end + + context 'when policy is unknown' do + let(:config) { { policy: "unknown" } } + + it 'reports error' do + is_expected.to include('cache policy should be pull-push, push, or pull') end end @@ -57,8 +87,7 @@ describe Gitlab::Ci::Config::Entry::Cache do let(:config) { { key: 1 } } it 'reports error with descendants' do - expect(entry.errors) - .to include 'key config should be a string or symbol' + is_expected.to include 'key config should be a string or symbol' end end @@ -66,8 +95,7 @@ describe Gitlab::Ci::Config::Entry::Cache do let(:config) { { invalid: true } } it 'reports error with descendants' do - expect(entry.errors) - .to include 'cache config contains unknown keys: invalid' + is_expected.to include 'cache config contains unknown keys: invalid' end end end diff --git a/spec/lib/gitlab/ci/config/entry/global_spec.rb b/spec/lib/gitlab/ci/config/entry/global_spec.rb index 293f112b2b0..1860ed79bfd 100644 --- a/spec/lib/gitlab/ci/config/entry/global_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/global_spec.rb @@ -143,7 +143,7 @@ describe Gitlab::Ci::Config::Entry::Global do describe '#cache_value' do it 'returns cache configuration' do expect(global.cache_value) - .to eq(key: 'k', untracked: true, paths: ['public/']) + .to eq(key: 'k', untracked: true, paths: ['public/'], policy: 'pull-push') end end @@ -157,7 +157,7 @@ describe Gitlab::Ci::Config::Entry::Global do image: { name: 'ruby:2.2' }, services: [{ name: 'postgres:9.1' }, { name: 'mysql:5.5' }], stage: 'test', - cache: { key: 'k', untracked: true, paths: ['public/'] }, + cache: { key: 'k', untracked: true, paths: ['public/'], policy: 'pull-push' }, variables: { 'VAR' => 'value' }, ignore: false, after_script: ['make clean'] }, @@ -168,7 +168,7 @@ describe Gitlab::Ci::Config::Entry::Global do image: { name: 'ruby:2.2' }, services: [{ name: 'postgres:9.1' }, { name: 'mysql:5.5' }], stage: 'test', - cache: { key: 'k', untracked: true, paths: ['public/'] }, + cache: { key: 'k', untracked: true, paths: ['public/'], policy: 'pull-push' }, variables: {}, ignore: false, after_script: ['make clean'] } @@ -212,7 +212,7 @@ describe Gitlab::Ci::Config::Entry::Global do describe '#cache_value' do it 'returns correct cache definition' do - expect(global.cache_value).to eq(key: 'a') + expect(global.cache_value).to eq(key: 'a', policy: 'pull-push') end end end diff --git a/spec/lib/gitlab/ci/config/entry/job_spec.rb b/spec/lib/gitlab/ci/config/entry/job_spec.rb index 92cba689f47..c5cad887b64 100644 --- a/spec/lib/gitlab/ci/config/entry/job_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/job_spec.rb @@ -109,7 +109,7 @@ describe Gitlab::Ci::Config::Entry::Job do it 'overrides global config' do expect(entry[:image].value).to eq(name: 'some_image') - expect(entry[:cache].value).to eq(key: 'test') + expect(entry[:cache].value).to eq(key: 'test', policy: 'pull-push') end end @@ -123,7 +123,7 @@ describe Gitlab::Ci::Config::Entry::Job do it 'uses config from global entry' do expect(entry[:image].value).to eq 'specified' - expect(entry[:cache].value).to eq(key: 'test') + expect(entry[:cache].value).to eq(key: 'test', policy: 'pull-push') end end end diff --git a/spec/lib/gitlab/closing_issue_extractor_spec.rb b/spec/lib/gitlab/closing_issue_extractor_spec.rb index ca68010cb89..fe988266ae3 100644 --- a/spec/lib/gitlab/closing_issue_extractor_spec.rb +++ b/spec/lib/gitlab/closing_issue_extractor_spec.rb @@ -276,7 +276,7 @@ describe Gitlab::ClosingIssueExtractor, lib: true do context "with a cross-project URL" do it do - message = "Closes #{urls.namespace_project_issue_url(issue2.project.namespace, issue2.project, issue2)}" + message = "Closes #{urls.project_issue_url(issue2.project, issue2)}" expect(subject.closed_by_message(message)).to eq([issue2]) end end @@ -292,7 +292,7 @@ describe Gitlab::ClosingIssueExtractor, lib: true do context "with an invalid URL" do it do - message = "Closes https://google.com#{urls.namespace_project_issue_path(issue2.project.namespace, issue2.project, issue2)}" + message = "Closes https://google.com#{urls.project_issue_path(issue2.project, issue2)}" expect(subject.closed_by_message(message)).to eq([]) end end @@ -347,14 +347,14 @@ describe Gitlab::ClosingIssueExtractor, lib: true do end it "fetches cross-project URL references" do - message = "Closes #{urls.namespace_project_issue_url(issue2.project.namespace, issue2.project, issue2)} and #{reference}" + message = "Closes #{urls.project_issue_url(issue2.project, issue2)} and #{reference}" expect(subject.closed_by_message(message)) .to match_array([issue, issue2]) end it "ignores invalid cross-project URL references" do - message = "Closes https://google.com#{urls.namespace_project_issue_path(issue2.project.namespace, issue2.project, issue2)} and #{reference}" + message = "Closes https://google.com#{urls.project_issue_path(issue2.project, issue2)} and #{reference}" expect(subject.closed_by_message(message)) .to match_array([issue]) diff --git a/spec/lib/gitlab/git/blame_spec.rb b/spec/lib/gitlab/git/blame_spec.rb index 8b041ac69b1..66c016d14b3 100644 --- a/spec/lib/gitlab/git/blame_spec.rb +++ b/spec/lib/gitlab/git/blame_spec.rb @@ -20,6 +20,7 @@ describe Gitlab::Git::Blame, seed_helper: true do expect(data.size).to eq(95) expect(data.first[:commit]).to be_kind_of(Gitlab::Git::Commit) expect(data.first[:line]).to eq("# Contribute to GitLab") + expect(data.first[:line]).to be_utf8 end end @@ -40,6 +41,7 @@ describe Gitlab::Git::Blame, seed_helper: true do expect(data.size).to eq(1) expect(data.first[:commit]).to be_kind_of(Gitlab::Git::Commit) expect(data.first[:line]).to eq("Ä ü") + expect(data.first[:line]).to be_utf8 end end @@ -61,6 +63,7 @@ describe Gitlab::Git::Blame, seed_helper: true do expect(data.size).to eq(1) expect(data.first[:commit]).to be_kind_of(Gitlab::Git::Commit) expect(data.first[:line]).to eq(" ") + expect(data.first[:line]).to be_utf8 end end end diff --git a/spec/lib/gitlab/git/branch_spec.rb b/spec/lib/gitlab/git/branch_spec.rb index 9dba4397e79..d1d7ed1d02a 100644 --- a/spec/lib/gitlab/git/branch_spec.rb +++ b/spec/lib/gitlab/git/branch_spec.rb @@ -48,7 +48,7 @@ describe Gitlab::Git::Branch, seed_helper: true do expect(Gitlab::Git::Commit).to receive(:decorate) .with(hash_including(attributes)).and_call_original - expect(branch.dereferenced_target.message.encoding).to be(Encoding::UTF_8) + expect(branch.dereferenced_target.message).to be_utf8 end end diff --git a/spec/lib/gitlab/git/diff_spec.rb b/spec/lib/gitlab/git/diff_spec.rb index d50ccb0df30..d97e85364c2 100644 --- a/spec/lib/gitlab/git/diff_spec.rb +++ b/spec/lib/gitlab/git/diff_spec.rb @@ -180,7 +180,7 @@ EOT let(:raw_patch) { @raw_diff_hash[:diff].encode(Encoding::ASCII_8BIT) } it 'encodes diff patch to UTF-8' do - expect(diff.diff.encoding).to eq(Encoding::UTF_8) + expect(diff.diff).to be_utf8 end end end diff --git a/spec/lib/gitlab/git/repository_spec.rb b/spec/lib/gitlab/git/repository_spec.rb index 0cd458bf933..6aca181194a 100644 --- a/spec/lib/gitlab/git/repository_spec.rb +++ b/spec/lib/gitlab/git/repository_spec.rb @@ -27,34 +27,24 @@ describe Gitlab::Git::Repository, seed_helper: true do end it 'returns UTF-8' do - expect(repository.root_ref.encoding).to eq(Encoding.find('UTF-8')) + expect(repository.root_ref).to be_utf8 end - context 'with gitaly enabled' do - before do - stub_gitaly - end - - after do - Gitlab::GitalyClient.clear_stubs! - end - - it 'gets the branch name from GitalyClient' do - expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:default_branch_name) - repository.root_ref - end + it 'gets the branch name from GitalyClient' do + expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:default_branch_name) + repository.root_ref + end - it 'wraps GRPC not found' do - expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:default_branch_name) - .and_raise(GRPC::NotFound) - expect { repository.root_ref }.to raise_error(Gitlab::Git::Repository::NoRepository) - end + it 'wraps GRPC not found' do + expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:default_branch_name) + .and_raise(GRPC::NotFound) + expect { repository.root_ref }.to raise_error(Gitlab::Git::Repository::NoRepository) + end - it 'wraps GRPC exceptions' do - expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:default_branch_name) - .and_raise(GRPC::Unknown) - expect { repository.root_ref }.to raise_error(Gitlab::Git::CommandError) - end + it 'wraps GRPC exceptions' do + expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:default_branch_name) + .and_raise(GRPC::Unknown) + expect { repository.root_ref }.to raise_error(Gitlab::Git::CommandError) end end @@ -129,37 +119,27 @@ describe Gitlab::Git::Repository, seed_helper: true do end it 'returns UTF-8' do - expect(subject.first.encoding).to eq(Encoding.find('UTF-8')) + expect(subject.first).to be_utf8 end it { is_expected.to include("master") } it { is_expected.not_to include("branch-from-space") } - context 'with gitaly enabled' do - before do - stub_gitaly - end - - after do - Gitlab::GitalyClient.clear_stubs! - end - - it 'gets the branch names from GitalyClient' do - expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:branch_names) - subject - end + it 'gets the branch names from GitalyClient' do + expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:branch_names) + subject + end - it 'wraps GRPC not found' do - expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:branch_names) - .and_raise(GRPC::NotFound) - expect { subject }.to raise_error(Gitlab::Git::Repository::NoRepository) - end + it 'wraps GRPC not found' do + expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:branch_names) + .and_raise(GRPC::NotFound) + expect { subject }.to raise_error(Gitlab::Git::Repository::NoRepository) + end - it 'wraps GRPC other exceptions' do - expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:branch_names) - .and_raise(GRPC::Unknown) - expect { subject }.to raise_error(Gitlab::Git::CommandError) - end + it 'wraps GRPC other exceptions' do + expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:branch_names) + .and_raise(GRPC::Unknown) + expect { subject }.to raise_error(Gitlab::Git::CommandError) end end @@ -173,7 +153,7 @@ describe Gitlab::Git::Repository, seed_helper: true do end it 'returns UTF-8' do - expect(subject.first.encoding).to eq(Encoding.find('UTF-8')) + expect(subject.first).to be_utf8 end describe '#last' do @@ -183,31 +163,21 @@ describe Gitlab::Git::Repository, seed_helper: true do it { is_expected.to include("v1.0.0") } it { is_expected.not_to include("v5.0.0") } - context 'with gitaly enabled' do - before do - stub_gitaly - end - - after do - Gitlab::GitalyClient.clear_stubs! - end - - it 'gets the tag names from GitalyClient' do - expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:tag_names) - subject - end + it 'gets the tag names from GitalyClient' do + expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:tag_names) + subject + end - it 'wraps GRPC not found' do - expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:tag_names) - .and_raise(GRPC::NotFound) - expect { subject }.to raise_error(Gitlab::Git::Repository::NoRepository) - end + it 'wraps GRPC not found' do + expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:tag_names) + .and_raise(GRPC::NotFound) + expect { subject }.to raise_error(Gitlab::Git::Repository::NoRepository) + end - it 'wraps GRPC exceptions' do - expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:tag_names) - .and_raise(GRPC::Unknown) - expect { subject }.to raise_error(Gitlab::Git::CommandError) - end + it 'wraps GRPC exceptions' do + expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:tag_names) + .and_raise(GRPC::Unknown) + expect { subject }.to raise_error(Gitlab::Git::CommandError) end end @@ -358,6 +328,38 @@ describe Gitlab::Git::Repository, seed_helper: true do end end + describe '#submodule_url_for' do + let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) } + let(:ref) { 'master' } + + def submodule_url(path) + repository.submodule_url_for(ref, path) + end + + it { expect(submodule_url('six')).to eq('git://github.com/randx/six.git') } + it { expect(submodule_url('nested/six')).to eq('git://github.com/randx/six.git') } + it { expect(submodule_url('deeper/nested/six')).to eq('git://github.com/randx/six.git') } + it { expect(submodule_url('invalid/path')).to eq(nil) } + + context 'uncommitted submodule dir' do + let(:ref) { 'fix-existing-submodule-dir' } + + it { expect(submodule_url('submodule-existing-dir')).to eq(nil) } + end + + context 'tags' do + let(:ref) { 'v1.2.1' } + + it { expect(submodule_url('six')).to eq('git://github.com/randx/six.git') } + end + + context 'no submodules at commit' do + let(:ref) { '6d39438' } + + it { expect(submodule_url('six')).to eq(nil) } + end + end + context '#submodules' do let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) } @@ -1281,42 +1283,31 @@ describe Gitlab::Git::Repository, seed_helper: true do expect(@repo.local_branches.any? { |branch| branch.name == 'local_branch' }).to eq(true) end - context 'with gitaly enabled' do - before do - stub_gitaly - end - - after do - Gitlab::GitalyClient.clear_stubs! - end - - it 'returns a Branch with UTF-8 fields' do - branches = @repo.local_branches.to_a - expect(branches.size).to be > 0 - utf_8 = Encoding.find('utf-8') - branches.each do |branch| - expect(branch.name.encoding).to eq(utf_8) - expect(branch.target.encoding).to eq(utf_8) unless branch.target.nil? - end + it 'returns a Branch with UTF-8 fields' do + branches = @repo.local_branches.to_a + expect(branches.size).to be > 0 + branches.each do |branch| + expect(branch.name).to be_utf8 + expect(branch.target).to be_utf8 unless branch.target.nil? end + end - it 'gets the branches from GitalyClient' do - expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:local_branches) - .and_return([]) - @repo.local_branches - end + it 'gets the branches from GitalyClient' do + expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:local_branches) + .and_return([]) + @repo.local_branches + end - it 'wraps GRPC not found' do - expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:local_branches) - .and_raise(GRPC::NotFound) - expect { @repo.local_branches }.to raise_error(Gitlab::Git::Repository::NoRepository) - end + it 'wraps GRPC not found' do + expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:local_branches) + .and_raise(GRPC::NotFound) + expect { @repo.local_branches }.to raise_error(Gitlab::Git::Repository::NoRepository) + end - it 'wraps GRPC exceptions' do - expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:local_branches) - .and_raise(GRPC::Unknown) - expect { @repo.local_branches }.to raise_error(Gitlab::Git::CommandError) - end + it 'wraps GRPC exceptions' do + expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:local_branches) + .and_raise(GRPC::Unknown) + expect { @repo.local_branches }.to raise_error(Gitlab::Git::CommandError) end end @@ -1395,11 +1386,4 @@ describe Gitlab::Git::Repository, seed_helper: true do sha = Rugged::Commit.create(repo, options) repo.lookup(sha) end - - def stub_gitaly - allow(Gitlab::GitalyClient).to receive(:feature_enabled?).and_return(true) - - stub = double(:stub) - allow(Gitaly::Ref::Stub).to receive(:new).and_return(stub) - end end diff --git a/spec/lib/gitlab/gitaly_client/ref_spec.rb b/spec/lib/gitlab/gitaly_client/ref_spec.rb index 8ad39a02b93..7c090460764 100644 --- a/spec/lib/gitlab/gitaly_client/ref_spec.rb +++ b/spec/lib/gitlab/gitaly_client/ref_spec.rb @@ -6,17 +6,6 @@ describe Gitlab::GitalyClient::Ref do let(:relative_path) { project.path_with_namespace + '.git' } let(:client) { described_class.new(project.repository) } - before do - allow(Gitlab.config.gitaly).to receive(:enabled).and_return(true) - end - - after do - # When we say `expect_any_instance_of(Gitaly::Ref::Stub)` a double is created, - # and because GitalyClient shares stubs these will get passed from example to - # example, which will cause an error, so we clean the stubs after each example. - Gitlab::GitalyClient.clear_stubs! - end - describe '#branch_names' do it 'sends a find_all_branch_names message' do expect_any_instance_of(Gitaly::Ref::Stub) @@ -82,4 +71,13 @@ describe Gitlab::GitalyClient::Ref do expect { client.local_branches(sort_by: 'invalid_sort') }.to raise_error(ArgumentError) end end + + describe '#find_ref_name', seed_helper: true do + let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) } + let(:client) { described_class.new(repository) } + subject { client.find_ref_name(SeedRepo::Commit::ID, 'refs/heads/master') } + + it { is_expected.to be_utf8 } + it { is_expected.to eq('refs/heads/master') } + end end diff --git a/spec/lib/gitlab/health_checks/fs_shards_check_spec.rb b/spec/lib/gitlab/health_checks/fs_shards_check_spec.rb index 61c10d47434..b333e162909 100644 --- a/spec/lib/gitlab/health_checks/fs_shards_check_spec.rb +++ b/spec/lib/gitlab/health_checks/fs_shards_check_spec.rb @@ -97,30 +97,40 @@ describe Gitlab::HealthChecks::FsShardsCheck do }.with_indifferent_access end - it { is_expected.to all(have_attributes(labels: { shard: :default })) } + # Unsolved intermittent failure in CI https://gitlab.com/gitlab-org/gitlab-ce/issues/31128 + around(:each) do |example| # rubocop:disable RSpec/AroundBlock + times_to_try = ENV['CI'] ? 4 : 1 + example.run_with_retry retry: times_to_try + end - it { is_expected.to include(an_object_having_attributes(name: :filesystem_accessible, value: 0)) } - it { is_expected.to include(an_object_having_attributes(name: :filesystem_readable, value: 0)) } - it { is_expected.to include(an_object_having_attributes(name: :filesystem_writable, value: 0)) } + it 'provides metrics' do + expect(subject).to all(have_attributes(labels: { shard: :default })) + expect(subject).to include(an_object_having_attributes(name: :filesystem_accessible, value: 0)) + expect(subject).to include(an_object_having_attributes(name: :filesystem_readable, value: 0)) + expect(subject).to include(an_object_having_attributes(name: :filesystem_writable, value: 0)) - it { is_expected.to include(an_object_having_attributes(name: :filesystem_access_latency, value: be >= 0)) } - it { is_expected.to include(an_object_having_attributes(name: :filesystem_read_latency, value: be >= 0)) } - it { is_expected.to include(an_object_having_attributes(name: :filesystem_write_latency, value: be >= 0)) } + expect(subject).to include(an_object_having_attributes(name: :filesystem_access_latency, value: be >= 0)) + expect(subject).to include(an_object_having_attributes(name: :filesystem_read_latency, value: be >= 0)) + expect(subject).to include(an_object_having_attributes(name: :filesystem_write_latency, value: be >= 0)) + end end context 'storage points to directory that has both read and write rights' do before do FileUtils.chmod_R(0755, tmp_dir) end - it { is_expected.to all(have_attributes(labels: { shard: :default })) } - it { is_expected.to include(an_object_having_attributes(name: :filesystem_accessible, value: 1)) } - it { is_expected.to include(an_object_having_attributes(name: :filesystem_readable, value: 1)) } - it { is_expected.to include(an_object_having_attributes(name: :filesystem_writable, value: 1)) } + it 'provides metrics' do + expect(subject).to all(have_attributes(labels: { shard: :default })) - it { is_expected.to include(an_object_having_attributes(name: :filesystem_access_latency, value: be >= 0)) } - it { is_expected.to include(an_object_having_attributes(name: :filesystem_read_latency, value: be >= 0)) } - it { is_expected.to include(an_object_having_attributes(name: :filesystem_write_latency, value: be >= 0)) } + expect(subject).to include(an_object_having_attributes(name: :filesystem_accessible, value: 1)) + expect(subject).to include(an_object_having_attributes(name: :filesystem_readable, value: 1)) + expect(subject).to include(an_object_having_attributes(name: :filesystem_writable, value: 1)) + + expect(subject).to include(an_object_having_attributes(name: :filesystem_access_latency, value: be >= 0)) + expect(subject).to include(an_object_having_attributes(name: :filesystem_read_latency, value: be >= 0)) + expect(subject).to include(an_object_having_attributes(name: :filesystem_write_latency, value: be >= 0)) + end end end end diff --git a/spec/lib/gitlab/import_export/safe_model_attributes.yml b/spec/lib/gitlab/import_export/safe_model_attributes.yml index fadd3ad1330..697ddf52af9 100644 --- a/spec/lib/gitlab/import_export/safe_model_attributes.yml +++ b/spec/lib/gitlab/import_export/safe_model_attributes.yml @@ -383,6 +383,7 @@ Project: - printing_merge_request_link_enabled - build_allow_git_fetch - last_repository_updated_at +- ci_config_path Author: - name ProjectFeature: diff --git a/spec/lib/gitlab/kubernetes_spec.rb b/spec/lib/gitlab/kubernetes_spec.rb index e8c599a95ee..34b33772578 100644 --- a/spec/lib/gitlab/kubernetes_spec.rb +++ b/spec/lib/gitlab/kubernetes_spec.rb @@ -46,4 +46,28 @@ describe Gitlab::Kubernetes do expect(filter_by_label(items, app: 'foo')).to eq(matching_items) end end + + describe '#to_kubeconfig' do + subject do + to_kubeconfig( + url: 'https://kube.domain.com', + namespace: 'NAMESPACE', + token: 'TOKEN', + ca_pem: ca_pem) + end + + context 'when CA PEM is provided' do + let(:ca_pem) { 'PEM' } + let(:path) { expand_fixture_path('config/kubeconfig.yml') } + + it { is_expected.to eq(YAML.load_file(path)) } + end + + context 'when CA PEM is not provided' do + let(:ca_pem) { nil } + let(:path) { expand_fixture_path('config/kubeconfig-without-ca.yml') } + + it { is_expected.to eq(YAML.load_file(path)) } + end + end end diff --git a/spec/lib/gitlab/metrics/connection_rack_middleware_spec.rb b/spec/lib/gitlab/metrics/connection_rack_middleware_spec.rb new file mode 100644 index 00000000000..94251af305f --- /dev/null +++ b/spec/lib/gitlab/metrics/connection_rack_middleware_spec.rb @@ -0,0 +1,88 @@ +require 'spec_helper' + +describe Gitlab::Metrics::ConnectionRackMiddleware do + let(:app) { double('app') } + subject { described_class.new(app) } + + around do |example| + Timecop.freeze { example.run } + end + + describe '#call' do + let(:status) { 100 } + let(:env) { { 'REQUEST_METHOD' => 'GET' } } + let(:stack_result) { [status, {}, 'body'] } + + before do + allow(app).to receive(:call).and_return(stack_result) + end + + context '@app.call succeeds with 200' do + before do + allow(app).to receive(:call).and_return([200, nil, nil]) + end + + it 'increments response count with status label' do + expect(described_class).to receive_message_chain(:rack_response_count, :increment).with(include(status: 200, method: 'get')) + + subject.call(env) + end + + it 'increments requests count' do + expect(described_class).to receive_message_chain(:rack_request_count, :increment).with(method: 'get') + + subject.call(env) + end + + it 'measures execution time' do + execution_time = 10 + allow(app).to receive(:call) do |*args| + Timecop.freeze(execution_time.seconds) + end + + expect(described_class).to receive_message_chain(:rack_execution_time, :observe).with({}, execution_time) + + subject.call(env) + end + end + + context '@app.call throws exception' do + let(:rack_response_count) { double('rack_response_count') } + + before do + allow(app).to receive(:call).and_raise(StandardError) + allow(described_class).to receive(:rack_response_count).and_return(rack_response_count) + end + + it 'increments exceptions count' do + expect(described_class).to receive_message_chain(:rack_uncaught_errors_count, :increment) + + expect { subject.call(env) }.to raise_error(StandardError) + end + + it 'increments requests count' do + expect(described_class).to receive_message_chain(:rack_request_count, :increment).with(method: 'get') + + expect { subject.call(env) }.to raise_error(StandardError) + end + + it "does't increment response count" do + expect(described_class.rack_response_count).not_to receive(:increment) + + expect { subject.call(env) }.to raise_error(StandardError) + end + + it 'measures execution time' do + execution_time = 10 + allow(app).to receive(:call) do |*args| + Timecop.freeze(execution_time.seconds) + raise StandardError + end + + expect(described_class).to receive_message_chain(:rack_execution_time, :observe).with({}, execution_time) + + expect { subject.call(env) }.to raise_error(StandardError) + end + end + end +end diff --git a/spec/lib/gitlab/metrics/sampler_spec.rb b/spec/lib/gitlab/metrics/influx_sampler_spec.rb index d07ce6f81af..0bc68d64276 100644 --- a/spec/lib/gitlab/metrics/sampler_spec.rb +++ b/spec/lib/gitlab/metrics/influx_sampler_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe Gitlab::Metrics::Sampler do +describe Gitlab::Metrics::InfluxSampler do let(:sampler) { described_class.new(5) } after do @@ -8,10 +8,10 @@ describe Gitlab::Metrics::Sampler do end describe '#start' do - it 'gathers a sample at a given interval' do - expect(sampler).to receive(:sleep).with(a_kind_of(Numeric)) - expect(sampler).to receive(:sample) - expect(sampler).to receive(:loop).and_yield + it 'runs once and gathers a sample at a given interval' do + expect(sampler).to receive(:sleep).with(a_kind_of(Numeric)).twice + expect(sampler).to receive(:sample).once + expect(sampler).to receive(:running).and_return(false, true, false) sampler.start.join end diff --git a/spec/lib/gitlab/metrics/unicorn_sampler_spec.rb b/spec/lib/gitlab/metrics/unicorn_sampler_spec.rb new file mode 100644 index 00000000000..dc0d1f2e940 --- /dev/null +++ b/spec/lib/gitlab/metrics/unicorn_sampler_spec.rb @@ -0,0 +1,108 @@ +require 'spec_helper' + +describe Gitlab::Metrics::UnicornSampler do + subject { described_class.new(1.second) } + + describe '#sample' do + let(:unicorn) { double('unicorn') } + let(:raindrops) { double('raindrops') } + let(:stats) { double('stats') } + + before do + stub_const('Unicorn', unicorn) + stub_const('Raindrops::Linux', raindrops) + allow(raindrops).to receive(:unix_listener_stats).and_return({}) + allow(raindrops).to receive(:tcp_listener_stats).and_return({}) + end + + context 'unicorn listens on unix sockets' do + let(:socket_address) { '/some/sock' } + let(:sockets) { [socket_address] } + + before do + allow(unicorn).to receive(:listener_names).and_return(sockets) + end + + it 'samples socket data' do + expect(raindrops).to receive(:unix_listener_stats).with(sockets) + + subject.sample + end + + context 'stats collected' do + before do + allow(stats).to receive(:active).and_return('active') + allow(stats).to receive(:queued).and_return('queued') + allow(raindrops).to receive(:unix_listener_stats).and_return({ socket_address => stats }) + end + + it 'updates metrics type unix and with addr' do + labels = { type: 'unix', address: socket_address } + + expect(subject).to receive_message_chain(:unicorn_active_connections, :set).with(labels, 'active') + expect(subject).to receive_message_chain(:unicorn_queued_connections, :set).with(labels, 'queued') + + subject.sample + end + end + end + + context 'unicorn listens on tcp sockets' do + let(:tcp_socket_address) { '0.0.0.0:8080' } + let(:tcp_sockets) { [tcp_socket_address] } + + before do + allow(unicorn).to receive(:listener_names).and_return(tcp_sockets) + end + + it 'samples socket data' do + expect(raindrops).to receive(:tcp_listener_stats).with(tcp_sockets) + + subject.sample + end + + context 'stats collected' do + before do + allow(stats).to receive(:active).and_return('active') + allow(stats).to receive(:queued).and_return('queued') + allow(raindrops).to receive(:tcp_listener_stats).and_return({ tcp_socket_address => stats }) + end + + it 'updates metrics type unix and with addr' do + labels = { type: 'tcp', address: tcp_socket_address } + + expect(subject).to receive_message_chain(:unicorn_active_connections, :set).with(labels, 'active') + expect(subject).to receive_message_chain(:unicorn_queued_connections, :set).with(labels, 'queued') + + subject.sample + end + end + end + end + + describe '#start' do + context 'when enabled' do + before do + allow(subject).to receive(:enabled?).and_return(true) + end + + it 'creates new thread' do + expect(Thread).to receive(:new) + + subject.start + end + end + + context 'when disabled' do + before do + allow(subject).to receive(:enabled?).and_return(false) + end + + it "doesn't create new thread" do + expect(Thread).not_to receive(:new) + + subject.start + end + end + end +end diff --git a/spec/lib/gitlab/popen_spec.rb b/spec/lib/gitlab/popen_spec.rb index 4ae216d55b0..af50ecdb2ab 100644 --- a/spec/lib/gitlab/popen_spec.rb +++ b/spec/lib/gitlab/popen_spec.rb @@ -32,6 +32,17 @@ describe 'Gitlab::Popen', lib: true, no_db: true do end end + context 'with custom options' do + let(:vars) { { 'foobar' => 123, 'PWD' => path } } + let(:options) { { chdir: path } } + + it 'calls popen3 with the provided environment variables' do + expect(Open3).to receive(:popen3).with(vars, 'ls', options) + + @output, @status = @klass.new.popen(%w(ls), path, { 'foobar' => 123 }) + end + end + context 'without a directory argument' do before do @output, @status = @klass.new.popen(%w(ls)) @@ -45,7 +56,7 @@ describe 'Gitlab::Popen', lib: true, no_db: true do before do @output, @status = @klass.new.popen(%w[cat]) { |stdin| stdin.write 'hello' } end - + it { expect(@status).to be_zero } it { expect(@output).to eq('hello') } end diff --git a/spec/lib/gitlab/regex_spec.rb b/spec/lib/gitlab/regex_spec.rb index 979f4fefcb6..51e2c3c38c6 100644 --- a/spec/lib/gitlab/regex_spec.rb +++ b/spec/lib/gitlab/regex_spec.rb @@ -14,12 +14,6 @@ describe Gitlab::Regex, lib: true do it { is_expected.not_to match('?gitlab') } end - describe '.file_name_regex' do - subject { described_class.file_name_regex } - - it { is_expected.to match('foo@bar') } - end - describe '.environment_slug_regex' do subject { described_class.environment_name_regex } diff --git a/spec/lib/gitlab/shell_spec.rb b/spec/lib/gitlab/shell_spec.rb index a97a0f8452b..5b1b8f9516a 100644 --- a/spec/lib/gitlab/shell_spec.rb +++ b/spec/lib/gitlab/shell_spec.rb @@ -4,6 +4,7 @@ require 'stringio' describe Gitlab::Shell, lib: true do let(:project) { double('Project', id: 7, path: 'diaspora') } let(:gitlab_shell) { Gitlab::Shell.new } + let(:popen_vars) { { 'GIT_TERMINAL_PROMPT' => ENV['GIT_TERMINAL_PROMPT'] } } before do allow(Project).to receive(:find).and_return(project) @@ -50,7 +51,7 @@ describe Gitlab::Shell, lib: true do describe '#add_key' do it 'removes trailing garbage' do allow(gitlab_shell).to receive(:gitlab_shell_keys_path).and_return(:gitlab_shell_keys_path) - expect(Gitlab::Utils).to receive(:system_silent).with( + expect(gitlab_shell).to receive(:gitlab_shell_fast_execute).with( [:gitlab_shell_keys_path, 'add-key', 'key-123', 'ssh-rsa foobar'] ) @@ -100,17 +101,91 @@ describe Gitlab::Shell, lib: true do allow(Gitlab.config.gitlab_shell).to receive(:git_timeout).and_return(800) end + describe '#add_repository' do + it 'returns true when the command succeeds' do + expect(Gitlab::Popen).to receive(:popen) + .with([projects_path, 'add-project', 'current/storage', 'project/path.git'], + nil, popen_vars).and_return([nil, 0]) + + expect(gitlab_shell.add_repository('current/storage', 'project/path')).to be true + end + + it 'returns false when the command fails' do + expect(Gitlab::Popen).to receive(:popen) + .with([projects_path, 'add-project', 'current/storage', 'project/path.git'], + nil, popen_vars).and_return(["error", 1]) + + expect(gitlab_shell.add_repository('current/storage', 'project/path')).to be false + end + end + + describe '#remove_repository' do + it 'returns true when the command succeeds' do + expect(Gitlab::Popen).to receive(:popen) + .with([projects_path, 'rm-project', 'current/storage', 'project/path.git'], + nil, popen_vars).and_return([nil, 0]) + + expect(gitlab_shell.remove_repository('current/storage', 'project/path')).to be true + end + + it 'returns false when the command fails' do + expect(Gitlab::Popen).to receive(:popen) + .with([projects_path, 'rm-project', 'current/storage', 'project/path.git'], + nil, popen_vars).and_return(["error", 1]) + + expect(gitlab_shell.remove_repository('current/storage', 'project/path')).to be false + end + end + + describe '#mv_repository' do + it 'returns true when the command succeeds' do + expect(Gitlab::Popen).to receive(:popen) + .with([projects_path, 'mv-project', 'current/storage', 'project/path.git', 'project/newpath.git'], + nil, popen_vars).and_return([nil, 0]) + + expect(gitlab_shell.mv_repository('current/storage', 'project/path', 'project/newpath')).to be true + end + + it 'returns false when the command fails' do + expect(Gitlab::Popen).to receive(:popen) + .with([projects_path, 'mv-project', 'current/storage', 'project/path.git', 'project/newpath.git'], + nil, popen_vars).and_return(["error", 1]) + + expect(gitlab_shell.mv_repository('current/storage', 'project/path', 'project/newpath')).to be false + end + end + + describe '#fork_repository' do + it 'returns true when the command succeeds' do + expect(Gitlab::Popen).to receive(:popen) + .with([projects_path, 'fork-project', 'current/storage', 'project/path.git', 'new/storage', 'new-namespace'], + nil, popen_vars).and_return([nil, 0]) + + expect(gitlab_shell.fork_repository('current/storage', 'project/path', 'new/storage', 'new-namespace')).to be true + end + + it 'return false when the command fails' do + expect(Gitlab::Popen).to receive(:popen) + .with([projects_path, 'fork-project', 'current/storage', 'project/path.git', 'new/storage', 'new-namespace'], + nil, popen_vars).and_return(["error", 1]) + + expect(gitlab_shell.fork_repository('current/storage', 'project/path', 'new/storage', 'new-namespace')).to be false + end + end + describe '#fetch_remote' do it 'returns true when the command succeeds' do expect(Gitlab::Popen).to receive(:popen) - .with([projects_path, 'fetch-remote', 'current/storage', 'project/path.git', 'new/storage', '800']).and_return([nil, 0]) + .with([projects_path, 'fetch-remote', 'current/storage', 'project/path.git', 'new/storage', '800'], + nil, popen_vars).and_return([nil, 0]) expect(gitlab_shell.fetch_remote('current/storage', 'project/path', 'new/storage')).to be true end it 'raises an exception when the command fails' do expect(Gitlab::Popen).to receive(:popen) - .with([projects_path, 'fetch-remote', 'current/storage', 'project/path.git', 'new/storage', '800']).and_return(["error", 1]) + .with([projects_path, 'fetch-remote', 'current/storage', 'project/path.git', 'new/storage', '800'], + nil, popen_vars).and_return(["error", 1]) expect { gitlab_shell.fetch_remote('current/storage', 'project/path', 'new/storage') }.to raise_error(Gitlab::Shell::Error, "error") end @@ -119,14 +194,16 @@ describe Gitlab::Shell, lib: true do describe '#import_repository' do it 'returns true when the command succeeds' do expect(Gitlab::Popen).to receive(:popen) - .with([projects_path, 'import-project', 'current/storage', 'project/path.git', 'https://gitlab.com/gitlab-org/gitlab-ce.git', "800"]).and_return([nil, 0]) + .with([projects_path, 'import-project', 'current/storage', 'project/path.git', 'https://gitlab.com/gitlab-org/gitlab-ce.git', "800"], + nil, popen_vars).and_return([nil, 0]) expect(gitlab_shell.import_repository('current/storage', 'project/path', 'https://gitlab.com/gitlab-org/gitlab-ce.git')).to be true end it 'raises an exception when the command fails' do expect(Gitlab::Popen).to receive(:popen) - .with([projects_path, 'import-project', 'current/storage', 'project/path.git', 'https://gitlab.com/gitlab-org/gitlab-ce.git', "800"]).and_return(["error", 1]) + .with([projects_path, 'import-project', 'current/storage', 'project/path.git', 'https://gitlab.com/gitlab-org/gitlab-ce.git', "800"], + nil, popen_vars).and_return(["error", 1]) expect { gitlab_shell.import_repository('current/storage', 'project/path', 'https://gitlab.com/gitlab-org/gitlab-ce.git') }.to raise_error(Gitlab::Shell::Error, "error") end diff --git a/spec/lib/gitlab/sql/glob_spec.rb b/spec/lib/gitlab/sql/glob_spec.rb new file mode 100644 index 00000000000..451c583310d --- /dev/null +++ b/spec/lib/gitlab/sql/glob_spec.rb @@ -0,0 +1,53 @@ +require 'spec_helper' + +describe Gitlab::SQL::Glob, lib: true do + describe '.to_like' do + it 'matches * as %' do + expect(glob('apple', '*')).to be(true) + expect(glob('apple', 'app*')).to be(true) + expect(glob('apple', 'apple*')).to be(true) + expect(glob('apple', '*pple')).to be(true) + expect(glob('apple', 'ap*le')).to be(true) + + expect(glob('apple', '*a')).to be(false) + expect(glob('apple', 'app*a')).to be(false) + expect(glob('apple', 'ap*l')).to be(false) + end + + it 'matches % literally' do + expect(glob('100%', '100%')).to be(true) + + expect(glob('100%', '%')).to be(false) + end + + it 'matches _ literally' do + expect(glob('^_^', '^_^')).to be(true) + + expect(glob('^A^', '^_^')).to be(false) + end + end + + def glob(string, pattern) + match(string, subject.to_like(quote(pattern))) + end + + def match(string, pattern) + value = query("SELECT #{quote(string)} LIKE #{pattern}") + .rows.flatten.first + + case value + when 't', 1 + true + else + false + end + end + + def query(sql) + ActiveRecord::Base.connection.select_all(sql) + end + + def quote(string) + ActiveRecord::Base.connection.quote(string) + end +end diff --git a/spec/mailers/notify_spec.rb b/spec/mailers/notify_spec.rb index 980b24370d0..683e893968b 100644 --- a/spec/mailers/notify_spec.rb +++ b/spec/mailers/notify_spec.rb @@ -52,7 +52,7 @@ describe Notify do it 'has the correct subject and body' do aggregate_failures do is_expected.to have_referable_subject(issue) - is_expected.to have_body_text(namespace_project_issue_path(project.namespace, project, issue)) + is_expected.to have_body_text(project_issue_path(project, issue)) end end @@ -99,7 +99,7 @@ describe Notify do is_expected.to have_referable_subject(issue, reply: true) is_expected.to have_html_escaped_body_text(previous_assignee.name) is_expected.to have_html_escaped_body_text(assignee.name) - is_expected.to have_body_text(namespace_project_issue_path(project.namespace, project, issue)) + is_expected.to have_body_text(project_issue_path(project, issue)) end end end @@ -125,7 +125,7 @@ describe Notify do aggregate_failures do is_expected.to have_referable_subject(issue, reply: true) is_expected.to have_body_text('foo, bar, and baz') - is_expected.to have_body_text(namespace_project_issue_path(project.namespace, project, issue)) + is_expected.to have_body_text(project_issue_path(project, issue)) end end @@ -165,7 +165,7 @@ describe Notify do is_expected.to have_referable_subject(issue, reply: true) is_expected.to have_body_text(status) is_expected.to have_html_escaped_body_text(current_user.name) - is_expected.to have_body_text(namespace_project_issue_path project.namespace, project, issue) + is_expected.to have_body_text(project_issue_path project, issue) end end end @@ -185,13 +185,12 @@ describe Notify do end it 'has the correct subject and body' do - new_issue_url = namespace_project_issue_path(new_issue.project.namespace, - new_issue.project, new_issue) + new_issue_url = project_issue_path(new_issue.project, new_issue) aggregate_failures do is_expected.to have_referable_subject(issue, reply: true) is_expected.to have_body_text(new_issue_url) - is_expected.to have_body_text(namespace_project_issue_path(project.namespace, project, issue)) + is_expected.to have_body_text(project_issue_path(project, issue)) end end end @@ -216,7 +215,7 @@ describe Notify do it 'has the correct subject and body' do aggregate_failures do is_expected.to have_referable_subject(merge_request) - is_expected.to have_body_text(namespace_project_merge_request_path(project.namespace, project, merge_request)) + is_expected.to have_body_text(project_merge_request_path(project, merge_request)) is_expected.to have_body_text(merge_request.source_branch) is_expected.to have_body_text(merge_request.target_branch) end @@ -265,7 +264,7 @@ describe Notify do aggregate_failures do is_expected.to have_referable_subject(merge_request, reply: true) is_expected.to have_html_escaped_body_text(previous_assignee.name) - is_expected.to have_body_text(namespace_project_merge_request_path(project.namespace, project, merge_request)) + is_expected.to have_body_text(project_merge_request_path(project, merge_request)) is_expected.to have_html_escaped_body_text(assignee.name) end end @@ -291,7 +290,7 @@ describe Notify do it 'has the correct subject and body' do is_expected.to have_referable_subject(merge_request, reply: true) is_expected.to have_body_text('foo, bar, and baz') - is_expected.to have_body_text(namespace_project_merge_request_path(project.namespace, project, merge_request)) + is_expected.to have_body_text(project_merge_request_path(project, merge_request)) end end @@ -316,7 +315,7 @@ describe Notify do is_expected.to have_referable_subject(merge_request, reply: true) is_expected.to have_body_text(status) is_expected.to have_html_escaped_body_text(current_user.name) - is_expected.to have_body_text(namespace_project_merge_request_path(project.namespace, project, merge_request)) + is_expected.to have_body_text(project_merge_request_path(project, merge_request)) end end end @@ -341,7 +340,7 @@ describe Notify do aggregate_failures do is_expected.to have_referable_subject(merge_request, reply: true) is_expected.to have_body_text('merged') - is_expected.to have_body_text(namespace_project_merge_request_path(project.namespace, project, merge_request)) + is_expected.to have_body_text(project_merge_request_path(project, merge_request)) end end end @@ -390,7 +389,7 @@ describe Notify do is_expected.to have_subject "Request to join the #{project.name_with_namespace} project" is_expected.to have_html_escaped_body_text project.name_with_namespace - is_expected.to have_body_text namespace_project_project_members_url(project.namespace, project) + is_expected.to have_body_text project_project_members_url(project) is_expected.to have_body_text project_member.human_access end end @@ -417,7 +416,7 @@ describe Notify do is_expected.to have_subject "Request to join the #{project.name_with_namespace} project" is_expected.to have_html_escaped_body_text project.name_with_namespace - is_expected.to have_body_text namespace_project_project_members_url(project.namespace, project) + is_expected.to have_body_text project_project_members_url(project) is_expected.to have_body_text project_member.human_access end end @@ -609,7 +608,7 @@ describe Notify do describe 'on a merge request' do let(:merge_request) { create(:merge_request, source_project: project, target_project: project) } - let(:note_on_merge_request_path) { namespace_project_merge_request_path(project.namespace, project, merge_request, anchor: "note_#{note.id}") } + let(:note_on_merge_request_path) { project_merge_request_path(project, merge_request, anchor: "note_#{note.id}") } before do allow(note).to receive(:noteable).and_return(merge_request) @@ -634,7 +633,7 @@ describe Notify do describe 'on an issue' do let(:issue) { create(:issue, project: project) } - let(:note_on_issue_path) { namespace_project_issue_path(project.namespace, project, issue, anchor: "note_#{note.id}") } + let(:note_on_issue_path) { project_issue_path(project, issue, anchor: "note_#{note.id}") } before do allow(note).to receive(:noteable).and_return(issue) @@ -725,7 +724,7 @@ describe Notify do describe 'on a merge request' do let(:merge_request) { create(:merge_request, source_project: project, target_project: project) } let(:note) { create(:discussion_note_on_merge_request, noteable: merge_request, project: project, author: note_author) } - let(:note_on_merge_request_path) { namespace_project_merge_request_path(project.namespace, project, merge_request, anchor: "note_#{note.id}") } + let(:note_on_merge_request_path) { project_merge_request_path(project, merge_request, anchor: "note_#{note.id}") } before do allow(note).to receive(:noteable).and_return(merge_request) @@ -752,7 +751,7 @@ describe Notify do describe 'on an issue' do let(:issue) { create(:issue, project: project) } let(:note) { create(:discussion_note_on_issue, noteable: issue, project: project, author: note_author) } - let(:note_on_issue_path) { namespace_project_issue_path(project.namespace, project, issue, anchor: "note_#{note.id}") } + let(:note_on_issue_path) { project_issue_path(project, issue, anchor: "note_#{note.id}") } before do allow(note).to receive(:noteable).and_return(issue) @@ -1022,7 +1021,7 @@ describe Notify do describe 'email on push for a created branch' do let(:example_site_path) { root_path } let(:user) { create(:user) } - let(:tree_path) { namespace_project_tree_path(project.namespace, project, "empty-branch") } + let(:tree_path) { project_tree_path(project, "empty-branch") } subject { described_class.repository_push_email(project.id, author_id: user.id, ref: 'refs/heads/empty-branch', action: :create) } @@ -1048,7 +1047,7 @@ describe Notify do describe 'email on push for a created tag' do let(:example_site_path) { root_path } let(:user) { create(:user) } - let(:tree_path) { namespace_project_tree_path(project.namespace, project, "v1.0") } + let(:tree_path) { project_tree_path(project, "v1.0") } subject { described_class.repository_push_email(project.id, author_id: user.id, ref: 'refs/tags/v1.0', action: :create) } @@ -1122,7 +1121,7 @@ describe Notify do let(:raw_compare) { Gitlab::Git::Compare.new(project.repository.raw_repository, sample_image_commit.id, sample_commit.id) } let(:compare) { Compare.decorate(raw_compare, project) } let(:commits) { compare.commits } - let(:diff_path) { namespace_project_compare_path(project.namespace, project, from: Commit.new(compare.base, project), to: Commit.new(compare.head, project)) } + let(:diff_path) { project_compare_path(project, from: Commit.new(compare.base, project), to: Commit.new(compare.head, project)) } let(:send_from_committer_email) { false } let(:diff_refs) { Gitlab::Diff::DiffRefs.new(base_sha: project.merge_base_commit(sample_image_commit.id, sample_commit.id).id, head_sha: sample_commit.id) } @@ -1216,7 +1215,7 @@ describe Notify do let(:raw_compare) { Gitlab::Git::Compare.new(project.repository.raw_repository, sample_commit.parent_id, sample_commit.id) } let(:compare) { Compare.decorate(raw_compare, project) } let(:commits) { compare.commits } - let(:diff_path) { namespace_project_commit_path(project.namespace, project, commits.first) } + let(:diff_path) { project_commit_path(project, commits.first) } let(:diff_refs) { Gitlab::Diff::DiffRefs.new(base_sha: project.merge_base_commit(sample_image_commit.id, sample_commit.id).id, head_sha: sample_commit.id) } subject { described_class.repository_push_email(project.id, author_id: user.id, ref: 'refs/heads/master', action: :push, compare: compare, diff_refs: diff_refs) } diff --git a/spec/migrations/rename_duplicated_variable_key_spec.rb b/spec/migrations/rename_duplicated_variable_key_spec.rb new file mode 100644 index 00000000000..11096564dfa --- /dev/null +++ b/spec/migrations/rename_duplicated_variable_key_spec.rb @@ -0,0 +1,34 @@ +require 'spec_helper' +require Rails.root.join('db', 'migrate', '20170622135451_rename_duplicated_variable_key.rb') + +describe RenameDuplicatedVariableKey, :migration do + let(:variables) { table(:ci_variables) } + let(:projects) { table(:projects) } + + before do + projects.create!(id: 1) + variables.create!(id: 1, key: 'key1', project_id: 1) + variables.create!(id: 2, key: 'key2', project_id: 1) + variables.create!(id: 3, key: 'keyX', project_id: 1) + variables.create!(id: 4, key: 'keyX', project_id: 1) + variables.create!(id: 5, key: 'keyY', project_id: 1) + variables.create!(id: 6, key: 'keyX', project_id: 1) + variables.create!(id: 7, key: 'key7', project_id: 1) + variables.create!(id: 8, key: 'keyY', project_id: 1) + end + + it 'correctly remove duplicated records with smaller id' do + migrate! + + expect(variables.pluck(:id, :key)).to contain_exactly( + [1, 'key1'], + [2, 'key2'], + [3, 'keyX_3'], + [4, 'keyX_4'], + [5, 'keyY_5'], + [6, 'keyX'], + [7, 'key7'], + [8, 'keyY'] + ) + end +end diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb index 488697f74eb..2b10791ad6d 100644 --- a/spec/models/ci/build_spec.rb +++ b/spec/models/ci/build_spec.rb @@ -998,13 +998,17 @@ describe Ci::Build, :models do describe '#ref_slug' do { - 'master' => 'master', - '1-foo' => '1-foo', - 'fix/1-foo' => 'fix-1-foo', - 'fix-1-foo' => 'fix-1-foo', - 'a' * 63 => 'a' * 63, - 'a' * 64 => 'a' * 63, - 'FOO' => 'foo' + 'master' => 'master', + '1-foo' => '1-foo', + 'fix/1-foo' => 'fix-1-foo', + 'fix-1-foo' => 'fix-1-foo', + 'a' * 63 => 'a' * 63, + 'a' * 64 => 'a' * 63, + 'FOO' => 'foo', + '-' + 'a' * 61 + '-' => 'a' * 61, + '-' + 'a' * 62 + '-' => 'a' * 62, + '-' + 'a' * 63 + '-' => 'a' * 62, + 'a' * 62 + ' ' => 'a' * 62 }.each do |ref, slug| it "transforms #{ref} to #{slug}" do build.ref = ref @@ -1179,6 +1183,7 @@ describe Ci::Build, :models do { key: 'CI_PROJECT_NAMESPACE', value: project.namespace.full_path, public: true }, { key: 'CI_PROJECT_URL', value: project.web_url, public: true }, { key: 'CI_PIPELINE_ID', value: pipeline.id.to_s, public: true }, + { key: 'CI_CONFIG_PATH', value: pipeline.ci_yaml_file_path, public: true }, { key: 'CI_REGISTRY_USER', value: 'gitlab-ci-token', public: true }, { key: 'CI_REGISTRY_PASSWORD', value: build.token, public: false }, { key: 'CI_REPOSITORY_URL', value: build.repo_url, public: false } @@ -1469,6 +1474,16 @@ describe Ci::Build, :models do it { is_expected.to include(deployment_variable) } end + context 'when project has custom CI config path' do + let(:ci_config_path) { { key: 'CI_CONFIG_PATH', value: 'custom', public: true } } + + before do + project.update(ci_config_path: 'custom') + end + + it { is_expected.to include(ci_config_path) } + end + context 'returns variables in valid order' do let(:build_pre_var) { { key: 'build', value: 'value' } } let(:project_pre_var) { { key: 'project', value: 'value' } } @@ -1481,9 +1496,10 @@ describe Ci::Build, :models do 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).with(build.ref) do - [create(:ci_variable, key: 'secret', value: 'value')] - end + allow(project).to receive(:secret_variables_for) + .with(ref: 'master', environment: nil) do + [create(:ci_variable, key: 'secret', value: 'value')] + end end it do diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb index 55d85a6e228..ba0696fa210 100644 --- a/spec/models/ci/pipeline_spec.rb +++ b/spec/models/ci/pipeline_spec.rb @@ -748,6 +748,39 @@ describe Ci::Pipeline, models: true do end end + describe '#ci_yaml_file_path' do + subject { pipeline.ci_yaml_file_path } + + it 'returns the path from project' do + allow(pipeline.project).to receive(:ci_config_path) { 'custom/path' } + + is_expected.to eq('custom/path') + end + + it 'returns default when custom path is nil' do + allow(pipeline.project).to receive(:ci_config_path) { nil } + + is_expected.to eq('.gitlab-ci.yml') + end + + it 'returns default when custom path is empty' do + allow(pipeline.project).to receive(:ci_config_path) { '' } + + is_expected.to eq('.gitlab-ci.yml') + end + end + + describe '#ci_yaml_file' do + it 'reports error if the file is not found' do + allow(pipeline.project).to receive(:ci_config_path) { 'custom' } + + pipeline.ci_yaml_file + + expect(pipeline.yaml_errors) + .to eq('Failed to load CI/CD config file at custom') + end + end + describe '#detailed_status' do subject { pipeline.detailed_status(user) } diff --git a/spec/models/ci/variable_spec.rb b/spec/models/ci/variable_spec.rb index 329682a0771..4ffbfa6c130 100644 --- a/spec/models/ci/variable_spec.rb +++ b/spec/models/ci/variable_spec.rb @@ -3,8 +3,12 @@ require 'spec_helper' describe Ci::Variable, models: true do subject { build(:ci_variable) } - it { is_expected.to include_module(HasVariable) } - it { is_expected.to validate_uniqueness_of(:key).scoped_to(:project_id) } + let(:secret_value) { 'secret' } + + describe 'validations' do + it { is_expected.to include_module(HasVariable) } + it { is_expected.to validate_uniqueness_of(:key).scoped_to(:project_id, :environment_scope) } + end describe '.unprotected' do subject { described_class.unprotected } diff --git a/spec/models/concerns/issuable_spec.rb b/spec/models/concerns/issuable_spec.rb index ac9303370ab..505039c9d88 100644 --- a/spec/models/concerns/issuable_spec.rb +++ b/spec/models/concerns/issuable_spec.rb @@ -155,7 +155,7 @@ describe Issuable do end describe "#sort" do - let(:project) { build_stubbed(:empty_project) } + let(:project) { create(:empty_project) } context "by milestone due date" do # Correct order is: diff --git a/spec/models/concerns/routable_spec.rb b/spec/models/concerns/routable_spec.rb index 65f05121b40..36aedd2f701 100644 --- a/spec/models/concerns/routable_spec.rb +++ b/spec/models/concerns/routable_spec.rb @@ -132,6 +132,19 @@ describe Group, 'Routable' do end end + describe '#expires_full_path_cache' do + context 'with RequestStore active', :request_store do + it 'expires the full_path cache' do + expect(group.full_path).to eq('foo') + + group.route.update(path: 'bar', name: 'bar') + group.expires_full_path_cache + + expect(group.full_path).to eq('bar') + end + end + end + describe '#full_name' do let(:group) { create(:group) } let(:nested_group) { create(:group, parent: group) } diff --git a/spec/models/concerns/sortable_spec.rb b/spec/models/concerns/sortable_spec.rb new file mode 100644 index 00000000000..d1e17c4f684 --- /dev/null +++ b/spec/models/concerns/sortable_spec.rb @@ -0,0 +1,21 @@ +require 'spec_helper' + +describe Sortable do + let(:relation) { Issue.all } + + describe '#where' do + it 'orders by id, descending' do + order_node = relation.where(iid: 1).order_values.first + expect(order_node).to be_a(Arel::Nodes::Descending) + expect(order_node.expr.name).to eq(:id) + end + end + + describe '#find_by' do + it 'does not order' do + expect(relation).to receive(:unscope).with(:order).and_call_original + + relation.find_by(iid: 1) + end + end +end diff --git a/spec/models/environment_spec.rb b/spec/models/environment_spec.rb index b0635c6a90a..0a2cd8c2957 100644 --- a/spec/models/environment_spec.rb +++ b/spec/models/environment_spec.rb @@ -120,28 +120,17 @@ describe Environment, models: true do let(:head_commit) { project.commit } let(:commit) { project.commit.parent } - context 'Gitaly find_ref_name feature disabled' do - it 'returns deployment id for the environment' do - expect(environment.first_deployment_for(commit)).to eq deployment1 - end + it 'returns deployment id for the environment' do + expect(environment.first_deployment_for(commit)).to eq deployment1 + end - it 'return nil when no deployment is found' do - expect(environment.first_deployment_for(head_commit)).to eq nil - end + it 'return nil when no deployment is found' do + expect(environment.first_deployment_for(head_commit)).to eq nil end - # TODO: Uncomment when feature is reenabled - # context 'Gitaly find_ref_name feature enabled' do - # before do - # allow(Gitlab::GitalyClient).to receive(:feature_enabled?).with(:find_ref_name).and_return(true) - # end - # - # it 'calls GitalyClient' do - # expect_any_instance_of(Gitlab::GitalyClient::Ref).to receive(:find_ref_name) - # - # environment.first_deployment_for(commit) - # end - # end + it 'returns a UTF-8 ref' do + expect(environment.first_deployment_for(commit).ref).to be_utf8 + end end describe '#environment_type' do diff --git a/spec/models/forked_project_link_spec.rb b/spec/models/forked_project_link_spec.rb index 6e8d43f988c..38fbdd2536a 100644 --- a/spec/models/forked_project_link_spec.rb +++ b/spec/models/forked_project_link_spec.rb @@ -2,53 +2,75 @@ require 'spec_helper' describe ForkedProjectLink, "add link on fork" do let(:project_from) { create(:project, :repository) } + let(:project_to) { fork_project(project_from, user) } let(:user) { create(:user) } let(:namespace) { user.namespace } before do - create(:project_member, :reporter, user: user, project: project_from) - @project_to = fork_project(project_from, user) + project_from.add_reporter(user) + end + + it 'project_from knows its forks' do + _ = project_to + + expect(project_from.forks.count).to eq(1) end it "project_to knows it is forked" do - expect(@project_to.forked?).to be_truthy + expect(project_to.forked?).to be_truthy end it "project knows who it is forked from" do - expect(@project_to.forked_from_project).to eq(project_from) + expect(project_to.forked_from_project).to eq(project_from) end -end -describe '#forked?' do - let(:forked_project_link) { build(:forked_project_link) } - let(:project_from) { create(:project, :repository) } - let(:project_to) { create(:project, forked_project_link: forked_project_link) } + context 'project_to is pending_delete' do + before do + project_to.update!(pending_delete: true) + end - before :each do - forked_project_link.forked_from_project = project_from - forked_project_link.forked_to_project = project_to - forked_project_link.save! + it { expect(project_from.forks.count).to eq(0) } end - it "project_to knows it is forked" do - expect(project_to.forked?).to be_truthy - end + context 'project_from is pending_delete' do + before do + project_from.update!(pending_delete: true) + end - it "project_from is not forked" do - expect(project_from.forked?).to be_falsey + it { expect(project_to.forked_from_project).to be_nil } end - it "project_to.destroy destroys fork_link" do - expect(forked_project_link).to receive(:destroy) - project_to.destroy + describe '#forked?' do + let(:project_to) { create(:project, forked_project_link: forked_project_link) } + let(:forked_project_link) { create(:forked_project_link) } + + before do + forked_project_link.forked_from_project = project_from + forked_project_link.forked_to_project = project_to + forked_project_link.save! + end + + it "project_to knows it is forked" do + expect(project_to.forked?).to be_truthy + end + + it "project_from is not forked" do + expect(project_from.forked?).to be_falsey + end + + it "project_to.destroy destroys fork_link" do + project_to.destroy + + expect(ForkedProjectLink.exists?(id: forked_project_link.id)).to eq(false) + end end -end -def fork_project(from_project, user) - shell = double('gitlab_shell', fork_repository: true) + def fork_project(from_project, user) + service = Projects::ForkService.new(from_project, user) + shell = double('gitlab_shell', fork_repository: true) - service = Projects::ForkService.new(from_project, user) - allow(service).to receive(:gitlab_shell).and_return(shell) + allow(service).to receive(:gitlab_shell).and_return(shell) - service.execute + service.execute + end end diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb index bb5273074a2..d91f1f1a11c 100644 --- a/spec/models/merge_request_spec.rb +++ b/spec/models/merge_request_spec.rb @@ -10,7 +10,7 @@ describe MergeRequest, models: true do it { is_expected.to belong_to(:source_project).class_name('Project') } it { is_expected.to belong_to(:merge_user).class_name("User") } it { is_expected.to belong_to(:assignee) } - it { is_expected.to have_many(:merge_request_diffs).dependent(:destroy) } + it { is_expected.to have_many(:merge_request_diffs) } end describe 'modules' do @@ -105,6 +105,22 @@ describe MergeRequest, models: true do end end + describe '#assignee_ids' do + it 'returns an array of the assigned user id' do + subject.assignee_id = 123 + + expect(subject.assignee_ids).to eq([123]) + end + end + + describe '#assignee_ids=' do + it 'sets assignee_id to the last id in the array' do + subject.assignee_ids = [123, 456] + + expect(subject.assignee_id).to eq(456) + end + end + describe '#assignee_or_author?' do let(:user) { create(:user) } diff --git a/spec/models/project_group_link_spec.rb b/spec/models/project_group_link_spec.rb index 4161b9158b1..d68d8b719cd 100644 --- a/spec/models/project_group_link_spec.rb +++ b/spec/models/project_group_link_spec.rb @@ -2,8 +2,8 @@ require 'spec_helper' describe ProjectGroupLink do describe "Associations" do - it { should belong_to(:group) } - it { should belong_to(:project) } + it { is_expected.to belong_to(:group) } + it { is_expected.to belong_to(:project) } end describe "Validation" do @@ -12,10 +12,10 @@ describe ProjectGroupLink do let(:project) { create(:project, group: group) } let!(:project_group_link) { create(:project_group_link, project: project) } - it { should validate_presence_of(:project_id) } - it { should validate_uniqueness_of(:group_id).scoped_to(:project_id).with_message(/already shared/) } - it { should validate_presence_of(:group) } - it { should validate_presence_of(:group_access) } + it { is_expected.to validate_presence_of(:project_id) } + it { is_expected.to validate_uniqueness_of(:group_id).scoped_to(:project_id).with_message(/already shared/) } + it { is_expected.to validate_presence_of(:group) } + it { is_expected.to validate_presence_of(:group_access) } it "doesn't allow a project to be shared with the group it is in" do project_group_link.group = group diff --git a/spec/models/project_services/external_wiki_service_spec.rb b/spec/models/project_services/external_wiki_service_spec.rb index 291fc645a1c..ef10df9e092 100644 --- a/spec/models/project_services/external_wiki_service_spec.rb +++ b/spec/models/project_services/external_wiki_service_spec.rb @@ -3,8 +3,8 @@ require 'spec_helper' describe ExternalWikiService, models: true do include ExternalWikiHelper describe "Associations" do - it { should belong_to :project } - it { should have_one :service_hook } + it { is_expected.to belong_to :project } + it { is_expected.to have_one :service_hook } end describe 'Validations' do diff --git a/spec/models/project_services/kubernetes_service_spec.rb b/spec/models/project_services/kubernetes_service_spec.rb index 858ad595dbf..5ba523a478a 100644 --- a/spec/models/project_services/kubernetes_service_spec.rb +++ b/spec/models/project_services/kubernetes_service_spec.rb @@ -129,7 +129,7 @@ describe KubernetesService, models: true, caching: true do it "returns the default namespace" do is_expected.to eq(service.send(:default_namespace)) end - + context 'when namespace is specified' do before do service.namespace = 'my-namespace' @@ -201,6 +201,22 @@ describe KubernetesService, models: true, caching: true do end describe '#predefined_variables' do + let(:kubeconfig) do + config = + YAML.load(File.read(expand_fixture_path('config/kubeconfig.yml'))) + + config.dig('users', 0, 'user')['token'] = + 'token' + + config.dig('clusters', 0, 'cluster')['certificate-authority-data'] = + Base64.encode64('CA PEM DATA') + + config.dig('contexts', 0, 'context')['namespace'] = + namespace + + YAML.dump(config) + end + before do subject.api_url = 'https://kube.domain.com' subject.token = 'token' @@ -208,32 +224,34 @@ describe KubernetesService, models: true, caching: true do subject.project = project end - context 'namespace is provided' do - before do - subject.namespace = 'my-project' - end - + shared_examples 'setting variables' do it 'sets the variables' do expect(subject.predefined_variables).to include( { key: 'KUBE_URL', value: 'https://kube.domain.com', public: true }, { key: 'KUBE_TOKEN', value: 'token', public: false }, - { key: 'KUBE_NAMESPACE', value: 'my-project', public: true }, + { key: 'KUBE_NAMESPACE', value: namespace, public: true }, + { key: 'KUBECONFIG', value: kubeconfig, public: false, file: true }, { key: 'KUBE_CA_PEM', value: 'CA PEM DATA', public: true }, { key: 'KUBE_CA_PEM_FILE', value: 'CA PEM DATA', public: true, file: true } ) end end - context 'no namespace provided' do - it 'sets the variables' do - expect(subject.predefined_variables).to include( - { key: 'KUBE_URL', value: 'https://kube.domain.com', public: true }, - { key: 'KUBE_TOKEN', value: 'token', public: false }, - { key: 'KUBE_CA_PEM', value: 'CA PEM DATA', public: true }, - { key: 'KUBE_CA_PEM_FILE', value: 'CA PEM DATA', public: true, file: true } - ) + context 'namespace is provided' do + let(:namespace) { 'my-project' } + + before do + subject.namespace = namespace end + it_behaves_like 'setting variables' + end + + context 'no namespace provided' do + let(:namespace) { subject.actual_namespace } + + it_behaves_like 'setting variables' + it 'sets the KUBE_NAMESPACE' do kube_namespace = subject.predefined_variables.find { |h| h[:key] == 'KUBE_NAMESPACE' } diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 1390848ff4a..99bfab70088 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -7,50 +7,50 @@ describe Project, models: true do it { is_expected.to belong_to(:creator).class_name('User') } it { is_expected.to have_many(:users) } it { is_expected.to have_many(:services) } - it { is_expected.to have_many(:events).dependent(:destroy) } - it { is_expected.to have_many(:merge_requests).dependent(:destroy) } - it { is_expected.to have_many(:issues).dependent(:destroy) } - it { is_expected.to have_many(:milestones).dependent(:destroy) } - it { is_expected.to have_many(:project_members).dependent(:destroy) } + it { is_expected.to have_many(:events) } + it { is_expected.to have_many(:merge_requests) } + it { is_expected.to have_many(:issues) } + it { is_expected.to have_many(:milestones) } + it { is_expected.to have_many(:project_members).dependent(:delete_all) } it { is_expected.to have_many(:users).through(:project_members) } - it { is_expected.to have_many(:requesters).dependent(:destroy) } - it { is_expected.to have_many(:notes).dependent(:destroy) } - it { is_expected.to have_many(:snippets).class_name('ProjectSnippet').dependent(:destroy) } - it { is_expected.to have_many(:deploy_keys_projects).dependent(:destroy) } + it { is_expected.to have_many(:requesters).dependent(:delete_all) } + it { is_expected.to have_many(:notes) } + it { is_expected.to have_many(:snippets).class_name('ProjectSnippet') } + it { is_expected.to have_many(:deploy_keys_projects) } it { is_expected.to have_many(:deploy_keys) } - it { is_expected.to have_many(:hooks).dependent(:destroy) } - it { is_expected.to have_many(:protected_branches).dependent(:destroy) } - it { is_expected.to have_one(:forked_project_link).dependent(:destroy) } - it { is_expected.to have_one(:slack_service).dependent(:destroy) } - it { is_expected.to have_one(:microsoft_teams_service).dependent(:destroy) } - it { is_expected.to have_one(:mattermost_service).dependent(:destroy) } - it { is_expected.to have_one(:pushover_service).dependent(:destroy) } - it { is_expected.to have_one(:asana_service).dependent(:destroy) } - it { is_expected.to have_many(:boards).dependent(:destroy) } - it { is_expected.to have_one(:campfire_service).dependent(:destroy) } - it { is_expected.to have_one(:drone_ci_service).dependent(:destroy) } - it { is_expected.to have_one(:emails_on_push_service).dependent(:destroy) } - it { is_expected.to have_one(:pipelines_email_service).dependent(:destroy) } - it { is_expected.to have_one(:irker_service).dependent(:destroy) } - it { is_expected.to have_one(:pivotaltracker_service).dependent(:destroy) } - it { is_expected.to have_one(:hipchat_service).dependent(:destroy) } - it { is_expected.to have_one(:flowdock_service).dependent(:destroy) } - it { is_expected.to have_one(:assembla_service).dependent(:destroy) } - it { is_expected.to have_one(:slack_slash_commands_service).dependent(:destroy) } - it { is_expected.to have_one(:mattermost_slash_commands_service).dependent(:destroy) } - it { is_expected.to have_one(:gemnasium_service).dependent(:destroy) } - it { is_expected.to have_one(:buildkite_service).dependent(:destroy) } - it { is_expected.to have_one(:bamboo_service).dependent(:destroy) } - it { is_expected.to have_one(:teamcity_service).dependent(:destroy) } - it { is_expected.to have_one(:jira_service).dependent(:destroy) } - it { is_expected.to have_one(:redmine_service).dependent(:destroy) } - it { is_expected.to have_one(:custom_issue_tracker_service).dependent(:destroy) } - it { is_expected.to have_one(:bugzilla_service).dependent(:destroy) } - it { is_expected.to have_one(:gitlab_issue_tracker_service).dependent(:destroy) } - it { is_expected.to have_one(:external_wiki_service).dependent(:destroy) } - it { is_expected.to have_one(:project_feature).dependent(:destroy) } - it { is_expected.to have_one(:statistics).class_name('ProjectStatistics').dependent(:delete) } - it { is_expected.to have_one(:import_data).class_name('ProjectImportData').dependent(:delete) } + it { is_expected.to have_many(:hooks) } + it { is_expected.to have_many(:protected_branches) } + it { is_expected.to have_one(:forked_project_link) } + it { is_expected.to have_one(:slack_service) } + it { is_expected.to have_one(:microsoft_teams_service) } + it { is_expected.to have_one(:mattermost_service) } + it { is_expected.to have_one(:pushover_service) } + it { is_expected.to have_one(:asana_service) } + it { is_expected.to have_many(:boards) } + it { is_expected.to have_one(:campfire_service) } + it { is_expected.to have_one(:drone_ci_service) } + it { is_expected.to have_one(:emails_on_push_service) } + it { is_expected.to have_one(:pipelines_email_service) } + it { is_expected.to have_one(:irker_service) } + it { is_expected.to have_one(:pivotaltracker_service) } + it { is_expected.to have_one(:hipchat_service) } + it { is_expected.to have_one(:flowdock_service) } + it { is_expected.to have_one(:assembla_service) } + it { is_expected.to have_one(:slack_slash_commands_service) } + it { is_expected.to have_one(:mattermost_slash_commands_service) } + it { is_expected.to have_one(:gemnasium_service) } + it { is_expected.to have_one(:buildkite_service) } + it { is_expected.to have_one(:bamboo_service) } + it { is_expected.to have_one(:teamcity_service) } + it { is_expected.to have_one(:jira_service) } + it { is_expected.to have_one(:redmine_service) } + it { is_expected.to have_one(:custom_issue_tracker_service) } + it { is_expected.to have_one(:bugzilla_service) } + it { is_expected.to have_one(:gitlab_issue_tracker_service) } + it { is_expected.to have_one(:external_wiki_service) } + it { is_expected.to have_one(:project_feature) } + it { is_expected.to have_one(:statistics).class_name('ProjectStatistics') } + it { is_expected.to have_one(:import_data).class_name('ProjectImportData') } it { is_expected.to have_one(:last_event).class_name('Event') } it { is_expected.to have_one(:forked_from_project).through(:forked_project_link) } it { is_expected.to have_many(:commit_statuses) } @@ -62,18 +62,18 @@ describe Project, models: true do it { is_expected.to have_many(:variables) } it { is_expected.to have_many(:triggers) } it { is_expected.to have_many(:pages_domains) } - it { is_expected.to have_many(:labels).class_name('ProjectLabel').dependent(:destroy) } - it { is_expected.to have_many(:users_star_projects).dependent(:destroy) } - it { is_expected.to have_many(:environments).dependent(:destroy) } - it { is_expected.to have_many(:deployments).dependent(:destroy) } - it { is_expected.to have_many(:todos).dependent(:destroy) } - it { is_expected.to have_many(:releases).dependent(:destroy) } - it { is_expected.to have_many(:lfs_objects_projects).dependent(:destroy) } - it { is_expected.to have_many(:project_group_links).dependent(:destroy) } - it { is_expected.to have_many(:notification_settings).dependent(:destroy) } + it { is_expected.to have_many(:labels).class_name('ProjectLabel') } + it { is_expected.to have_many(:users_star_projects) } + it { is_expected.to have_many(:environments) } + it { is_expected.to have_many(:deployments) } + it { is_expected.to have_many(:todos) } + it { is_expected.to have_many(:releases) } + it { is_expected.to have_many(:lfs_objects_projects) } + it { is_expected.to have_many(:project_group_links) } + it { is_expected.to have_many(:notification_settings).dependent(:delete_all) } it { is_expected.to have_many(:forks).through(:forked_project_links) } it { is_expected.to have_many(:uploads).dependent(:destroy) } - it { is_expected.to have_many(:pipeline_schedules).dependent(:destroy) } + it { is_expected.to have_many(:pipeline_schedules) } context 'after initialized' do it "has a project_feature" do @@ -143,6 +143,10 @@ describe Project, models: true do it { is_expected.to validate_length_of(:description).is_at_most(2000) } + it { is_expected.to validate_length_of(:ci_config_path).is_at_most(255) } + it { is_expected.to allow_value('').for(:ci_config_path) } + it { is_expected.not_to allow_value('test/../foo').for(:ci_config_path) } + it { is_expected.to validate_presence_of(:creator) } it { is_expected.to validate_presence_of(:namespace) } @@ -823,13 +827,13 @@ describe Project, models: true do let(:avatar_path) { "/#{project.full_path}/avatar" } - it { should eq "http://#{Gitlab.config.gitlab.host}#{avatar_path}" } + it { is_expected.to eq "http://#{Gitlab.config.gitlab.host}#{avatar_path}" } end context 'when git repo is empty' do let(:project) { create(:empty_project) } - it { should eq nil } + it { is_expected.to eq nil } end end @@ -1216,6 +1220,8 @@ describe Project, models: true do expect(project).to receive(:expire_caches_before_rename) + expect(project).to receive(:expires_full_path_cache) + project.rename_repo end @@ -1344,7 +1350,7 @@ describe Project, models: true do .with(project.repository_storage_path, project.path_with_namespace) .and_return(true) - expect(project).to receive(:create_repository) + expect(project).to receive(:create_repository).with(force: true) project.ensure_repository end @@ -1357,6 +1363,19 @@ describe Project, models: true do project.ensure_repository end + + it 'creates the repository if it is a fork' do + expect(project).to receive(:forked?).and_return(true) + + allow(project).to receive(:repository_exists?) + .and_return(false) + + expect(shell).to receive(:add_repository) + .with(project.repository_storage_path, project.path_with_namespace) + .and_return(true) + + project.ensure_repository + end end describe '#user_can_push_to_empty_repo?' do @@ -1489,6 +1508,28 @@ describe Project, models: true do end end + describe '#ci_config_path=' do + let(:project) { create(:empty_project) } + + it 'sets nil' do + project.update!(ci_config_path: nil) + + expect(project.ci_config_path).to be_nil + end + + it 'sets a string' do + project.update!(ci_config_path: 'foo/.gitlab_ci.yml') + + expect(project.ci_config_path).to eq('foo/.gitlab_ci.yml') + end + + it 'sets a string but removes all leading slashes and null characters' do + project.update!(ci_config_path: "///f\0oo/\0/.gitlab_ci.yml") + + expect(project.ci_config_path).to eq('foo//.gitlab_ci.yml') + end + end + describe 'Project import job' do let(:project) { create(:empty_project, import_url: generate(:url)) } @@ -1834,7 +1875,12 @@ describe Project, models: true do create(:ci_variable, :protected, value: 'protected', project: project) end - subject { project.secret_variables_for('ref') } + subject { project.secret_variables_for(ref: 'ref') } + + before do + stub_application_setting( + default_branch_protection: Gitlab::Access::PROTECTION_NONE) + end shared_examples 'ref is protected' do it 'contains all the variables' do @@ -1843,11 +1889,6 @@ describe Project, models: true do end context 'when the ref is not protected' do - before do - stub_application_setting( - default_branch_protection: Gitlab::Access::PROTECTION_NONE) - end - it 'contains only the secret variables' do is_expected.to contain_exactly(secret_variable) end @@ -2158,4 +2199,21 @@ describe Project, models: true do end end end + + describe '#remove_private_deploy_keys' do + it 'removes the private deploy keys of a project' do + project = create(:empty_project) + + private_key = create(:deploy_key, public: false) + public_key = create(:deploy_key, public: true) + + create(:deploy_keys_project, deploy_key: private_key, project: project) + create(:deploy_keys_project, deploy_key: public_key, project: project) + + project.remove_private_deploy_keys + + expect(project.deploy_keys.where(public: false).any?).to eq(false) + expect(project.deploy_keys.where(public: true).any?).to eq(true) + end + end end diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb index c69f0a495db..af305e9b234 100644 --- a/spec/models/repository_spec.rb +++ b/spec/models/repository_spec.rb @@ -347,6 +347,17 @@ describe Repository, models: true do expect(blob.data).to eq('Changelog!') end + it 'creates new file and dir when file_path has a forward slash' do + expect do + repository.create_file(user, 'new_dir/new_file.txt', 'File!', + message: 'Create new_file with new_dir', + branch_name: 'master') + end.to change { repository.commits('master').count }.by(1) + + expect(repository.tree('master', 'new_dir').path).to eq('new_dir') + expect(repository.blob_at('master', 'new_dir/new_file.txt').data).to eq('File!') + end + it 'respects the autocrlf setting' do repository.create_file(user, 'hello.txt', "Hello,\r\nWorld", message: 'Add hello world', diff --git a/spec/policies/global_policy_spec.rb b/spec/policies/global_policy_spec.rb new file mode 100644 index 00000000000..bb0fa0c0e9c --- /dev/null +++ b/spec/policies/global_policy_spec.rb @@ -0,0 +1,34 @@ +require 'spec_helper' + +describe GlobalPolicy, models: true do + let(:current_user) { create(:user) } + let(:user) { create(:user) } + + subject { GlobalPolicy.new(current_user, [user]) } + + describe "reading the list of users" do + context "for a logged in user" do + it { is_expected.to be_allowed(:read_users_list) } + end + + context "for an anonymous user" do + let(:current_user) { nil } + + context "when the public level is restricted" do + before do + stub_application_setting(restricted_visibility_levels: [Gitlab::VisibilityLevel::PUBLIC]) + end + + it { is_expected.not_to be_allowed(:read_users_list) } + end + + context "when the public level is not restricted" do + before do + stub_application_setting(restricted_visibility_levels: []) + end + + it { is_expected.to be_allowed(:read_users_list) } + end + end + end +end diff --git a/spec/presenters/ci/build_presenter_spec.rb b/spec/presenters/ci/build_presenter_spec.rb index 518e97d17a1..f05d5c7fce5 100644 --- a/spec/presenters/ci/build_presenter_spec.rb +++ b/spec/presenters/ci/build_presenter_spec.rb @@ -85,7 +85,7 @@ describe Ci::BuildPresenter do describe 'quack like a Ci::Build permission-wise' do context 'user is not allowed' do - let(:project) { build_stubbed(:empty_project, public_builds: false) } + let(:project) { create(:empty_project, public_builds: false) } it 'returns false' do expect(presenter.can?(nil, :read_build)).to be_falsy @@ -93,7 +93,7 @@ describe Ci::BuildPresenter do end context 'user is allowed' do - let(:project) { build_stubbed(:empty_project, :public) } + let(:project) { create(:empty_project, :public) } it 'returns true' do expect(presenter.can?(nil, :read_build)).to be_truthy diff --git a/spec/requests/api/commit_statuses_spec.rb b/spec/requests/api/commit_statuses_spec.rb index cdb60fc0d1a..8b62aa268d9 100644 --- a/spec/requests/api/commit_statuses_spec.rb +++ b/spec/requests/api/commit_statuses_spec.rb @@ -237,6 +237,28 @@ describe API::CommitStatuses do end end + context 'when retrying a commit status' do + before do + post api(post_url, developer), + { state: 'failed', name: 'test', ref: 'master' } + + post api(post_url, developer), + { state: 'success', name: 'test', ref: 'master' } + end + + it 'correctly posts a new commit status' do + expect(response).to have_http_status(201) + expect(json_response['sha']).to eq(commit.id) + expect(json_response['status']).to eq('success') + end + + it 'retries a commit status' do + expect(CommitStatus.count).to eq 2 + expect(CommitStatus.first).to be_retried + expect(CommitStatus.last.pipeline).to be_success + end + end + context 'when status is invalid' do before do post api(post_url, developer), state: 'invalid' diff --git a/spec/requests/api/helpers_spec.rb b/spec/requests/api/helpers_spec.rb index 191c60aba31..25ec44fa036 100644 --- a/spec/requests/api/helpers_spec.rb +++ b/spec/requests/api/helpers_spec.rb @@ -14,6 +14,10 @@ describe API::Helpers do let(:request) { Rack::Request.new(env) } let(:header) { } + before do + allow_any_instance_of(self.class).to receive(:options).and_return({}) + end + def set_env(user_or_token, identifier) clear_env clear_param @@ -167,7 +171,6 @@ describe API::Helpers do it "returns nil for a token without the appropriate scope" do personal_access_token = create(:personal_access_token, user: user, scopes: ['read_user']) env[API::APIGuard::PRIVATE_TOKEN_HEADER] = personal_access_token.token - allow_access_with_scope('write_user') expect(current_user).to be_nil end diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb index 14dec3d45b1..ee25bd1deb1 100644 --- a/spec/requests/api/projects_spec.rb +++ b/spec/requests/api/projects_spec.rb @@ -347,7 +347,8 @@ describe API::Projects do wiki_enabled: false, only_allow_merge_if_pipeline_succeeds: false, request_access_enabled: true, - only_allow_merge_if_all_discussions_are_resolved: false + only_allow_merge_if_all_discussions_are_resolved: false, + ci_config_path: 'a/custom/path' }) post api('/projects', user), project @@ -475,6 +476,26 @@ describe API::Projects do end end + describe 'GET /users/:user_id/projects/' do + let!(:public_project) { create(:empty_project, :public, name: 'public_project', creator_id: user4.id, namespace: user4.namespace) } + + it 'returns error when user not found' do + get api('/users/9999/projects/') + + expect(response).to have_http_status(404) + expect(json_response['message']).to eq('404 User Not Found') + end + + it 'returns projects filtered by user' do + get api("/users/#{user4.id}/projects/", user) + + expect(response).to have_http_status(200) + expect(response).to include_pagination_headers + expect(json_response).to be_an Array + expect(json_response.map { |project| project['id'] }).to contain_exactly(public_project.id) + end + end + describe 'POST /projects/user/:id' do before do expect(project).to be_persisted @@ -653,6 +674,7 @@ describe API::Projects do expect(json_response['star_count']).to be_present expect(json_response['forks_count']).to be_present expect(json_response['public_jobs']).to be_present + expect(json_response['ci_config_path']).to be_nil expect(json_response['shared_with_groups']).to be_an Array expect(json_response['shared_with_groups'].length).to eq(1) expect(json_response['shared_with_groups'][0]['group_id']).to eq(group.id) diff --git a/spec/requests/api/runner_spec.rb b/spec/requests/api/runner_spec.rb index 339a57a1f20..ca5d98c78ef 100644 --- a/spec/requests/api/runner_spec.rb +++ b/spec/requests/api/runner_spec.rb @@ -351,7 +351,8 @@ describe API::Runner do let(:expected_cache) do [{ 'key' => 'cache_key', 'untracked' => false, - 'paths' => ['vendor/*'] }] + 'paths' => ['vendor/*'], + 'policy' => 'pull-push' }] end it 'picks a job' do diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb index c0174b304c8..70b94a09e6b 100644 --- a/spec/requests/api/users_spec.rb +++ b/spec/requests/api/users_spec.rb @@ -13,9 +13,40 @@ describe API::Users do describe 'GET /users' do context "when unauthenticated" do - it "returns authentication error" do + it "returns authorization error when the `username` parameter is not passed" do get api("/users") - expect(response).to have_http_status(401) + + expect(response).to have_http_status(403) + end + + it "returns the user when a valid `username` parameter is passed" do + user = create(:user) + + get api("/users"), username: user.username + + expect(response).to have_http_status(200) + expect(json_response).to be_an Array + expect(json_response.size).to eq(1) + expect(json_response[0]['id']).to eq(user.id) + expect(json_response[0]['username']).to eq(user.username) + end + + it "returns authorization error when the `username` parameter refers to an inaccessible user" do + user = create(:user) + + stub_application_setting(restricted_visibility_levels: [Gitlab::VisibilityLevel::PUBLIC]) + + get api("/users"), username: user.username + + expect(response).to have_http_status(403) + end + + it "returns an empty response when an invalid `username` parameter is passed" do + get api("/users"), username: 'invalid' + + expect(response).to have_http_status(200) + expect(json_response).to be_an Array + expect(json_response.size).to eq(0) end end @@ -138,6 +169,7 @@ describe API::Users do describe "GET /users/:id" do it "returns a user by id" do get api("/users/#{user.id}", user) + expect(response).to have_http_status(200) expect(json_response['username']).to eq(user.username) end @@ -148,9 +180,22 @@ describe API::Users do expect(json_response['is_admin']).to be_nil end - it "returns a 401 if unauthenticated" do - get api("/users/9998") - expect(response).to have_http_status(401) + context 'for an anonymous user' do + it "returns a user by id" do + get api("/users/#{user.id}") + + expect(response).to have_http_status(200) + expect(json_response['username']).to eq(user.username) + end + + it "returns a 404 if the target user is present but inaccessible" do + allow(Ability).to receive(:allowed?).and_call_original + allow(Ability).to receive(:allowed?).with(nil, :read_user, user).and_return(false) + + get api("/users/#{user.id}") + + expect(response).to have_http_status(404) + end end it "returns a 404 error if user id not found" do @@ -345,6 +390,14 @@ describe API::Users do expect(json_response['identities'].first['provider']).to eq('github') end end + + context "scopes" do + let(:user) { admin } + let(:path) { '/users' } + let(:api_call) { method(:api) } + + include_examples 'does not allow the "read_user" scope' + end end describe "GET /users/sign_up" do @@ -842,6 +895,13 @@ describe API::Users do expect(response).to match_response_schema('public_api/v4/user/public') expect(json_response['id']).to eq(user.id) end + + context "scopes" do + let(:path) { "/user" } + let(:api_call) { method(:api) } + + include_examples 'allows the "read_user" scope' + end end context 'with admin' do @@ -911,6 +971,13 @@ describe API::Users do expect(json_response).to be_an Array expect(json_response.first["title"]).to eq(key.title) end + + context "scopes" do + let(:path) { "/user/keys" } + let(:api_call) { method(:api) } + + include_examples 'allows the "read_user" scope' + end end end @@ -944,6 +1011,13 @@ describe API::Users do expect(response).to have_http_status(404) end + + context "scopes" do + let(:path) { "/user/keys/#{key.id}" } + let(:api_call) { method(:api) } + + include_examples 'allows the "read_user" scope' + end end describe "POST /user/keys" do @@ -1033,6 +1107,13 @@ describe API::Users do expect(json_response).to be_an Array expect(json_response.first["email"]).to eq(email.email) end + + context "scopes" do + let(:path) { "/user/emails" } + let(:api_call) { method(:api) } + + include_examples 'allows the "read_user" scope' + end end end @@ -1065,6 +1146,13 @@ describe API::Users do expect(response).to have_http_status(404) end + + context "scopes" do + let(:path) { "/user/emails/#{email.id}" } + let(:api_call) { method(:api) } + + include_examples 'allows the "read_user" scope' + end end describe "POST /user/emails" do diff --git a/spec/requests/api/v3/users_spec.rb b/spec/requests/api/v3/users_spec.rb index 6d7401f9764..de7499a4e43 100644 --- a/spec/requests/api/v3/users_spec.rb +++ b/spec/requests/api/v3/users_spec.rb @@ -67,6 +67,19 @@ describe API::V3::Users do expect(json_response.first['title']).to eq(key.title) end end + + context "scopes" do + let(:user) { admin } + let(:path) { "/users/#{user.id}/keys" } + let(:api_call) { method(:v3_api) } + + before do + user.keys << key + user.save + end + + include_examples 'allows the "read_user" scope' + end end describe 'GET /user/:id/emails' do @@ -287,7 +300,7 @@ describe API::V3::Users do end it 'returns a 404 error if not found' do - get v3_api('/users/42/events', user) + get v3_api('/users/420/events', user) expect(response).to have_http_status(404) expect(json_response['message']).to eq('404 User Not Found') @@ -312,5 +325,13 @@ describe API::V3::Users do expect(json_response['is_admin']).to be_nil end + + context "scopes" do + let(:user) { admin } + let(:path) { '/users' } + let(:api_call) { method(:v3_api) } + + include_examples 'does not allow the "read_user" scope' + end end end diff --git a/spec/requests/projects/cycle_analytics_events_spec.rb b/spec/requests/projects/cycle_analytics_events_spec.rb index d4d3c9478a0..e78d2cfdb33 100644 --- a/spec/requests/projects/cycle_analytics_events_spec.rb +++ b/spec/requests/projects/cycle_analytics_events_spec.rb @@ -21,7 +21,7 @@ describe 'cycle analytics events', api: true do end it 'lists the issue events' do - get namespace_project_cycle_analytics_issue_path(project.namespace, project, format: :json) + get project_cycle_analytics_issue_path(project, format: :json) first_issue_iid = project.issues.sort(:created_desc).pluck(:iid).first.to_s @@ -30,7 +30,7 @@ describe 'cycle analytics events', api: true do end it 'lists the plan events' do - get namespace_project_cycle_analytics_plan_path(project.namespace, project, format: :json) + get project_cycle_analytics_plan_path(project, format: :json) first_mr_short_sha = project.merge_requests.sort(:created_asc).first.commits.first.short_id @@ -39,7 +39,7 @@ describe 'cycle analytics events', api: true do end it 'lists the code events' do - get namespace_project_cycle_analytics_code_path(project.namespace, project, format: :json) + get project_cycle_analytics_code_path(project, format: :json) expect(json_response['events']).not_to be_empty @@ -49,14 +49,14 @@ describe 'cycle analytics events', api: true do end it 'lists the test events' do - get namespace_project_cycle_analytics_test_path(project.namespace, project, format: :json) + get project_cycle_analytics_test_path(project, format: :json) expect(json_response['events']).not_to be_empty expect(json_response['events'].first['date']).not_to be_empty end it 'lists the review events' do - get namespace_project_cycle_analytics_review_path(project.namespace, project, format: :json) + get project_cycle_analytics_review_path(project, format: :json) first_mr_iid = project.merge_requests.sort(:created_desc).pluck(:iid).first.to_s @@ -65,14 +65,14 @@ describe 'cycle analytics events', api: true do end it 'lists the staging events' do - get namespace_project_cycle_analytics_staging_path(project.namespace, project, format: :json) + get project_cycle_analytics_staging_path(project, format: :json) expect(json_response['events']).not_to be_empty expect(json_response['events'].first['date']).not_to be_empty end it 'lists the production events' do - get namespace_project_cycle_analytics_production_path(project.namespace, project, format: :json) + get project_cycle_analytics_production_path(project, format: :json) first_issue_iid = project.issues.sort(:created_desc).pluck(:iid).first.to_s @@ -84,7 +84,7 @@ describe 'cycle analytics events', api: true do it 'lists the test events' do branch = project.merge_requests.first.source_branch - get namespace_project_cycle_analytics_test_path(project.namespace, project, format: :json, branch: branch) + get project_cycle_analytics_test_path(project, format: :json, branch: branch) expect(json_response['events']).not_to be_empty expect(json_response['events'].first['date']).not_to be_empty @@ -97,19 +97,19 @@ describe 'cycle analytics events', api: true do end it 'does not list the test events' do - get namespace_project_cycle_analytics_test_path(project.namespace, project, format: :json) + get project_cycle_analytics_test_path(project, format: :json) expect(response).to have_http_status(:not_found) end it 'does not list the staging events' do - get namespace_project_cycle_analytics_staging_path(project.namespace, project, format: :json) + get project_cycle_analytics_staging_path(project, format: :json) expect(response).to have_http_status(:not_found) end it 'lists the issue events' do - get namespace_project_cycle_analytics_issue_path(project.namespace, project, format: :json) + get project_cycle_analytics_issue_path(project, format: :json) expect(response).to have_http_status(:ok) end diff --git a/spec/rubocop/cop/active_record_dependent_spec.rb b/spec/rubocop/cop/active_record_dependent_spec.rb new file mode 100644 index 00000000000..599a032bfc5 --- /dev/null +++ b/spec/rubocop/cop/active_record_dependent_spec.rb @@ -0,0 +1,33 @@ +require 'spec_helper' +require 'rubocop' +require 'rubocop/rspec/support' +require_relative '../../../rubocop/cop/active_record_dependent' + +describe RuboCop::Cop::ActiveRecordDependent do + include CopHelper + + subject(:cop) { described_class.new } + + context 'inside the app/models directory' do + it 'registers an offense when dependent: is used' do + allow(cop).to receive(:in_model?).and_return(true) + + inspect_source(cop, 'belongs_to :foo, dependent: :destroy') + + aggregate_failures do + expect(cop.offenses.size).to eq(1) + expect(cop.offenses.map(&:line)).to eq([1]) + end + end + end + + context 'outside the app/models directory' do + it 'does nothing' do + allow(cop).to receive(:in_model?).and_return(false) + + inspect_source(cop, 'belongs_to :foo, dependent: :destroy') + + expect(cop.offenses).to be_empty + end + end +end diff --git a/spec/rubocop/cop/activerecord_serialize_spec.rb b/spec/rubocop/cop/active_record_serialize_spec.rb index 5bd7e5fa926..b94b25cecd0 100644 --- a/spec/rubocop/cop/activerecord_serialize_spec.rb +++ b/spec/rubocop/cop/active_record_serialize_spec.rb @@ -1,9 +1,9 @@ require 'spec_helper' require 'rubocop' require 'rubocop/rspec/support' -require_relative '../../../rubocop/cop/activerecord_serialize' +require_relative '../../../rubocop/cop/active_record_serialize' -describe RuboCop::Cop::ActiverecordSerialize do +describe RuboCop::Cop::ActiveRecordSerialize do include CopHelper subject(:cop) { described_class.new } diff --git a/spec/rubocop/cop/project_path_helper_spec.rb b/spec/rubocop/cop/project_path_helper_spec.rb new file mode 100644 index 00000000000..bc47b45cad7 --- /dev/null +++ b/spec/rubocop/cop/project_path_helper_spec.rb @@ -0,0 +1,41 @@ +require 'spec_helper' + +require 'rubocop' +require 'rubocop/rspec/support' + +require_relative '../../../rubocop/cop/project_path_helper' + +describe RuboCop::Cop::ProjectPathHelper do + include CopHelper + + subject(:cop) { described_class.new } + + context "when using namespace_project with the project's namespace" do + let(:source) { 'edit_namespace_project_issue_path(@issue.project.namespace, @issue.project, @issue)' } + let(:correct_source) { 'edit_project_issue_path(@issue.project, @issue)' } + + it 'registers an offense' do + inspect_source(cop, source) + + aggregate_failures do + expect(cop.offenses.size).to eq(1) + expect(cop.offenses.map(&:line)).to eq([1]) + expect(cop.highlights).to eq(['edit_namespace_project_issue_path']) + end + end + + it 'autocorrects to the right version' do + autocorrected = autocorrect_source(cop, source) + + expect(autocorrected).to eq(correct_source) + end + end + + context 'when using namespace_project with a different namespace' do + it 'registers no offense' do + inspect_source(cop, 'edit_namespace_project_issue_path(namespace, project)') + + expect(cop.offenses.size).to eq(0) + end + end +end diff --git a/spec/serializers/deploy_key_entity_spec.rb b/spec/serializers/deploy_key_entity_spec.rb index ed89fccc3d0..9620f9665cf 100644 --- a/spec/serializers/deploy_key_entity_spec.rb +++ b/spec/serializers/deploy_key_entity_spec.rb @@ -29,7 +29,7 @@ describe DeployKeyEntity do { id: project.id, name: project.name, - full_path: namespace_project_path(project.namespace, project), + full_path: project_path(project), full_name: project.full_name } ] diff --git a/spec/services/access_token_validation_service_spec.rb b/spec/services/access_token_validation_service_spec.rb index 87f093ee8ce..11225fad18a 100644 --- a/spec/services/access_token_validation_service_spec.rb +++ b/spec/services/access_token_validation_service_spec.rb @@ -2,40 +2,71 @@ require 'spec_helper' describe AccessTokenValidationService, services: true do describe ".include_any_scope?" do + let(:request) { double("request") } + it "returns true if the required scope is present in the token's scopes" do token = double("token", scopes: [:api, :read_user]) + scopes = [:api] - expect(described_class.new(token).include_any_scope?([:api])).to be(true) + expect(described_class.new(token, request: request).include_any_scope?(scopes)).to be(true) end it "returns true if more than one of the required scopes is present in the token's scopes" do token = double("token", scopes: [:api, :read_user, :other_scope]) + scopes = [:api, :other_scope] - expect(described_class.new(token).include_any_scope?([:api, :other_scope])).to be(true) + expect(described_class.new(token, request: request).include_any_scope?(scopes)).to be(true) end it "returns true if the list of required scopes is an exact match for the token's scopes" do token = double("token", scopes: [:api, :read_user, :other_scope]) + scopes = [:api, :read_user, :other_scope] - expect(described_class.new(token).include_any_scope?([:api, :read_user, :other_scope])).to be(true) + expect(described_class.new(token, request: request).include_any_scope?(scopes)).to be(true) end it "returns true if the list of required scopes contains all of the token's scopes, in addition to others" do token = double("token", scopes: [:api, :read_user]) + scopes = [:api, :read_user, :other_scope] - expect(described_class.new(token).include_any_scope?([:api, :read_user, :other_scope])).to be(true) + expect(described_class.new(token, request: request).include_any_scope?(scopes)).to be(true) end it 'returns true if the list of required scopes is blank' do token = double("token", scopes: []) + scopes = [] - expect(described_class.new(token).include_any_scope?([])).to be(true) + expect(described_class.new(token, request: request).include_any_scope?(scopes)).to be(true) end it "returns false if there are no scopes in common between the required scopes and the token scopes" do token = double("token", scopes: [:api, :read_user]) + scopes = [:other_scope] + + expect(described_class.new(token, request: request).include_any_scope?(scopes)).to be(false) + end + + context "conditions" do + it "ignores any scopes whose `if` condition returns false" do + token = double("token", scopes: [:api, :read_user]) + scopes = [API::Scope.new(:api, if: ->(_) { false })] + + expect(described_class.new(token, request: request).include_any_scope?(scopes)).to be(false) + end + + it "does not ignore scopes whose `if` condition is not set" do + token = double("token", scopes: [:api, :read_user]) + scopes = [API::Scope.new(:api, if: ->(_) { false }), :read_user] + + expect(described_class.new(token, request: request).include_any_scope?(scopes)).to be(true) + end + + it "does not ignore scopes whose `if` condition returns true" do + token = double("token", scopes: [:api, :read_user]) + scopes = [API::Scope.new(:api, if: ->(_) { true }), API::Scope.new(:read_user, if: ->(_) { false })] - expect(described_class.new(token).include_any_scope?([:other_scope])).to be(false) + expect(described_class.new(token, request: request).include_any_scope?(scopes)).to be(true) + end end end end diff --git a/spec/services/delete_merged_branches_service_spec.rb b/spec/services/delete_merged_branches_service_spec.rb index cae74df9c90..fe21ca0b3cb 100644 --- a/spec/services/delete_merged_branches_service_spec.rb +++ b/spec/services/delete_merged_branches_service_spec.rb @@ -24,6 +24,14 @@ describe DeleteMergedBranchesService, services: true do expect(project.repository.branch_names).to include('master') end + it 'keeps protected branches' do + create(:protected_branch, project: project, name: 'improve/awesome') + + service.execute + + expect(project.repository.branch_names).to include('improve/awesome') + end + context 'user without rights' do let(:user) { create(:user) } diff --git a/spec/services/merge_requests/merge_service_spec.rb b/spec/services/merge_requests/merge_service_spec.rb index 711059208c1..19d9e4049fe 100644 --- a/spec/services/merge_requests/merge_service_spec.rb +++ b/spec/services/merge_requests/merge_service_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' describe MergeRequests::MergeService, services: true do let(:user) { create(:user) } let(:user2) { create(:user) } - let(:merge_request) { create(:merge_request, assignee: user2) } + let(:merge_request) { create(:merge_request, :simple, author: user2, assignee: user2) } let(:project) { merge_request.project } before do @@ -133,18 +133,65 @@ describe MergeRequests::MergeService, services: true do it { expect(todo).to be_done } end - context 'remove source branch by author' do - let(:service) do - merge_request.merge_params['force_remove_source_branch'] = '1' - merge_request.save! - MergeRequests::MergeService.new(project, user, commit_message: 'Awesome message') + context 'source branch removal' do + context 'when the source branch is protected' do + let(:service) do + MergeRequests::MergeService.new(project, user, should_remove_source_branch: '1') + end + + before do + create(:protected_branch, project: project, name: merge_request.source_branch) + end + + it 'does not delete the source branch' do + expect(DeleteBranchService).not_to receive(:new) + service.execute(merge_request) + end end - it 'removes the source branch' do - expect(DeleteBranchService).to receive(:new) - .with(merge_request.source_project, merge_request.author) - .and_call_original - service.execute(merge_request) + context 'when the source branch is the default branch' do + let(:service) do + MergeRequests::MergeService.new(project, user, should_remove_source_branch: '1') + end + + before do + allow(project).to receive(:root_ref?).with(merge_request.source_branch).and_return(true) + end + + it 'does not delete the source branch' do + expect(DeleteBranchService).not_to receive(:new) + service.execute(merge_request) + end + end + + context 'when the source branch can be removed' do + context 'when MR author set the source branch to be removed' do + let(:service) do + merge_request.merge_params['force_remove_source_branch'] = '1' + merge_request.save! + MergeRequests::MergeService.new(project, user, commit_message: 'Awesome message') + end + + it 'removes the source branch using the author user' do + expect(DeleteBranchService).to receive(:new) + .with(merge_request.source_project, merge_request.author) + .and_call_original + service.execute(merge_request) + end + end + + context 'when MR merger set the source branch to be removed' do + let(:service) do + MergeRequests::MergeService.new(project, user, commit_message: 'Awesome message', should_remove_source_branch: '1') + end + + it 'removes the source branch using the current user' do + expect(DeleteBranchService).to receive(:new) + .with(merge_request.source_project, user) + .and_call_original + service.execute(merge_request) + end + end end end diff --git a/spec/services/projects/transfer_service_spec.rb b/spec/services/projects/transfer_service_spec.rb index 76c52d55ae5..441a5276c56 100644 --- a/spec/services/projects/transfer_service_spec.rb +++ b/spec/services/projects/transfer_service_spec.rb @@ -30,6 +30,12 @@ describe Projects::TransferService, services: true do transfer_project(project, user, group) end + it 'expires full_path cache' do + expect(project).to receive(:expires_full_path_cache) + + transfer_project(project, user, group) + end + it 'executes system hooks' do expect_any_instance_of(Projects::TransferService).to receive(:execute_system_hooks) diff --git a/spec/services/quick_actions/interpret_service_spec.rb b/spec/services/quick_actions/interpret_service_spec.rb index c9e63efbc14..35373675894 100644 --- a/spec/services/quick_actions/interpret_service_spec.rb +++ b/spec/services/quick_actions/interpret_service_spec.rb @@ -359,18 +359,18 @@ describe QuickActions::InterpretService, services: true do let(:content) { "/assign @#{developer.username}" } context 'Issue' do - it 'fetches assignee and populates assignee_id if content contains /assign' do + it 'fetches assignee and populates assignee_ids if content contains /assign' do _, updates = service.execute(content, issue) - expect(updates).to eq(assignee_ids: [developer.id]) + expect(updates[:assignee_ids]).to match_array([developer.id]) end end context 'Merge Request' do - it 'fetches assignee and populates assignee_id if content contains /assign' do + it 'fetches assignee and populates assignee_ids if content contains /assign' do _, updates = service.execute(content, merge_request) - expect(updates).to eq(assignee_id: developer.id) + expect(updates).to eq(assignee_ids: [developer.id]) end end end @@ -383,7 +383,7 @@ describe QuickActions::InterpretService, services: true do end context 'Issue' do - it 'fetches assignee and populates assignee_id if content contains /assign' do + it 'fetches assignee and populates assignee_ids if content contains /assign' do _, updates = service.execute(content, issue) expect(updates[:assignee_ids]).to match_array([developer.id]) @@ -391,10 +391,10 @@ describe QuickActions::InterpretService, services: true do end context 'Merge Request' do - it 'fetches assignee and populates assignee_id if content contains /assign' do + it 'fetches assignee and populates assignee_ids if content contains /assign' do _, updates = service.execute(content, merge_request) - expect(updates).to eq(assignee_id: developer.id) + expect(updates).to eq(assignee_ids: [developer.id]) end end end @@ -422,11 +422,27 @@ describe QuickActions::InterpretService, services: true do end context 'Merge Request' do - it 'populates assignee_id: nil if content contains /unassign' do - merge_request.update(assignee_id: developer.id) + it 'populates assignee_ids: [] if content contains /unassign' do + merge_request.update(assignee_ids: [developer.id]) _, updates = service.execute(content, merge_request) - expect(updates).to eq(assignee_id: nil) + expect(updates).to eq(assignee_ids: []) + end + end + end + + context 'reassign command' do + let(:content) { '/reassign' } + + context 'Issue' do + it 'reassigns user if content contains /reassign @user' do + user = create(:user) + + issue.update(assignee_ids: [developer.id]) + + _, updates = service.execute("/reassign @#{user.username}", issue) + + expect(updates).to eq(assignee_ids: [user.id]) end end end diff --git a/spec/services/system_note_service_spec.rb b/spec/services/system_note_service_spec.rb index 8d3dafafab2..e35e4c1d631 100644 --- a/spec/services/system_note_service_spec.rb +++ b/spec/services/system_note_service_spec.rb @@ -807,7 +807,7 @@ describe SystemNoteService, services: true do body: hash_including( GlobalID: "GitLab", object: { - url: namespace_project_commit_url(project.namespace, project, commit), + url: project_commit_url(project, commit), title: "GitLab: Mentioned on commit - #{commit.title}", icon: { title: "GitLab", url16x16: "https://gitlab.com/favicon.ico" }, status: { resolved: false } @@ -833,7 +833,7 @@ describe SystemNoteService, services: true do body: hash_including( GlobalID: "GitLab", object: { - url: namespace_project_issue_url(project.namespace, project, issue), + url: project_issue_url(project, issue), title: "GitLab: Mentioned on issue - #{issue.title}", icon: { title: "GitLab", url16x16: "https://gitlab.com/favicon.ico" }, status: { resolved: false } @@ -859,7 +859,7 @@ describe SystemNoteService, services: true do body: hash_including( GlobalID: "GitLab", object: { - url: namespace_project_snippet_url(project.namespace, project, snippet), + url: project_snippet_url(project, snippet), title: "GitLab: Mentioned on snippet - #{snippet.title}", icon: { title: "GitLab", url16x16: "https://gitlab.com/favicon.ico" }, status: { resolved: false } @@ -1098,7 +1098,7 @@ describe SystemNoteService, services: true do diff_id = merge_request.merge_request_diff.id line_code = change_position.line_code(project.repository) - expect(subject.note).to include(diffs_namespace_project_merge_request_url(project.namespace, project, merge_request, diff_id: diff_id, anchor: line_code)) + expect(subject.note).to include(diffs_project_merge_request_url(project, merge_request, diff_id: diff_id, anchor: line_code)) end end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index fdef6fd5221..3e90a642d56 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -57,7 +57,7 @@ RSpec.configure do |config| config.include StubGitlabCalls config.include StubGitlabData config.include ApiHelpers, :api - config.include Rails.application.routes.url_helpers, type: :routing + config.include Gitlab::Routing.url_helpers, type: :routing config.include MigrationsHelpers, :migration config.infer_spec_type_from_file_location! diff --git a/spec/support/api/scopes/read_user_shared_examples.rb b/spec/support/api/scopes/read_user_shared_examples.rb new file mode 100644 index 00000000000..3bd589d64b9 --- /dev/null +++ b/spec/support/api/scopes/read_user_shared_examples.rb @@ -0,0 +1,79 @@ +shared_examples_for 'allows the "read_user" scope' do + context 'for personal access tokens' do + context 'when the requesting token has the "api" scope' do + let(:token) { create(:personal_access_token, scopes: ['api'], user: user) } + + it 'returns a "200" response' do + get api_call.call(path, user, personal_access_token: token) + + expect(response).to have_http_status(200) + end + end + + context 'when the requesting token has the "read_user" scope' do + let(:token) { create(:personal_access_token, scopes: ['read_user'], user: user) } + + it 'returns a "200" response' do + get api_call.call(path, user, personal_access_token: token) + + expect(response).to have_http_status(200) + end + end + + context 'when the requesting token does not have any required scope' do + let(:token) { create(:personal_access_token, scopes: ['read_registry'], user: user) } + + it 'returns a "401" response' do + get api_call.call(path, user, personal_access_token: token) + + expect(response).to have_http_status(401) + end + end + end + + context 'for doorkeeper (OAuth) tokens' do + let!(:application) { Doorkeeper::Application.create!(name: "MyApp", redirect_uri: "https://app.com", owner: user) } + + context 'when the requesting token has the "api" scope' do + let!(:token) { Doorkeeper::AccessToken.create! application_id: application.id, resource_owner_id: user.id, scopes: "api" } + + it 'returns a "200" response' do + get api_call.call(path, user, oauth_access_token: token) + + expect(response).to have_http_status(200) + end + end + + context 'when the requesting token has the "read_user" scope' do + let!(:token) { Doorkeeper::AccessToken.create! application_id: application.id, resource_owner_id: user.id, scopes: "read_user" } + + it 'returns a "200" response' do + get api_call.call(path, user, oauth_access_token: token) + + expect(response).to have_http_status(200) + end + end + + context 'when the requesting token does not have any required scope' do + let!(:token) { Doorkeeper::AccessToken.create! application_id: application.id, resource_owner_id: user.id, scopes: "invalid" } + + it 'returns a "403" response' do + get api_call.call(path, user, oauth_access_token: token) + + expect(response).to have_http_status(403) + end + end + end +end + +shared_examples_for 'does not allow the "read_user" scope' do + context 'when the requesting token has the "read_user" scope' do + let(:token) { create(:personal_access_token, scopes: ['read_user'], user: user) } + + it 'returns a "401" response' do + post api_call.call(path, user, personal_access_token: token), attributes_for(:user, projects_limit: 3) + + expect(response).to have_http_status(401) + end + end +end diff --git a/spec/support/api_helpers.rb b/spec/support/api_helpers.rb index 35d1e1cfc7d..ac0aaa524b7 100644 --- a/spec/support/api_helpers.rb +++ b/spec/support/api_helpers.rb @@ -17,14 +17,18 @@ module ApiHelpers # => "/api/v2/issues?foo=bar&private_token=..." # # Returns the relative path to the requested API resource - def api(path, user = nil, version: API::API.version) + def api(path, user = nil, version: API::API.version, personal_access_token: nil, oauth_access_token: nil) "/api/#{version}#{path}" + # Normalize query string (path.index('?') ? '' : '?') + + if personal_access_token.present? + "&private_token=#{personal_access_token.token}" + elsif oauth_access_token.present? + "&access_token=#{oauth_access_token.token}" # Append private_token if given a User object - if user.respond_to?(:private_token) + elsif user.respond_to?(:private_token) "&private_token=#{user.private_token}" else '' @@ -32,8 +36,14 @@ module ApiHelpers end # Temporary helper method for simplifying V3 exclusive API specs - def v3_api(path, user = nil) - api(path, user, version: 'v3') + def v3_api(path, user = nil, personal_access_token: nil, oauth_access_token: nil) + api( + path, + user, + version: 'v3', + personal_access_token: personal_access_token, + oauth_access_token: oauth_access_token + ) end def ci_api(path, user = nil) diff --git a/spec/support/capybara_helpers.rb b/spec/support/capybara_helpers.rb index b57a3493aff..3eb7bea3227 100644 --- a/spec/support/capybara_helpers.rb +++ b/spec/support/capybara_helpers.rb @@ -35,6 +35,11 @@ module CapybaraHelpers visit 'about:blank' visit url end + + # Simulate a browser restart by clearing the session cookie. + def clear_browser_session + page.driver.remove_cookie('_gitlab_session') + end end RSpec.configure do |config| diff --git a/spec/support/cycle_analytics_helpers.rb b/spec/support/cycle_analytics_helpers.rb index 6e1eb5c678d..c0a5491a430 100644 --- a/spec/support/cycle_analytics_helpers.rb +++ b/spec/support/cycle_analytics_helpers.rb @@ -74,7 +74,9 @@ module CycleAnalyticsHelpers def dummy_pipeline @dummy_pipeline ||= - Ci::Pipeline.new(sha: project.repository.commit('master').sha) + Ci::Pipeline.new( + sha: project.repository.commit('master').sha, + project: project) end def new_dummy_job(environment) diff --git a/spec/support/issue_helpers.rb b/spec/support/issue_helpers.rb index 85241793743..ffd72515f37 100644 --- a/spec/support/issue_helpers.rb +++ b/spec/support/issue_helpers.rb @@ -1,6 +1,6 @@ module IssueHelpers def visit_issues(project, opts = {}) - visit namespace_project_issues_path project.namespace, project, opts + visit project_issues_path project, opts end def first_issue diff --git a/spec/support/login_helpers.rb b/spec/support/login_helpers.rb index 4c88958264b..99e7806353d 100644 --- a/spec/support/login_helpers.rb +++ b/spec/support/login_helpers.rb @@ -62,6 +62,16 @@ module LoginHelpers Thread.current[:current_user] = user end + def login_via(provider, user, uid, remember_me: false) + mock_auth_hash(provider, uid, user.email) + visit new_user_session_path + expect(page).to have_content('Sign in with') + + check 'Remember Me' if remember_me + + click_link "oauth-login-#{provider}" + end + def mock_auth_hash(provider, uid, email) # The mock_auth configuration allows you to set per-provider (or default) # authentication hashes to return during integration testing. @@ -108,6 +118,7 @@ module LoginHelpers end allow(Gitlab::OAuth::Provider).to receive_messages(providers: [:saml], config_for: mock_saml_config) stub_omniauth_setting(messages) - expect_any_instance_of(Object).to receive(:omniauth_authorize_path).with(:user, "saml").and_return('/users/auth/saml') + allow_any_instance_of(Object).to receive(:user_saml_omniauth_authorize_path).and_return('/users/auth/saml') + allow_any_instance_of(Object).to receive(:omniauth_authorize_path).with(:user, "saml").and_return('/users/auth/saml') end end diff --git a/spec/support/matchers/be_utf8.rb b/spec/support/matchers/be_utf8.rb new file mode 100644 index 00000000000..ea806352422 --- /dev/null +++ b/spec/support/matchers/be_utf8.rb @@ -0,0 +1,9 @@ +RSpec::Matchers.define :be_utf8 do |_| + match do |actual| + actual.is_a?(String) && actual.encoding == Encoding.find('UTF-8') + end + + description do + "be a String with encoding UTF-8" + end +end diff --git a/spec/support/merge_request_helpers.rb b/spec/support/merge_request_helpers.rb index 326b85eabd0..772adff4626 100644 --- a/spec/support/merge_request_helpers.rb +++ b/spec/support/merge_request_helpers.rb @@ -1,6 +1,6 @@ module MergeRequestHelpers def visit_merge_requests(project, opts = {}) - visit namespace_project_merge_requests_path project.namespace, project, opts + visit project_merge_requests_path project, opts end def first_merge_request diff --git a/spec/support/protected_tags/access_control_ce_shared_examples.rb b/spec/support/protected_tags/access_control_ce_shared_examples.rb index 1d11512ef82..421a51fc336 100644 --- a/spec/support/protected_tags/access_control_ce_shared_examples.rb +++ b/spec/support/protected_tags/access_control_ce_shared_examples.rb @@ -1,7 +1,7 @@ RSpec.shared_examples "protected tags > access control > CE" do ProtectedTag::CreateAccessLevel.human_access_levels.each do |(access_type_id, access_type_name)| it "allows creating protected tags that #{access_type_name} can create" do - visit namespace_project_protected_tags_path(project.namespace, project) + visit project_protected_tags_path(project) set_protected_tag_name('master') @@ -22,7 +22,7 @@ RSpec.shared_examples "protected tags > access control > CE" do end it "allows updating protected tags so that #{access_type_name} can create them" do - visit namespace_project_protected_tags_path(project.namespace, project) + visit project_protected_tags_path(project) set_protected_tag_name('master') diff --git a/spec/support/routing_helpers.rb b/spec/support/routing_helpers.rb new file mode 100644 index 00000000000..af1f4760804 --- /dev/null +++ b/spec/support/routing_helpers.rb @@ -0,0 +1,3 @@ +RSpec.configure do |config| + config.include GitlabRoutingHelper +end diff --git a/spec/support/shared_examples/features/protected_branches_access_control_ce.rb b/spec/support/shared_examples/features/protected_branches_access_control_ce.rb index b6341127a76..66e598e2691 100644 --- a/spec/support/shared_examples/features/protected_branches_access_control_ce.rb +++ b/spec/support/shared_examples/features/protected_branches_access_control_ce.rb @@ -1,7 +1,7 @@ shared_examples "protected branches > access control > CE" do ProtectedBranch::PushAccessLevel.human_access_levels.each do |(access_type_id, access_type_name)| it "allows creating protected branches that #{access_type_name} can push to" do - visit namespace_project_protected_branches_path(project.namespace, project) + visit project_protected_branches_path(project) set_protected_branch_name('master') @@ -21,7 +21,7 @@ shared_examples "protected branches > access control > CE" do end it "allows updating protected branches so that #{access_type_name} can push to them" do - visit namespace_project_protected_branches_path(project.namespace, project) + visit project_protected_branches_path(project) set_protected_branch_name('master') @@ -46,7 +46,7 @@ shared_examples "protected branches > access control > CE" do ProtectedBranch::MergeAccessLevel.human_access_levels.each do |(access_type_id, access_type_name)| it "allows creating protected branches that #{access_type_name} can merge to" do - visit namespace_project_protected_branches_path(project.namespace, project) + visit project_protected_branches_path(project) set_protected_branch_name('master') @@ -66,7 +66,7 @@ shared_examples "protected branches > access control > CE" do end it "allows updating protected branches so that #{access_type_name} can merge to them" do - visit namespace_project_protected_branches_path(project.namespace, project) + visit project_protected_branches_path(project) set_protected_branch_name('master') diff --git a/spec/views/ci/status/_badge.html.haml_spec.rb b/spec/views/ci/status/_badge.html.haml_spec.rb index 72323da2838..6a4738ba443 100644 --- a/spec/views/ci/status/_badge.html.haml_spec.rb +++ b/spec/views/ci/status/_badge.html.haml_spec.rb @@ -16,8 +16,7 @@ describe 'ci/status/_badge', :view do end it 'has link to build details page' do - details_path = namespace_project_job_path( - project.namespace, project, build) + details_path = project_job_path(project, build) render_status(build) diff --git a/spec/views/projects/merge_requests/_commits.html.haml_spec.rb b/spec/views/projects/merge_requests/_commits.html.haml_spec.rb index 3e17fe2104b..98c7de9b709 100644 --- a/spec/views/projects/merge_requests/_commits.html.haml_spec.rb +++ b/spec/views/projects/merge_requests/_commits.html.haml_spec.rb @@ -25,10 +25,7 @@ describe 'projects/merge_requests/_commits.html.haml' do render commit = source_project.commit(merge_request.source_branch) - href = namespace_project_commit_path( - source_project.namespace, - source_project, - commit) + href = project_commit_path(source_project, commit) expect(rendered).to have_link(Commit.truncate_sha(commit.sha), href: href) end diff --git a/spec/workers/expire_build_instance_artifacts_worker_spec.rb b/spec/workers/expire_build_instance_artifacts_worker_spec.rb index 1d8da68883b..bed5c5e2ecb 100644 --- a/spec/workers/expire_build_instance_artifacts_worker_spec.rb +++ b/spec/workers/expire_build_instance_artifacts_worker_spec.rb @@ -30,20 +30,6 @@ describe ExpireBuildInstanceArtifactsWorker do expect(build.reload.artifacts_file_identifier).to be_nil end end - - context 'when associated project was removed' do - let(:build) do - create(:ci_build, :artifacts, artifacts_expiry) do |build| - build.project.pending_delete = true - end - end - - it 'does not remove artifacts' do - expect do - build.reload.artifacts_file - end.not_to raise_error - end - end end context 'with not yet expired artifacts' do |