Commit d35df0ad authored by GitLab Bot's avatar GitLab Bot

Add latest changes from gitlab-org/gitlab@12-10-stable-ee

parent 3c51da6f
...@@ -3,7 +3,6 @@ import SecretValues from '~/behaviors/secret_values'; ...@@ -3,7 +3,6 @@ import SecretValues from '~/behaviors/secret_values';
import AjaxVariableList from '~/ci_variable_list/ajax_variable_list'; import AjaxVariableList from '~/ci_variable_list/ajax_variable_list';
import registrySettingsApp from '~/registry/settings/registry_settings_bundle'; import registrySettingsApp from '~/registry/settings/registry_settings_bundle';
import initVariableList from '~/ci_variable_list'; import initVariableList from '~/ci_variable_list';
import initDeployKeys from '~/deploy_keys';
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
// Initialize expandable settings panels // Initialize expandable settings panels
...@@ -41,5 +40,4 @@ document.addEventListener('DOMContentLoaded', () => { ...@@ -41,5 +40,4 @@ document.addEventListener('DOMContentLoaded', () => {
}); });
registrySettingsApp(); registrySettingsApp();
initDeployKeys();
}); });
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
import ProtectedTagCreate from '~/protected_tags/protected_tag_create'; import ProtectedTagCreate from '~/protected_tags/protected_tag_create';
import ProtectedTagEditList from '~/protected_tags/protected_tag_edit_list'; import ProtectedTagEditList from '~/protected_tags/protected_tag_edit_list';
import initSettingsPanels from '~/settings_panels'; import initSettingsPanels from '~/settings_panels';
import initDeployKeys from '~/deploy_keys';
import ProtectedBranchCreate from '~/protected_branches/protected_branch_create'; import ProtectedBranchCreate from '~/protected_branches/protected_branch_create';
import ProtectedBranchEditList from '~/protected_branches/protected_branch_edit_list'; import ProtectedBranchEditList from '~/protected_branches/protected_branch_edit_list';
import DueDateSelectors from '~/due_date_select'; import DueDateSelectors from '~/due_date_select';
...@@ -11,6 +12,7 @@ import fileUpload from '~/lib/utils/file_upload'; ...@@ -11,6 +12,7 @@ import fileUpload from '~/lib/utils/file_upload';
export default () => { export default () => {
new ProtectedTagCreate(); new ProtectedTagCreate();
new ProtectedTagEditList(); new ProtectedTagEditList();
initDeployKeys();
initSettingsPanels(); initSettingsPanels();
new ProtectedBranchCreate(); new ProtectedBranchCreate();
new ProtectedBranchEditList(); new ProtectedBranchEditList();
......
...@@ -108,14 +108,14 @@ export default { ...@@ -108,14 +108,14 @@ export default {
return acc.concat({ return acc.concat({
name, name,
path, path,
to: `/-/tree/${joinPaths(escapeFileUrl(this.ref), path)}`, to: `/-/tree/${joinPaths(this.escapedRef, path)}`,
}); });
}, },
[ [
{ {
name: this.projectShortPath, name: this.projectShortPath,
path: '/', path: '/',
to: `/-/tree/${escapeFileUrl(this.ref)}/`, to: `/-/tree/${this.escapedRef}/`,
}, },
], ],
); );
......
...@@ -81,7 +81,7 @@ export default { ...@@ -81,7 +81,7 @@ export default {
<tbody> <tbody>
<parent-row <parent-row
v-show="showParentRow" v-show="showParentRow"
:commit-ref="ref" :commit-ref="escapedRef"
:path="path" :path="path"
:loading-path="loadingPath" :loading-path="loadingPath"
/> />
......
<script> <script>
import { GlLoadingIcon } from '@gitlab/ui'; import { GlLoadingIcon } from '@gitlab/ui';
import { escapeFileUrl } from '~/lib/utils/url_utility';
export default { export default {
components: { components: {
...@@ -29,7 +28,7 @@ export default { ...@@ -29,7 +28,7 @@ export default {
return splitArray.map(p => encodeURIComponent(p)).join('/'); return splitArray.map(p => encodeURIComponent(p)).join('/');
}, },
parentRoute() { parentRoute() {
return { path: `/-/tree/${escapeFileUrl(this.commitRef)}/${this.parentPath}` }; return { path: `/-/tree/${this.commitRef}/${this.parentPath}` };
}, },
}, },
methods: { methods: {
......
...@@ -99,7 +99,7 @@ export default { ...@@ -99,7 +99,7 @@ export default {
computed: { computed: {
routerLinkTo() { routerLinkTo() {
return this.isFolder return this.isFolder
? { path: `/-/tree/${escapeFileUrl(this.ref)}/${escapeFileUrl(this.path)}` } ? { path: `/-/tree/${this.escapedRef}/${escapeFileUrl(this.path)}` }
: null; : null;
}, },
isFolder() { isFolder() {
......
...@@ -15,14 +15,15 @@ import { __ } from '../locale'; ...@@ -15,14 +15,15 @@ import { __ } from '../locale';
export default function setupVueRepositoryList() { export default function setupVueRepositoryList() {
const el = document.getElementById('js-tree-list'); const el = document.getElementById('js-tree-list');
const { dataset } = el; const { dataset } = el;
const { projectPath, projectShortPath, ref, fullName } = dataset; const { projectPath, projectShortPath, ref, escapedRef, fullName } = dataset;
const router = createRouter(projectPath, ref); const router = createRouter(projectPath, escapedRef);
apolloProvider.clients.defaultClient.cache.writeData({ apolloProvider.clients.defaultClient.cache.writeData({
data: { data: {
projectPath, projectPath,
projectShortPath, projectShortPath,
ref, ref,
escapedRef,
vueFileListLfsBadge: gon.features?.vueFileListLfsBadge || false, vueFileListLfsBadge: gon.features?.vueFileListLfsBadge || false,
commits: [], commits: [],
}, },
......
...@@ -23,13 +23,13 @@ export function fetchLogsTree(client, path, offset, resolver = null) { ...@@ -23,13 +23,13 @@ export function fetchLogsTree(client, path, offset, resolver = null) {
if (fetchpromise) return fetchpromise; if (fetchpromise) return fetchpromise;
const { projectPath } = client.readQuery({ query: getProjectPath }); const { projectPath } = client.readQuery({ query: getProjectPath });
const { ref } = client.readQuery({ query: getRef }); const { escapedRef } = client.readQuery({ query: getRef });
fetchpromise = axios fetchpromise = axios
.get( .get(
`${gon.relative_url_root}/${projectPath}/-/refs/${encodeURIComponent( `${gon.relative_url_root}/${projectPath}/-/refs/${escapedRef}/logs_tree/${encodeURIComponent(
ref, path.replace(/^\//, ''),
)}/logs_tree/${encodeURIComponent(path.replace(/^\//, ''))}`, )}`,
{ {
params: { format: 'json', offset }, params: { format: 'json', offset },
}, },
......
...@@ -4,11 +4,19 @@ export default { ...@@ -4,11 +4,19 @@ export default {
apollo: { apollo: {
ref: { ref: {
query: getRef, query: getRef,
manual: true,
result({ data, loading }) {
if (!loading) {
this.ref = data.ref;
this.escapedRef = data.escapedRef;
}
},
}, },
}, },
data() { data() {
return { return {
ref: '', ref: '',
escapedRef: '',
}; };
}, },
}; };
query getRef { query getRef {
ref @client ref @client
escapedRef @client
} }
...@@ -12,7 +12,7 @@ export default function createRouter(base, baseRef) { ...@@ -12,7 +12,7 @@ export default function createRouter(base, baseRef) {
base: joinPaths(gon.relative_url_root || '', base), base: joinPaths(gon.relative_url_root || '', base),
routes: [ routes: [
{ {
path: `(/-)?/tree/(${encodeURIComponent(baseRef).replace(/%2F/g, '/')}|${baseRef})/:path*`, path: `(/-)?/tree/${baseRef}/:path*`,
name: 'treePath', name: 'treePath',
component: TreePage, component: TreePage,
props: route => ({ props: route => ({
......
...@@ -497,7 +497,7 @@ class ApplicationController < ActionController::Base ...@@ -497,7 +497,7 @@ class ApplicationController < ActionController::Base
end end
def public_visibility_restricted? def public_visibility_restricted?
Gitlab::CurrentSettings.restricted_visibility_levels.include? Gitlab::VisibilityLevel::PUBLIC Gitlab::VisibilityLevel.public_visibility_restricted?
end end
def set_usage_stats_consent_flag def set_usage_stats_consent_flag
......
# frozen_string_literal: true # frozen_string_literal: true
class Projects::DeployKeysController < Projects::ApplicationController class Projects::DeployKeysController < Projects::ApplicationController
include RepositorySettingsRedirect
respond_to :html respond_to :html
# Authorize # Authorize
...@@ -11,7 +12,7 @@ class Projects::DeployKeysController < Projects::ApplicationController ...@@ -11,7 +12,7 @@ class Projects::DeployKeysController < Projects::ApplicationController
def index def index
respond_to do |format| respond_to do |format|
format.html { redirect_to_ci_cd_settings } format.html { redirect_to_repository }
format.json do format.json do
render json: Projects::Settings::DeployKeysPresenter.new(@project, current_user: current_user).as_json render json: Projects::Settings::DeployKeysPresenter.new(@project, current_user: current_user).as_json
end end
...@@ -19,7 +20,7 @@ class Projects::DeployKeysController < Projects::ApplicationController ...@@ -19,7 +20,7 @@ class Projects::DeployKeysController < Projects::ApplicationController
end end
def new def new
redirect_to_ci_cd_settings redirect_to_repository
end end
def create def create
...@@ -29,7 +30,7 @@ class Projects::DeployKeysController < Projects::ApplicationController ...@@ -29,7 +30,7 @@ class Projects::DeployKeysController < Projects::ApplicationController
flash[:alert] = @key.errors.full_messages.join(', ').html_safe flash[:alert] = @key.errors.full_messages.join(', ').html_safe
end end
redirect_to_ci_cd_settings redirect_to_repository
end end
def edit def edit
...@@ -38,7 +39,7 @@ class Projects::DeployKeysController < Projects::ApplicationController ...@@ -38,7 +39,7 @@ class Projects::DeployKeysController < Projects::ApplicationController
def update def update
if deploy_key.update(update_params) if deploy_key.update(update_params)
flash[:notice] = _('Deploy key was successfully updated.') flash[:notice] = _('Deploy key was successfully updated.')
redirect_to_ci_cd_settings redirect_to_repository
else else
render 'edit' render 'edit'
end end
...@@ -50,7 +51,7 @@ class Projects::DeployKeysController < Projects::ApplicationController ...@@ -50,7 +51,7 @@ class Projects::DeployKeysController < Projects::ApplicationController
return render_404 unless key return render_404 unless key
respond_to do |format| respond_to do |format|
format.html { redirect_to_ci_cd_settings } format.html { redirect_to_repository }
format.json { head :ok } format.json { head :ok }
end end
end end
...@@ -61,7 +62,7 @@ class Projects::DeployKeysController < Projects::ApplicationController ...@@ -61,7 +62,7 @@ class Projects::DeployKeysController < Projects::ApplicationController
return render_404 unless deploy_key_project return render_404 unless deploy_key_project
respond_to do |format| respond_to do |format|
format.html { redirect_to_ci_cd_settings } format.html { redirect_to_repository }
format.json { head :ok } format.json { head :ok }
end end
end end
...@@ -97,7 +98,9 @@ class Projects::DeployKeysController < Projects::ApplicationController ...@@ -97,7 +98,9 @@ class Projects::DeployKeysController < Projects::ApplicationController
end end
end end
def redirect_to_ci_cd_settings private
redirect_to project_settings_ci_cd_path(@project, anchor: 'js-deploy-keys-settings')
def redirect_to_repository
redirect_to_repository_settings(@project, anchor: 'js-deploy-keys-settings')
end end
end end
...@@ -11,6 +11,10 @@ class Projects::RefsController < Projects::ApplicationController ...@@ -11,6 +11,10 @@ class Projects::RefsController < Projects::ApplicationController
before_action :assign_ref_vars before_action :assign_ref_vars
before_action :authorize_download_code! before_action :authorize_download_code!
before_action only: [:logs_tree] do
push_frontend_feature_flag(:vue_file_list_lfs_badge)
end
def switch def switch
respond_to do |format| respond_to do |format|
format.html do format.html do
......
...@@ -88,7 +88,6 @@ module Projects ...@@ -88,7 +88,6 @@ module Projects
define_triggers_variables define_triggers_variables
define_badges_variables define_badges_variables
define_auto_devops_variables define_auto_devops_variables
define_deploy_keys
end end
def define_runners_variables def define_runners_variables
...@@ -135,10 +134,6 @@ module Projects ...@@ -135,10 +134,6 @@ module Projects
def define_auto_devops_variables def define_auto_devops_variables
@auto_devops = @project.auto_devops || ProjectAutoDevops.new @auto_devops = @project.auto_devops || ProjectAutoDevops.new
end end
def define_deploy_keys
@deploy_keys = DeployKeysPresenter.new(@project, current_user: current_user)
end
end end
end end
end end
......
...@@ -63,6 +63,8 @@ module Projects ...@@ -63,6 +63,8 @@ module Projects
end end
def define_variables def define_variables
@deploy_keys = DeployKeysPresenter.new(@project, current_user: current_user)
define_deploy_token_variables define_deploy_token_variables
define_protected_refs define_protected_refs
remote_mirror remote_mirror
......
...@@ -52,7 +52,7 @@ module ExploreHelper ...@@ -52,7 +52,7 @@ module ExploreHelper
end end
def public_visibility_restricted? def public_visibility_restricted?
Gitlab::CurrentSettings.restricted_visibility_levels&.include? Gitlab::VisibilityLevel::PUBLIC Gitlab::VisibilityLevel.public_visibility_restricted?
end end
private private
......
...@@ -194,6 +194,7 @@ module TreeHelper ...@@ -194,6 +194,7 @@ module TreeHelper
project_path: project.full_path, project_path: project.full_path,
project_short_path: project.path, project_short_path: project.path,
ref: ref, ref: ref,
escaped_ref: ActionDispatch::Journey::Router::Utils.escape_path(ref),
full_name: project.name_with_namespace full_name: project.name_with_namespace
} }
end end
......
...@@ -982,6 +982,8 @@ module Ci ...@@ -982,6 +982,8 @@ module Ci
jwt = Gitlab::Ci::Jwt.for_build(self) jwt = Gitlab::Ci::Jwt.for_build(self)
variables.append(key: 'CI_JOB_JWT', value: jwt, public: false, masked: true) variables.append(key: 'CI_JOB_JWT', value: jwt, public: false, masked: true)
rescue OpenSSL::PKey::RSAError => e
Gitlab::ErrorTracking.track_exception(e)
end end
end end
end end
......
...@@ -17,6 +17,7 @@ module Discussions ...@@ -17,6 +17,7 @@ module Discussions
return unless result return unless result
position = result[:position] position = result[:position]
return unless position
# Currently position data is copied across all notes of a discussion # Currently position data is copied across all notes of a discussion
# It makes sense to store a position only for the first note instead # It makes sense to store a position only for the first note instead
......
...@@ -173,6 +173,10 @@ module Projects ...@@ -173,6 +173,10 @@ module Projects
def create_prometheus_service def create_prometheus_service
service = @project.find_or_initialize_service(::PrometheusService.to_param) service = @project.find_or_initialize_service(::PrometheusService.to_param)
# If the service has already been inserted in the database, that
# means it came from a template, and there's nothing more to do.
return if service.persisted?
if service.prometheus_available? if service.prometheus_available?
service.save! service.save!
else else
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
.mobile-overlay .mobile-overlay
.alert-wrapper .alert-wrapper
= render 'shared/outdated_browser' = render 'shared/outdated_browser'
- if Feature.enabled?(:subscribable_banner_license) - if Feature.enabled?(:subscribable_banner_license, default_enabled: true)
= render_if_exists "layouts/header/ee_subscribable_banner" = render_if_exists "layouts/header/ee_subscribable_banner"
= render "layouts/broadcast" = render "layouts/broadcast"
= render "layouts/header/read_only_banner" = render "layouts/header/read_only_banner"
......
...@@ -4,22 +4,21 @@ ...@@ -4,22 +4,21 @@
- commits = @commits - commits = @commits
- hidden = @hidden_commit_count - hidden = @hidden_commit_count
- commits_count = @commits.size
- commits.chunk { |c| c.committed_date.in_time_zone.to_date }.each do |day, commits| - commits.chunk { |c| c.committed_date.in_time_zone.to_date }.each do |day, daily_commits|
%li.commit-header.js-commit-header{ data: { day: day } } %li.commit-header.js-commit-header{ data: { day: day } }
%span.day= l(day, format: '%d %b, %Y') %span.day= l(day, format: '%d %b, %Y')
%span.commits-count= n_("%d commit", "%d commits", commits_count) % commits_count %span.commits-count= n_("%d commit", "%d commits", daily_commits.size) % daily_commits.size
%li.commits-row{ data: { day: day } } %li.commits-row{ data: { day: day } }
%ul.content-list.commit-list.flex-list %ul.content-list.commit-list.flex-list
= render partial: 'projects/commits/commit', collection: commits, locals: { project: project, ref: ref, merge_request: merge_request } = render partial: 'projects/commits/commit', collection: daily_commits, locals: { project: project, ref: ref, merge_request: merge_request }
- if hidden > 0 - if hidden > 0
%li.alert.alert-warning %li.alert.alert-warning
= 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) = 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)
- if commits_count == 0 - if commits.size == 0
.mt-4.text-center .mt-4.text-center
.bold .bold
= _('Your search didn\'t match any commits.') = _('Your search didn\'t match any commits.')
......
...@@ -51,8 +51,6 @@ ...@@ -51,8 +51,6 @@
.settings-content .settings-content
= render 'ci/variables/index', save_endpoint: project_variables_path(@project) = render 'ci/variables/index', save_endpoint: project_variables_path(@project)
= render @deploy_keys
%section.settings.no-animate#js-pipeline-triggers{ class: ('expanded' if expanded) } %section.settings.no-animate#js-pipeline-triggers{ class: ('expanded' if expanded) }
.settings-header .settings-header
%h4 %h4
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
-# reused in EE. -# reused in EE.
= render "projects/settings/repository/protected_branches" = render "projects/settings/repository/protected_branches"
= render "shared/deploy_tokens/index", group_or_project: @project, description: deploy_token_description = render "shared/deploy_tokens/index", group_or_project: @project, description: deploy_token_description
= render @deploy_keys
= render "projects/cleanup/show" = render "projects/cleanup/show"
= render_if_exists 'shared/promotions/promote_repository_features' = render_if_exists 'shared/promotions/promote_repository_features'
---
title: Fix incorrect commits number in commits list
merge_request: 30412
author:
type: fixed
---
title: Handle possible RSA key exceptions when generating CI_JOB_JWT
merge_request: 30702
author:
type: changed
---
title: Fixes branch name not getting escaped correctly on frontend
merge_request:
author:
type: fixed
---
title: Fix second 500 error with NULL restricted visibility levels
merge_request: 30414
author:
type: fixed
---
title: Disable schema dumping after migrations in production
merge_request: 30812
author:
type: fixed
---
title: Fix errors creating project with active Prometheus service template
merge_request: 30340
author:
type: fixed
---
title: Add LFS badge feature flag to RefsController#logs_tree
merge_request: 30442
author:
type: fixed
...@@ -52,6 +52,9 @@ Rails.application.configure do ...@@ -52,6 +52,9 @@ Rails.application.configure do
# Enable serving of images, stylesheets, and JavaScripts from an asset server # Enable serving of images, stylesheets, and JavaScripts from an asset server
config.action_controller.asset_host = ENV['GITLAB_CDN_HOST'] if ENV['GITLAB_CDN_HOST'].present? config.action_controller.asset_host = ENV['GITLAB_CDN_HOST'] if ENV['GITLAB_CDN_HOST'].present?
# Do not dump schema after migrations.
config.active_record.dump_schema_after_migration = false
# Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added) # Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added)
# config.assets.precompile += %w( search.js ) # config.assets.precompile += %w( search.js )
......
...@@ -312,8 +312,8 @@ GET /projects?custom_attributes[key]=value&custom_attributes[other_key]=other_va ...@@ -312,8 +312,8 @@ GET /projects?custom_attributes[key]=value&custom_attributes[other_key]=other_va
### Pagination limits ### Pagination limits
From GitLab 12.10, [offset-based pagination](README.md#offset-based-pagination) will be From GitLab 13.0, [offset-based pagination](README.md#offset-based-pagination) will be
[limited to 10,000 records](https://gitlab.com/gitlab-org/gitlab/issues/34565). [limited to 50,000 records](https://gitlab.com/gitlab-org/gitlab/issues/34565).
[Keyset pagination](README.md#keyset-based-pagination) will be required to retrieve projects [Keyset pagination](README.md#keyset-based-pagination) will be required to retrieve projects
beyond this limit. beyond this limit.
......
...@@ -288,14 +288,6 @@ https://example.gitlab.com/<namespace>/<project>/badges/<branch>/coverage.svg?st ...@@ -288,14 +288,6 @@ https://example.gitlab.com/<namespace>/<project>/badges/<branch>/coverage.svg?st
[Environment variables](../variables/README.md#gitlab-cicd-environment-variables) can be set in an environment to be available to a runner. [Environment variables](../variables/README.md#gitlab-cicd-environment-variables) can be set in an environment to be available to a runner.
## Deploy Keys
With Deploy Keys, GitLab allows you to import SSH public keys. You can then have
read only or read/write access to your project from the machines the keys were generated from.
SSH keys added to your project settings will be used for continuous integration,
staging, or production servers.
<!-- ## Troubleshooting <!-- ## Troubleshooting
Include any troubleshooting steps that you can foresee. If you know beforehand what issues Include any troubleshooting steps that you can foresee. If you know beforehand what issues
......
...@@ -384,9 +384,7 @@ If you don't have a key pair, you might want to use a ...@@ -384,9 +384,7 @@ If you don't have a key pair, you might want to use a
Project maintainers and owners can add a deploy key for a repository. Project maintainers and owners can add a deploy key for a repository.
1. Navigate to the project's **Settings** page, then: 1. Navigate to the project's **Settings > Repository** page.
- On GitLab 12.8 and earlier, click **Repository**.
- On GitLab 12.9 and later, click **CI / CD**.
1. Expand the **Deploy Keys** section. 1. Expand the **Deploy Keys** section.
1. Specify a title for the new deploy key and paste a public SSH key. 1. Specify a title for the new deploy key and paste a public SSH key.
...@@ -432,9 +430,7 @@ your repository". ...@@ -432,9 +430,7 @@ your repository".
Once a GitLab administrator adds the Global Deployment key, project maintainers Once a GitLab administrator adds the Global Deployment key, project maintainers
and owners can add it by: and owners can add it by:
1. Navigating the settings page: 1. Navigate to the project's **Settings > Repository** page.
- On GitLab 12.8 and earlier, the project's **Settings > Repository** page.
- On GitLab 12.9 and later, the project's **Settings > CI / CD** page.
1. Expanding the **Deploy Keys** section. 1. Expanding the **Deploy Keys** section.
1. Clicking **Enable** next to the appropriate key listed under 1. Clicking **Enable** next to the appropriate key listed under
**Public deploy keys available to any project**. **Public deploy keys available to any project**.
......
...@@ -46,7 +46,7 @@ module API ...@@ -46,7 +46,7 @@ module API
desc 'Add a new terraform state or update an existing one' desc 'Add a new terraform state or update an existing one'
route_setting :authentication, basic_auth_personal_access_token: true route_setting :authentication, basic_auth_personal_access_token: true
post do post do
data = request.body.string data = request.body.read
no_content! if data.empty? no_content! if data.empty?
remote_state_handler.handle_with_lock do |state| remote_state_handler.handle_with_lock do |state|
......
...@@ -82,15 +82,23 @@ module Gitlab ...@@ -82,15 +82,23 @@ module Gitlab
end end
def non_restricted_level?(level) def non_restricted_level?(level)
!restricted_level?(level)
end
def restricted_level?(level)
restricted_levels = Gitlab::CurrentSettings.restricted_visibility_levels restricted_levels = Gitlab::CurrentSettings.restricted_visibility_levels
if restricted_levels.nil? if restricted_levels.nil?
true false
else else
!restricted_levels.include?(level) restricted_levels.include?(level)
end end
end end
def public_visibility_restricted?
restricted_level?(PUBLIC)
end
def valid_level?(level) def valid_level?(level)
options.value?(level) options.value?(level)
end end
......
...@@ -13,16 +13,6 @@ module QA ...@@ -13,16 +13,6 @@ module QA
element :variables_settings_content element :variables_settings_content
end end
view 'app/views/projects/deploy_keys/_index.html.haml' do
element :deploy_keys_settings
end
def expand_deploy_keys(&block)
expand_section(:deploy_keys_settings) do
Settings::DeployKeys.perform(&block)
end
end
def expand_runners_settings(&block) def expand_runners_settings(&block)
expand_section(:runners_settings_content) do expand_section(:runners_settings_content) do
Settings::Runners.perform(&block) Settings::Runners.perform(&block)
......
...@@ -19,12 +19,22 @@ module QA ...@@ -19,12 +19,22 @@ module QA
element :deploy_tokens_settings element :deploy_tokens_settings
end end
view 'app/views/projects/deploy_keys/_index.html.haml' do
element :deploy_keys_settings
end
def expand_deploy_tokens(&block) def expand_deploy_tokens(&block)
expand_section(:deploy_tokens_settings) do expand_section(:deploy_tokens_settings) do
Settings::DeployTokens.perform(&block) Settings::DeployTokens.perform(&block)
end end
end end
def expand_deploy_keys(&block)
expand_section(:deploy_keys_settings) do
Settings::DeployKeys.perform(&block)
end
end
def expand_protected_branches(&block) def expand_protected_branches(&block)
expand_section(:protected_branches_settings) do expand_section(:protected_branches_settings) do
ProtectedBranches.perform(&block) ProtectedBranches.perform(&block)
......
...@@ -6,7 +6,7 @@ module QA ...@@ -6,7 +6,7 @@ module QA
attr_accessor :title, :key attr_accessor :title, :key
attribute :md5_fingerprint do attribute :md5_fingerprint do
Page::Project::Settings::CICD.perform do |setting| Page::Project::Settings::Repository.perform do |setting|
setting.expand_deploy_keys do |key| setting.expand_deploy_keys do |key|
key.find_md5_fingerprint(title) key.find_md5_fingerprint(title)
end end
...@@ -23,9 +23,9 @@ module QA ...@@ -23,9 +23,9 @@ module QA
def fabricate! def fabricate!
project.visit! project.visit!
Page::Project::Menu.perform(&:go_to_ci_cd_settings) Page::Project::Menu.perform(&:go_to_repository_settings)
Page::Project::Settings::CICD.perform do |setting| Page::Project::Settings::Repository.perform do |setting|
setting.expand_deploy_keys do |page| setting.expand_deploy_keys do |page|
page.fill_key_title(title) page.fill_key_title(title)
page.fill_key_value(key) page.fill_key_value(key)
......
...@@ -17,7 +17,7 @@ module QA ...@@ -17,7 +17,7 @@ module QA
expect(deploy_key.md5_fingerprint).to eq key.md5_fingerprint expect(deploy_key.md5_fingerprint).to eq key.md5_fingerprint
Page::Project::Settings::CICD.perform do |setting| Page::Project::Settings::Repository.perform do |setting|
setting.expand_deploy_keys do |keys| setting.expand_deploy_keys do |keys|
expect(keys).to have_key(deploy_key_title, key.md5_fingerprint) expect(keys).to have_key(deploy_key_title, key.md5_fingerprint)
end end
......
...@@ -19,10 +19,10 @@ describe Projects::DeployKeysController do ...@@ -19,10 +19,10 @@ describe Projects::DeployKeysController do
end end
context 'when html requested' do context 'when html requested' do
it 'redirects to project ci / cd settings with the correct anchor' do it 'redirects to project settings with the correct anchor' do
get :index, params: params get :index, params: params
expect(response).to redirect_to(project_settings_ci_cd_path(project, anchor: 'js-deploy-keys-settings')) expect(response).to redirect_to(project_settings_repository_path(project, anchor: 'js-deploy-keys-settings'))
end end
end end
...@@ -87,13 +87,13 @@ describe Projects::DeployKeysController do ...@@ -87,13 +87,13 @@ describe Projects::DeployKeysController do
it 'creates a new deploy key for the project' do it 'creates a new deploy key for the project' do
expect { post :create, params: create_params }.to change(project.deploy_keys, :count).by(1) expect { post :create, params: create_params }.to change(project.deploy_keys, :count).by(1)
expect(response).to redirect_to(project_settings_ci_cd_path(project, anchor: 'js-deploy-keys-settings')) expect(response).to redirect_to(project_settings_repository_path(project, anchor: 'js-deploy-keys-settings'))
end end
it 'redirects to project settings with the correct anchor' do it 'redirects to project settings with the correct anchor' do
post :create, params: create_params post :create, params: create_params
expect(response).to redirect_to(project_settings_ci_cd_path(project, anchor: 'js-deploy-keys-settings')) expect(response).to redirect_to(project_settings_repository_path(project, anchor: 'js-deploy-keys-settings'))
end end
context 'when the deploy key is invalid' do context 'when the deploy key is invalid' do
...@@ -153,7 +153,7 @@ describe Projects::DeployKeysController do ...@@ -153,7 +153,7 @@ describe Projects::DeployKeysController do
expect(DeployKeysProject.where(project_id: project.id, deploy_key_id: deploy_key.id).count).to eq(1) expect(DeployKeysProject.where(project_id: project.id, deploy_key_id: deploy_key.id).count).to eq(1)
expect(response).to have_gitlab_http_status(:found) expect(response).to have_gitlab_http_status(:found)
expect(response).to redirect_to(namespace_project_settings_ci_cd_path(anchor: 'js-deploy-keys-settings')) expect(response).to redirect_to(namespace_project_settings_repository_path(anchor: 'js-deploy-keys-settings'))
end end
it 'returns 404' do it 'returns 404' do
...@@ -175,7 +175,7 @@ describe Projects::DeployKeysController do ...@@ -175,7 +175,7 @@ describe Projects::DeployKeysController do
expect(DeployKeysProject.where(project_id: project.id, deploy_key_id: deploy_key.id).count).to eq(1) expect(DeployKeysProject.where(project_id: project.id, deploy_key_id: deploy_key.id).count).to eq(1)
expect(response).to have_gitlab_http_status(:found) expect(response).to have_gitlab_http_status(:found)
expect(response).to redirect_to(namespace_project_settings_ci_cd_path(anchor: 'js-deploy-keys-settings')) expect(response).to redirect_to(namespace_project_settings_repository_path(anchor: 'js-deploy-keys-settings'))
end end
end end
end end
...@@ -216,7 +216,7 @@ describe Projects::DeployKeysController do ...@@ -216,7 +216,7 @@ describe Projects::DeployKeysController do
put :disable, params: { id: deploy_key.id, namespace_id: project.namespace, project_id: project } put :disable, params: { id: deploy_key.id, namespace_id: project.namespace, project_id: project }
expect(response).to have_gitlab_http_status(:found) expect(response).to have_gitlab_http_status(:found)
expect(response).to redirect_to(namespace_project_settings_ci_cd_path(anchor: 'js-deploy-keys-settings')) expect(response).to redirect_to(namespace_project_settings_repository_path(anchor: 'js-deploy-keys-settings'))
expect { DeployKey.find(deploy_key.id) }.to raise_error(ActiveRecord::RecordNotFound) expect { DeployKey.find(deploy_key.id) }.to raise_error(ActiveRecord::RecordNotFound)
end end
...@@ -239,7 +239,7 @@ describe Projects::DeployKeysController do ...@@ -239,7 +239,7 @@ describe Projects::DeployKeysController do
end.to change { DeployKey.count }.by(-1) end.to change { DeployKey.count }.by(-1)
expect(response).to have_gitlab_http_status(:found) expect(response).to have_gitlab_http_status(:found)
expect(response).to redirect_to(namespace_project_settings_ci_cd_path(anchor: 'js-deploy-keys-settings')) expect(response).to redirect_to(namespace_project_settings_repository_path(anchor: 'js-deploy-keys-settings'))
expect { DeployKey.find(deploy_key.id) }.to raise_error(ActiveRecord::RecordNotFound) expect { DeployKey.find(deploy_key.id) }.to raise_error(ActiveRecord::RecordNotFound)
end end
......
...@@ -17,7 +17,7 @@ describe 'Project deploy keys', :js do ...@@ -17,7 +17,7 @@ describe 'Project deploy keys', :js do
end end
it 'removes association between project and deploy key' do it 'removes association between project and deploy key' do
visit project_settings_ci_cd_path(project) visit project_settings_repository_path(project)
page.within(find('.qa-deploy-keys-settings')) do page.within(find('.qa-deploy-keys-settings')) do
expect(page).to have_selector('.deploy-key', count: 1) expect(page).to have_selector('.deploy-key', count: 1)
......
# frozen_string_literal: true
require 'spec_helper'
describe 'Projects > Settings > CI / CD settings' do
let_it_be(:project) { create(:project_empty_repo) }
let_it_be(:user) { create(:user) }
let_it_be(:role) { :maintainer }
context 'Deploy Keys', :js do
let_it_be(:private_deploy_key) { create(:deploy_key, title: 'private_deploy_key', public: false) }
let_it_be(:public_deploy_key) { create(:another_deploy_key, title: 'public_deploy_key', public: true) }
let(:new_ssh_key) { attributes_for(:key)[:key] }
before do
project.add_role(user, role)
sign_in(user)
end
it 'get list of keys' do
project.deploy_keys << private_deploy_key
project.deploy_keys << public_deploy_key
visit project_settings_ci_cd_path(project)
expect(page).to have_content('private_deploy_key')
expect(page).to have_content('public_deploy_key')
end
it 'add a new deploy key' do
visit project_settings_ci_cd_path(project)
fill_in 'deploy_key_title', with: 'new_deploy_key'
fill_in 'deploy_key_key', with: new_ssh_key
check 'deploy_key_deploy_keys_projects_attributes_0_can_push'
click_button 'Add key'
expect(page).to have_content('new_deploy_key')
expect(page).to have_content('Write access allowed')
end
it 'edit an existing deploy key' do
project.deploy_keys << private_deploy_key
visit project_settings_ci_cd_path(project)
find('.deploy-key', text: private_deploy_key.title).find('.ic-pencil').click
fill_in 'deploy_key_title', with: 'updated_deploy_key'
check 'deploy_key_deploy_keys_projects_attributes_0_can_push'
click_button 'Save changes'
expect(page).to have_content('updated_deploy_key')
expect(page).to have_content('Write access allowed')
end
it 'edit an existing public deploy key to be writable' do
project.deploy_keys << public_deploy_key
visit project_settings_ci_cd_path(project)
find('.deploy-key', text: public_deploy_key.title).find('.ic-pencil').click
check 'deploy_key_deploy_keys_projects_attributes_0_can_push'
click_button 'Save changes'
expect(page).to have_content('public_deploy_key')
expect(page).to have_content('Write access allowed')
end
it 'edit a deploy key from projects user has access to' do
project2 = create(:project_empty_repo)
project2.add_role(user, role)
project2.deploy_keys << private_deploy_key
visit project_settings_ci_cd_path(project)
find('.js-deployKeys-tab-available_project_keys').click
find('.deploy-key', text: private_deploy_key.title).find('.ic-pencil').click
fill_in 'deploy_key_title', with: 'updated_deploy_key'
click_button 'Save changes'
find('.js-deployKeys-tab-available_project_keys').click
expect(page).to have_content('updated_deploy_key')
end
it 'remove an existing deploy key' do
project.deploy_keys << private_deploy_key
visit project_settings_ci_cd_path(project)
accept_confirm { find('.deploy-key', text: private_deploy_key.title).find('.ic-remove').click }
expect(page).not_to have_content(private_deploy_key.title)
end
end
end
...@@ -39,6 +39,89 @@ describe 'Projects > Settings > Repository settings' do ...@@ -39,6 +39,89 @@ describe 'Projects > Settings > Repository settings' do
end end
end end
context 'Deploy Keys', :js do
let_it_be(:private_deploy_key) { create(:deploy_key, title: 'private_deploy_key', public: false) }
let_it_be(:public_deploy_key) { create(:another_deploy_key, title: 'public_deploy_key', public: true) }
let(:new_ssh_key) { attributes_for(:key)[:key] }
it 'get list of keys' do
project.deploy_keys << private_deploy_key
project.deploy_keys << public_deploy_key
visit project_settings_repository_path(project)
expect(page).to have_content('private_deploy_key')
expect(page).to have_content('public_deploy_key')
end
it 'add a new deploy key' do
visit project_settings_repository_path(project)
fill_in 'deploy_key_title', with: 'new_deploy_key'
fill_in 'deploy_key_key', with: new_ssh_key
check 'deploy_key_deploy_keys_projects_attributes_0_can_push'
click_button 'Add key'
expect(page).to have_content('new_deploy_key')
expect(page).to have_content('Write access allowed')
end
it 'edit an existing deploy key' do
project.deploy_keys << private_deploy_key
visit project_settings_repository_path(project)
find('.deploy-key', text: private_deploy_key.title).find('.ic-pencil').click
fill_in 'deploy_key_title', with: 'updated_deploy_key'
check 'deploy_key_deploy_keys_projects_attributes_0_can_push'
click_button 'Save changes'
expect(page).to have_content('updated_deploy_key')
expect(page).to have_content('Write access allowed')
end
it 'edit an existing public deploy key to be writable' do
project.deploy_keys << public_deploy_key
visit project_settings_repository_path(project)
find('.deploy-key', text: public_deploy_key.title).find('.ic-pencil').click
check 'deploy_key_deploy_keys_projects_attributes_0_can_push'
click_button 'Save changes'
expect(page).to have_content('public_deploy_key')
expect(page).to have_content('Write access allowed')
end
it 'edit a deploy key from projects user has access to' do
project2 = create(:project_empty_repo)
project2.add_role(user, role)
project2.deploy_keys << private_deploy_key
visit project_settings_repository_path(project)
find('.js-deployKeys-tab-available_project_keys').click
find('.deploy-key', text: private_deploy_key.title).find('.ic-pencil').click
fill_in 'deploy_key_title', with: 'updated_deploy_key'
click_button 'Save changes'
find('.js-deployKeys-tab-available_project_keys').click
expect(page).to have_content('updated_deploy_key')
end
it 'remove an existing deploy key' do
project.deploy_keys << private_deploy_key
visit project_settings_repository_path(project)
accept_confirm { find('.deploy-key', text: private_deploy_key.title).find('.ic-remove').click }
expect(page).not_to have_content(private_deploy_key.title)
end
end
context 'remote mirror settings' do context 'remote mirror settings' do
before do before do
visit project_settings_repository_path(project) visit project_settings_repository_path(project)
......
...@@ -20,7 +20,7 @@ describe "User interacts with deploy keys", :js do ...@@ -20,7 +20,7 @@ describe "User interacts with deploy keys", :js do
click_button("Enable") click_button("Enable")
expect(page).not_to have_selector(".fa-spinner") expect(page).not_to have_selector(".fa-spinner")
expect(current_path).to eq(project_settings_ci_cd_path(project)) expect(current_path).to eq(project_settings_repository_path(project))
find(".js-deployKeys-tab-enabled_keys").click find(".js-deployKeys-tab-enabled_keys").click
...@@ -96,7 +96,7 @@ describe "User interacts with deploy keys", :js do ...@@ -96,7 +96,7 @@ describe "User interacts with deploy keys", :js do
click_button("Add key") click_button("Add key")
expect(current_path).to eq(project_settings_ci_cd_path(project)) expect(current_path).to eq(project_settings_repository_path(project))
page.within(".deploy-keys") do page.within(".deploy-keys") do
expect(page).to have_content(DEPLOY_KEY_TITLE) expect(page).to have_content(DEPLOY_KEY_TITLE)
......
...@@ -26,7 +26,7 @@ function factory(propsData = {}) { ...@@ -26,7 +26,7 @@ function factory(propsData = {}) {
}, },
}); });
vm.setData({ ref: 'master' }); vm.setData({ escapedRef: 'master' });
} }
describe('Repository table row component', () => { describe('Repository table row component', () => {
......
...@@ -53,7 +53,7 @@ describe('fetchLogsTree', () => { ...@@ -53,7 +53,7 @@ describe('fetchLogsTree', () => {
client = { client = {
readQuery: () => ({ readQuery: () => ({
projectPath: 'gitlab-org/gitlab-foss', projectPath: 'gitlab-org/gitlab-foss',
ref: 'master', escapedRef: 'master',
commits: [], commits: [],
}), }),
writeQuery: jest.fn(), writeQuery: jest.fn(),
...@@ -86,16 +86,18 @@ describe('fetchLogsTree', () => { ...@@ -86,16 +86,18 @@ describe('fetchLogsTree', () => {
it('calls entry resolver', () => it('calls entry resolver', () =>
fetchLogsTree(client, '', '0', resolver).then(() => { fetchLogsTree(client, '', '0', resolver).then(() => {
expect(resolver.resolve).toHaveBeenCalledWith({ expect(resolver.resolve).toHaveBeenCalledWith(
__typename: 'LogTreeCommit', expect.objectContaining({
commitPath: 'https://test.com', __typename: 'LogTreeCommit',
committedDate: '2019-01-01', commitPath: 'https://test.com',
fileName: 'index.js', committedDate: '2019-01-01',
filePath: '/index.js', fileName: 'index.js',
message: 'testing message', filePath: '/index.js',
sha: '123', message: 'testing message',
type: 'blob', sha: '123',
}); type: 'blob',
}),
);
})); }));
it('writes query to client', () => it('writes query to client', () =>
...@@ -104,7 +106,7 @@ describe('fetchLogsTree', () => { ...@@ -104,7 +106,7 @@ describe('fetchLogsTree', () => {
query: expect.anything(), query: expect.anything(),
data: { data: {
commits: [ commits: [
{ expect.objectContaining({
__typename: 'LogTreeCommit', __typename: 'LogTreeCommit',
commitPath: 'https://test.com', commitPath: 'https://test.com',
committedDate: '2019-01-01', committedDate: '2019-01-01',
...@@ -113,7 +115,7 @@ describe('fetchLogsTree', () => { ...@@ -113,7 +115,7 @@ describe('fetchLogsTree', () => {
message: 'testing message', message: 'testing message',
sha: '123', sha: '123',
type: 'blob', type: 'blob',
}, }),
], ],
}, },
}); });
......
...@@ -4,13 +4,12 @@ import createRouter from '~/repository/router'; ...@@ -4,13 +4,12 @@ import createRouter from '~/repository/router';
describe('Repository router spec', () => { describe('Repository router spec', () => {
it.each` it.each`
path | branch | component | componentName path | branch | component | componentName
${'/'} | ${'master'} | ${IndexPage} | ${'IndexPage'} ${'/'} | ${'master'} | ${IndexPage} | ${'IndexPage'}
${'/tree/master'} | ${'master'} | ${TreePage} | ${'TreePage'} ${'/tree/master'} | ${'master'} | ${TreePage} | ${'TreePage'}
${'/-/tree/master'} | ${'master'} | ${TreePage} | ${'TreePage'} ${'/-/tree/master'} | ${'master'} | ${TreePage} | ${'TreePage'}
${'/-/tree/master/app/assets'} | ${'master'} | ${TreePage} | ${'TreePage'} ${'/-/tree/master/app/assets'} | ${'master'} | ${TreePage} | ${'TreePage'}
${'/-/tree/feature/test-%23/app/assets'} | ${'feature/test-#'} | ${TreePage} | ${'TreePage'} ${'/-/tree/123/app/assets'} | ${'master'} | ${null} | ${'null'}
${'/-/tree/123/app/assets'} | ${'master'} | ${null} | ${'null'}
`('sets component as $componentName for path "$path"', ({ path, component, branch }) => { `('sets component as $componentName for path "$path"', ({ path, component, branch }) => {
const router = createRouter('', branch); const router = createRouter('', branch);
......
...@@ -19,23 +19,10 @@ describe ExploreHelper do ...@@ -19,23 +19,10 @@ describe ExploreHelper do
end end
describe '#public_visibility_restricted?' do describe '#public_visibility_restricted?' do
using RSpec::Parameterized::TableSyntax it 'delegates to Gitlab::VisibilityLevel' do
expect(Gitlab::VisibilityLevel).to receive(:public_visibility_restricted?).and_call_original
where(:visibility_levels, :expected_status) do helper.public_visibility_restricted?
nil | nil
[Gitlab::VisibilityLevel::PRIVATE] | false
[Gitlab::VisibilityLevel::PRIVATE, Gitlab::VisibilityLevel::INTERNAL] | false
[Gitlab::VisibilityLevel::PUBLIC] | true
end
with_them do
before do
stub_application_setting(restricted_visibility_levels: visibility_levels)
end
it 'returns the expected status' do
expect(helper.public_visibility_restricted?).to eq(expected_status)
end
end end
end end
end end
...@@ -96,6 +96,30 @@ describe Gitlab::VisibilityLevel do ...@@ -96,6 +96,30 @@ describe Gitlab::VisibilityLevel do
end end
end end
describe '.restricted_level?, .non_restricted_level?, and .public_level_restricted?' do
using RSpec::Parameterized::TableSyntax
where(:visibility_levels, :expected_status) do
nil | false
[Gitlab::VisibilityLevel::PRIVATE] | false
[Gitlab::VisibilityLevel::PRIVATE, Gitlab::VisibilityLevel::INTERNAL] | false
[Gitlab::VisibilityLevel::PUBLIC] | true
[Gitlab::VisibilityLevel::PUBLIC, Gitlab::VisibilityLevel::INTERNAL] | true
end
with_them do
before do
stub_application_setting(restricted_visibility_levels: visibility_levels)
end
it 'returns the expected status' do
expect(described_class.restricted_level?(Gitlab::VisibilityLevel::PUBLIC)).to eq(expected_status)
expect(described_class.non_restricted_level?(Gitlab::VisibilityLevel::PUBLIC)).to eq(!expected_status)
expect(described_class.public_visibility_restricted?).to eq(expected_status)
end
end
end
describe '#visibility_level_decreased?' do describe '#visibility_level_decreased?' do
let(:project) { create(:project, :internal) } let(:project) { create(:project, :internal) }
......
...@@ -2350,6 +2350,16 @@ describe Ci::Build do ...@@ -2350,6 +2350,16 @@ describe Ci::Build do
end end
end end
context 'when CI_JOB_JWT generation fails' do
it 'CI_JOB_JWT is not included' do
expect(Gitlab::Ci::Jwt).to receive(:for_build).and_raise(OpenSSL::PKey::RSAError, 'Neither PUB key nor PRIV key: not enough data')
expect(Gitlab::ErrorTracking).to receive(:track_exception)
expect { subject }.not_to raise_error
expect(subject.pluck(:key)).not_to include('CI_JOB_JWT')
end
end
describe 'variables ordering' do describe 'variables ordering' do
context 'when variables hierarchy is stubbed' do context 'when variables hierarchy is stubbed' do
let(:build_pre_var) { { key: 'build', value: 'value', public: true, masked: false } } let(:build_pre_var) { { key: 'build', value: 'value', public: true, masked: false } }
......
...@@ -3,10 +3,11 @@ ...@@ -3,10 +3,11 @@
require 'spec_helper' require 'spec_helper'
describe Discussions::CaptureDiffNotePositionService do describe Discussions::CaptureDiffNotePositionService do
subject { described_class.new(note.noteable, paths) }
context 'image note on diff' do context 'image note on diff' do
let!(:note) { create(:image_diff_note_on_merge_request) } let!(:note) { create(:image_diff_note_on_merge_request) }
let(:paths) { ['files/images/any_image.png'] }
subject { described_class.new(note.noteable, ['files/images/any_image.png']) }
it 'is note affected by the service' do it 'is note affected by the service' do
expect(Gitlab::Diff::PositionTracer).not_to receive(:new) expect(Gitlab::Diff::PositionTracer).not_to receive(:new)
...@@ -18,8 +19,7 @@ describe Discussions::CaptureDiffNotePositionService do ...@@ -18,8 +19,7 @@ describe Discussions::CaptureDiffNotePositionService do
context 'when empty paths are passed as a param' do context 'when empty paths are passed as a param' do
let!(:note) { create(:diff_note_on_merge_request) } let!(:note) { create(:diff_note_on_merge_request) }
let(:paths) { [] }
subject { described_class.new(note.noteable, []) }
it 'does not calculate positons' do it 'does not calculate positons' do
expect(Gitlab::Diff::PositionTracer).not_to receive(:new) expect(Gitlab::Diff::PositionTracer).not_to receive(:new)
...@@ -28,4 +28,19 @@ describe Discussions::CaptureDiffNotePositionService do ...@@ -28,4 +28,19 @@ describe Discussions::CaptureDiffNotePositionService do
expect(note.diff_note_positions).to be_empty expect(note.diff_note_positions).to be_empty
end end
end end
context 'when position tracer returned nil position' do
let!(:note) { create(:diff_note_on_merge_request) }
let(:paths) { ['files/any_file.txt'] }
it 'does not create diff note position' do
expect(note.noteable).to receive(:merge_ref_head).and_return(double.as_null_object)
expect_next_instance_of(Gitlab::Diff::PositionTracer) do |tracer|
expect(tracer).to receive(:trace).and_return({ position: nil })
end
expect(subject.execute(note.discussion)).to eq(nil)
expect(note.diff_note_positions).to be_empty
end
end
end end
...@@ -348,6 +348,7 @@ describe Projects::CreateService, '#execute' do ...@@ -348,6 +348,7 @@ describe Projects::CreateService, '#execute' do
project = create_project(user, opts) project = create_project(user, opts)
expect(project.services.count).to eq 1 expect(project.services.count).to eq 1
expect(project.errors).to be_empty
end end
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment