Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2020-07-27 15:09:25 +00:00
parent 8827c1d184
commit e69aae81ea
26 changed files with 153 additions and 195 deletions

View File

@ -41,7 +41,7 @@ gem 'omniauth-oauth2-generic', '~> 0.2.2'
gem 'omniauth-saml', '~> 1.10' gem 'omniauth-saml', '~> 1.10'
gem 'omniauth-shibboleth', '~> 1.3.0' gem 'omniauth-shibboleth', '~> 1.3.0'
gem 'omniauth-twitter', '~> 1.4' gem 'omniauth-twitter', '~> 1.4'
gem 'omniauth_crowd', '~> 2.2.0' gem 'omniauth_crowd', '~> 2.4.0'
gem 'omniauth-authentiq', '~> 0.3.3' gem 'omniauth-authentiq', '~> 0.3.3'
gem 'omniauth_openid_connect', '~> 0.3.5' gem 'omniauth_openid_connect', '~> 0.3.5'
gem 'omniauth-salesforce', '~> 1.0.5' gem 'omniauth-salesforce', '~> 1.0.5'
@ -188,7 +188,7 @@ gem 'acts-as-taggable-on', '~> 6.0'
# Background jobs # Background jobs
gem 'sidekiq', '~> 5.2.7' gem 'sidekiq', '~> 5.2.7'
gem 'sidekiq-cron', '~> 1.0' gem 'sidekiq-cron', '~> 1.0'
gem 'redis-namespace', '~> 1.6.0' gem 'redis-namespace', '~> 1.7.0'
gem 'gitlab-sidekiq-fetcher', '0.5.2', require: 'sidekiq-reliable-fetch' gem 'gitlab-sidekiq-fetcher', '0.5.2', require: 'sidekiq-reliable-fetch'
# Cron Parser # Cron Parser

View File

@ -740,7 +740,7 @@ GEM
omniauth-twitter (1.4.0) omniauth-twitter (1.4.0)
omniauth-oauth (~> 1.1) omniauth-oauth (~> 1.1)
rack rack
omniauth_crowd (2.2.3) omniauth_crowd (2.4.0)
activesupport activesupport
nokogiri (>= 1.4.4) nokogiri (>= 1.4.4)
omniauth (~> 1.0) omniauth (~> 1.0)
@ -877,7 +877,7 @@ GEM
redis-activesupport (5.2.0) redis-activesupport (5.2.0)
activesupport (>= 3, < 7) activesupport (>= 3, < 7)
redis-store (>= 1.3, < 2) redis-store (>= 1.3, < 2)
redis-namespace (1.6.0) redis-namespace (1.7.0)
redis (>= 3.0.4) redis (>= 3.0.4)
redis-rack (2.1.2) redis-rack (2.1.2)
rack (>= 2.0.8, < 3) rack (>= 2.0.8, < 3)
@ -1337,7 +1337,7 @@ DEPENDENCIES
omniauth-saml (~> 1.10) omniauth-saml (~> 1.10)
omniauth-shibboleth (~> 1.3.0) omniauth-shibboleth (~> 1.3.0)
omniauth-twitter (~> 1.4) omniauth-twitter (~> 1.4)
omniauth_crowd (~> 2.2.0) omniauth_crowd (~> 2.4.0)
omniauth_openid_connect (~> 0.3.5) omniauth_openid_connect (~> 0.3.5)
org-ruby (~> 0.9.12) org-ruby (~> 0.9.12)
parallel (~> 1.19) parallel (~> 1.19)
@ -1365,7 +1365,7 @@ DEPENDENCIES
re2 (~> 1.2.0) re2 (~> 1.2.0)
recaptcha (~> 4.11) recaptcha (~> 4.11)
redis (~> 4.0) redis (~> 4.0)
redis-namespace (~> 1.6.0) redis-namespace (~> 1.7.0)
redis-rails (~> 5.0.2) redis-rails (~> 5.0.2)
request_store (~> 1.5) request_store (~> 1.5)
responders (~> 3.0) responders (~> 3.0)

View File

@ -11,7 +11,7 @@ import {
} from '@gitlab/ui'; } from '@gitlab/ui';
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue'; import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import { s__ } from '~/locale'; import { s__ } from '~/locale';
import { mergeUrlParams } from '~/lib/utils/url_utility'; import { mergeUrlParams, joinPaths, visitUrl } from '~/lib/utils/url_utility';
import getIncidents from '../graphql/queries/get_incidents.query.graphql'; import getIncidents from '../graphql/queries/get_incidents.query.graphql';
import { I18N } from '../constants'; import { I18N } from '../constants';
@ -19,7 +19,7 @@ const tdClass =
'table-col gl-display-flex d-md-table-cell gl-align-items-center gl-white-space-nowrap'; 'table-col gl-display-flex d-md-table-cell gl-align-items-center gl-white-space-nowrap';
const thClass = 'gl-hover-bg-blue-50'; const thClass = 'gl-hover-bg-blue-50';
const bodyTrClass = const bodyTrClass =
'gl-border-1 gl-border-t-solid gl-border-gray-100 gl-hover-bg-blue-50 gl-hover-border-b-solid gl-hover-border-blue-200'; 'gl-border-1 gl-border-t-solid gl-border-gray-100 gl-hover-cursor-pointer gl-hover-bg-blue-50 gl-hover-border-b-solid gl-hover-border-blue-200';
export default { export default {
i18n: I18N, i18n: I18N,
@ -56,7 +56,7 @@ export default {
directives: { directives: {
GlTooltip: GlTooltipDirective, GlTooltip: GlTooltipDirective,
}, },
inject: ['projectPath', 'newIssuePath', 'incidentTemplateName'], inject: ['projectPath', 'newIssuePath', 'incidentTemplateName', 'issuePath'],
apollo: { apollo: {
incidents: { incidents: {
query: getIncidents, query: getIncidents,
@ -102,6 +102,9 @@ export default {
hasAssignees(assignees) { hasAssignees(assignees) {
return Boolean(assignees.nodes?.length); return Boolean(assignees.nodes?.length);
}, },
navigateToIncidentDetails({ iid }) {
return visitUrl(joinPaths(this.issuePath, iid));
},
}, },
}; };
</script> </script>
@ -138,6 +141,7 @@ export default {
:tbody-tr-class="tbodyTrClass" :tbody-tr-class="tbodyTrClass"
:no-local-sorting="true" :no-local-sorting="true"
fixed fixed
@row-clicked="navigateToIncidentDetails"
> >
<template #cell(title)="{ item }"> <template #cell(title)="{ item }">
<div class="gl-max-w-full text-truncate" :title="item.title">{{ item.title }}</div> <div class="gl-max-w-full text-truncate" :title="item.title">{{ item.title }}</div>

View File

@ -8,7 +8,7 @@ export default () => {
const selector = '#js-incidents'; const selector = '#js-incidents';
const domEl = document.querySelector(selector); const domEl = document.querySelector(selector);
const { projectPath, newIssuePath, incidentTemplateName } = domEl.dataset; const { projectPath, newIssuePath, incidentTemplateName, issuePath } = domEl.dataset;
const apolloProvider = new VueApollo({ const apolloProvider = new VueApollo({
defaultClient: createDefaultClient(), defaultClient: createDefaultClient(),
@ -20,6 +20,7 @@ export default () => {
projectPath, projectPath,
incidentTemplateName, incidentTemplateName,
newIssuePath, newIssuePath,
issuePath,
}, },
apolloProvider, apolloProvider,
components: { components: {

View File

@ -15,12 +15,7 @@ module Groups
end end
def update def update
update_result = Ci::ChangeVariablesService.new( if @group.update(group_variables_params)
container: @group, current_user: current_user,
params: group_variables_params
).execute
if update_result
respond_to do |format| respond_to do |format|
format.json { render_group_variables } format.json { render_group_variables }
end end

View File

@ -5,7 +5,8 @@ module Projects::IncidentsHelper
{ {
'project-path' => project.full_path, 'project-path' => project.full_path,
'new-issue-path' => new_project_issue_path(project), 'new-issue-path' => new_project_issue_path(project),
'incident-template-name' => 'incident' 'incident-template-name' => 'incident',
'issue-path' => project_issues_path(project)
} }
end end
end end

View File

@ -1,28 +0,0 @@
# frozen_string_literal: true
module Ci
class ChangeVariableService < BaseContainerService
def execute
case params[:action]
when :create
container.variables.create(params[:variable_params])
when :update
variable.tap do |target_variable|
target_variable.update(params[:variable_params].except(:key))
end
when :destroy
variable.tap do |target_variable|
target_variable.destroy
end
end
end
private
def variable
container.variables.find_by!(params[:variable_params].slice(:key)) # rubocop:disable CodeReuse/ActiveRecord
end
end
end
::Ci::ChangeVariableService.prepend_if_ee('EE::Ci::ChangeVariableService')

View File

@ -1,11 +0,0 @@
# frozen_string_literal: true
module Ci
class ChangeVariablesService < BaseContainerService
def execute
container.update(params)
end
end
end
::Ci::ChangeVariablesService.prepend_if_ee('EE::Ci::ChangeVariablesService')

View File

@ -1,4 +1,4 @@
%li %li{ data: { qa_selector: 'wiki_directory_content' } }
= wiki_directory.slug = wiki_directory.slug
%ul %ul
= render wiki_directory.pages, context: context = render wiki_directory.pages, context: context

View File

@ -0,0 +1,5 @@
---
title: Add link to issue details page from Incident list page
merge_request: 37814
author:
type: other

View File

@ -126,6 +126,33 @@ these epics/issues:
- [Unreplicated Data Types](https://gitlab.com/groups/gitlab-org/-/epics/893) - [Unreplicated Data Types](https://gitlab.com/groups/gitlab-org/-/epics/893)
- [Verify all replicated data](https://gitlab.com/groups/gitlab-org/-/epics/1430) - [Verify all replicated data](https://gitlab.com/groups/gitlab-org/-/epics/1430)
### Replicated data types behind a feature flag
The replication for some data types is behind a corresponding feature flag:
> - They're deployed behind a feature flag, enabled by default.
> - They're enabled on GitLab.com.
> - They can't be enabled or disabled per-project.
> - They are recommended for production use.
> - For GitLab self-managed instances, GitLab administrators can opt to [disable them](#enable-or-disable-replication-for-some-data-types-core-only). **(CORE ONLY)**
#### Enable or disable replication (for some data types) **(CORE ONLY)**
Replication for some data types are released behind feature flags that are **enabled by default**.
[GitLab administrators with access to the GitLab Rails console](../../feature_flags.md) can opt to disable it for your instance. You can find feature flag names of each of those data types in the notes column of the table below.
To disable, such as for package file replication:
```ruby
Feature.disable(:geo_package_file_replication)
```
To enable, such as for package file replication:
```ruby
Feature.enable(:geo_package_file_replication)
```
DANGER: **Danger:** DANGER: **Danger:**
Features not on this list, or with **No** in the **Replicated** column, Features not on this list, or with **No** in the **Replicated** column,
are not replicated on the **secondary** node. Failing over without manually are not replicated on the **secondary** node. Failing over without manually
@ -151,12 +178,12 @@ successfully, you must replicate their data using some other means.
| [Elasticsearch integration](../../../integration/elasticsearch.md) | [No](https://gitlab.com/gitlab-org/gitlab/-/issues/1186) | No | | | [Elasticsearch integration](../../../integration/elasticsearch.md) | [No](https://gitlab.com/gitlab-org/gitlab/-/issues/1186) | No | |
| [GitLab Pages](../../pages/index.md) | [No](https://gitlab.com/groups/gitlab-org/-/epics/589) | No | | | [GitLab Pages](../../pages/index.md) | [No](https://gitlab.com/groups/gitlab-org/-/epics/589) | No | |
| [Container Registry](../../packages/container_registry.md) | **Yes** (12.3) | No | | | [Container Registry](../../packages/container_registry.md) | **Yes** (12.3) | No | |
| [NPM Registry](../../../user/packages/npm_registry/index.md) | **Yes** (13.2) | No | | | [NPM Registry](../../../user/packages/npm_registry/index.md) | **Yes** (13.2) | No | Behind feature flag `geo_package_file_replication`, enabled by default | |
| [Maven Repository](../../../user/packages/maven_repository/index.md) | **Yes** (13.2) | No | | | [Maven Repository](../../../user/packages/maven_repository/index.md) | **Yes** (13.2) | No | Behind feature flag `geo_package_file_replication`, enabled by default | |
| [Conan Repository](../../../user/packages/conan_repository/index.md) | **Yes** (13.2) | No | | | [Conan Repository](../../../user/packages/conan_repository/index.md) | **Yes** (13.2) | No | Behind feature flag `geo_package_file_replication`, enabled by default | |
| [NuGet Repository](../../../user/packages/nuget_repository/index.md) | **Yes** (13.2) | No | | | [NuGet Repository](../../../user/packages/nuget_repository/index.md) | **Yes** (13.2) | No | Behind feature flag `geo_package_file_replication`, enabled by default | |
| [PyPi Repository](../../../user/packages/pypi_repository/index.md) | **Yes** (13.2) | No | | | [PyPi Repository](../../../user/packages/pypi_repository/index.md) | **Yes** (13.2) | No | Behind feature flag `geo_package_file_replication`, enabled by default | |
| [Composer Repository](../../../user/packages/composer_repository/index.md) | **Yes** (13.2) | No | | | [Composer Repository](../../../user/packages/composer_repository/index.md) | **Yes** (13.2) | No | Behind feature flag `geo_package_file_replication`, enabled by default | |
| [External merge request diffs](../../merge_request_diffs.md) | [No](https://gitlab.com/gitlab-org/gitlab/-/issues/33817) | No | | | [External merge request diffs](../../merge_request_diffs.md) | [No](https://gitlab.com/gitlab-org/gitlab/-/issues/33817) | No | |
| [Terraform State](../../terraform_state.md) | [No](https://gitlab.com/groups/gitlab-org/-/epics/3112)(*3*) | No | | | [Terraform State](../../terraform_state.md) | [No](https://gitlab.com/groups/gitlab-org/-/epics/3112)(*3*) | No | |
| [Vulnerability Export](../../../user/application_security/security_dashboard/#export-vulnerabilities) | [No](https://gitlab.com/groups/gitlab-org/-/epics/3111)(*3*) | No | | | | [Vulnerability Export](../../../user/application_security/security_dashboard/#export-vulnerabilities) | [No](https://gitlab.com/groups/gitlab-org/-/epics/3111)(*3*) | No | | |

View File

@ -141,7 +141,15 @@ keeping in mind the task name in this case is `gitlab:uploads:migrate_to_local`.
To migrate uploads from object storage to local storage: To migrate uploads from object storage to local storage:
1. Disable both `direct_upload` and `background_upload` under `uploads` settings in `gitlab.rb`. 1. Disable both `direct_upload` and `background_upload` under `uploads` settings in `gitlab.rb`:
```ruby
gitlab_rails['uploads_object_store_direct_upload'] = false
gitlab_rails['uploads_object_store_background_upload'] = false
```
Save the file and [reconfigure GitLab](../../restart_gitlab.md#omnibus-gitlab-reconfigure).
1. Run the Rake task: 1. Run the Rake task:
**Omnibus Installation** **Omnibus Installation**

View File

@ -15,16 +15,15 @@ There are several messages that can be displayed depending on the status of the
### "Checking pipeline status" ### "Checking pipeline status"
This message is shown when the merge request has no pipeline associated with the latest commit yet and [Pipelines must succeed](../user/project/merge_requests/merge_when_pipeline_succeeds.md#only-allow-merge-requests-to-be-merged-if-the-pipeline-succeeds) is turned on. This might be because: This message is shown when the merge request has no pipeline associated with the latest commit yet. This might be because:
- GitLab hasn't finished creating the pipeline yet. - GitLab hasn't finished creating the pipeline yet.
- You are using an external CI service and GitLab hasn't heard back from the service yet. - You are using an external CI service and GitLab hasn't heard back from the service yet.
- You are not using CI/CD pipelines in your project. - You are not using CI/CD pipelines in your project.
- The latest pipeline was deleted (this is a [known issue](https://gitlab.com/gitlab-org/gitlab/-/issues/214323)).
After the pipeline is created, the message will update with the pipeline status. After the pipeline is created, the message will update with the pipeline status.
Note: Currently if you delete the latest pipeline of a Merge Request, this message will be shown instead of a meaningful error message. This is a known issue and should be resolved soon.
## Merge request ability to merge widget ## Merge request ability to merge widget
The merge request status widget shows the **Merge** button and whether or not a merge request is ready to merge. If the merge request can't be merged, the reason for this is displayed. The merge request status widget shows the **Merge** button and whether or not a merge request is ready to merge. If the merge request can't be merged, the reason for this is displayed.

View File

@ -90,6 +90,14 @@ module Geo
def self.model def self.model
::Packages::PackageFile ::Packages::PackageFile
end end
# Change this to `true` to release replication of this model. Then remove
# this override in the next release.
# The feature flag follows the format `geo_#{replicable_name}_replication`,
# so here it would be `geo_package_file_replication`
def self.replication_enabled_by_default?
false
end
end end
end end
``` ```

View File

@ -69,6 +69,8 @@ You can filter the vulnerabilities by:
- Severity - Severity
- Report type - Report type
By default, detected and confirmed vulnerabilities will be displayed.
You can also dismiss vulnerabilities in the table: You can also dismiss vulnerabilities in the table:
1. Select the checkbox for each vulnerability you want to dismiss. 1. Select the checkbox for each vulnerability you want to dismiss.
@ -97,6 +99,8 @@ You can filter which vulnerabilities the Security Dashboard displays by:
- Report type - Report type
- Project - Project
By default, detected and confirmed vulnerabilities will be displayed.
A table lists the vulnerabilities, sorted by severity. The table shows each vulnerability's status, A table lists the vulnerabilities, sorted by severity. The table shows each vulnerability's status,
severity, and description. Clicking a vulnerability takes you to its [Vulnerability Details](../vulnerabilities) severity, and description. Clicking a vulnerability takes you to its [Vulnerability Details](../vulnerabilities)
page to view more information about that vulnerability. page to view more information about that vulnerability.

View File

@ -51,11 +51,9 @@ module API
optional :variable_type, type: String, values: ::Ci::GroupVariable.variable_types.keys, desc: 'The type of variable, must be one of env_var or file. Defaults to env_var' optional :variable_type, type: String, values: ::Ci::GroupVariable.variable_types.keys, desc: 'The type of variable, must be one of env_var or file. Defaults to env_var'
end end
post ':id/variables' do post ':id/variables' do
variable = ::Ci::ChangeVariableService.new( variable_params = declared_params(include_missing: false)
container: user_group,
current_user: current_user, variable = user_group.variables.create(variable_params)
params: { action: :create, variable_params: declared_params(include_missing: false) }
).execute
if variable.valid? if variable.valid?
present variable, with: Entities::Variable present variable, with: Entities::Variable
@ -76,19 +74,17 @@ module API
end end
# rubocop: disable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord
put ':id/variables/:key' do put ':id/variables/:key' do
variable = ::Ci::ChangeVariableService.new( variable = user_group.variables.find_by(key: params[:key])
container: user_group,
current_user: current_user,
params: { action: :update, variable_params: declared_params(include_missing: false) }
).execute
if variable.valid? break not_found!('GroupVariable') unless variable
variable_params = declared_params(include_missing: false).except(:key)
if variable.update(variable_params)
present variable, with: Entities::Variable present variable, with: Entities::Variable
else else
render_validation_error!(variable) render_validation_error!(variable)
end end
rescue ::ActiveRecord::RecordNotFound
not_found!('GroupVariable')
end end
# rubocop: enable CodeReuse/ActiveRecord # rubocop: enable CodeReuse/ActiveRecord
@ -100,17 +96,10 @@ module API
end end
# rubocop: disable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord
delete ':id/variables/:key' do delete ':id/variables/:key' do
variable = user_group.variables.find_by!(key: params[:key]) variable = user_group.variables.find_by(key: params[:key])
not_found!('GroupVariable') unless variable
destroy_conditionally!(variable) do |target_variable| destroy_conditionally!(variable)
::Ci::ChangeVariableService.new(
container: user_group,
current_user: current_user,
params: { action: :destroy, variable_params: declared_params(include_missing: false) }
).execute
end
rescue ::ActiveRecord::RecordNotFound
not_found!('GroupVariable')
end end
# rubocop: enable CodeReuse/ActiveRecord # rubocop: enable CodeReuse/ActiveRecord
end end

View File

@ -4,7 +4,7 @@ gem 'gitlab-qa'
gem 'activesupport', '~> 6.0.3.1' # This should stay in sync with the root's Gemfile gem 'activesupport', '~> 6.0.3.1' # This should stay in sync with the root's Gemfile
gem 'capybara', '~> 3.29.0' gem 'capybara', '~> 3.29.0'
gem 'capybara-screenshot', '~> 1.0.23' gem 'capybara-screenshot', '~> 1.0.23'
gem 'rake', '~> 12.3.0' gem 'rake', '~> 12.3.3'
gem 'rspec', '~> 3.7' gem 'rspec', '~> 3.7'
gem 'selenium-webdriver', '~> 3.12' gem 'selenium-webdriver', '~> 3.12'
gem 'airborne', '~> 0.3.4' gem 'airborne', '~> 0.3.4'

View File

@ -128,7 +128,7 @@ DEPENDENCIES
nokogiri (~> 1.10.9) nokogiri (~> 1.10.9)
parallel_tests (~> 2.29) parallel_tests (~> 2.29)
pry-byebug (~> 3.5.1) pry-byebug (~> 3.5.1)
rake (~> 12.3.0) rake (~> 12.3.3)
rest-client (~> 2.1.0) rest-client (~> 2.1.0)
rotp (~> 3.1.0) rotp (~> 3.1.0)
rspec (~> 3.7) rspec (~> 3.7)

View File

@ -2,7 +2,7 @@ GEM
remote: https://rubygems.org/ remote: https://rubygems.org/
specs: specs:
rack (2.0.6) rack (2.0.6)
rake (12.3.0) rake (12.3.3)
PLATFORMS PLATFORMS
ruby ruby
@ -12,4 +12,4 @@ DEPENDENCIES
rake rake
BUNDLED WITH BUNDLED WITH
1.17.1 1.17.3

View File

@ -18,6 +18,10 @@ module QA
base.view 'app/views/shared/wikis/_sidebar_wiki_page.html.haml' do base.view 'app/views/shared/wikis/_sidebar_wiki_page.html.haml' do
element :wiki_page_link element :wiki_page_link
end end
base.view 'app/views/shared/wikis/_wiki_directory.html.haml' do
element :wiki_directory_content
end
end end
def click_clone_repository def click_clone_repository
@ -35,6 +39,10 @@ module QA
def has_page_listed?(page_title) def has_page_listed?(page_title)
has_element? :wiki_page_link, page_name: page_title has_element? :wiki_page_link, page_name: page_title
end end
def has_directory?(directory)
has_element? :wiki_directory_content, text: directory
end
end end
end end
end end

View File

@ -0,0 +1,31 @@
# frozen_string_literal: true
module QA
RSpec.describe 'Create' do
context 'Wiki' do
let(:initial_wiki) { Resource::Wiki::ProjectPage.fabricate_via_api! }
let(:new_path) { "a/new/path" }
before do
Flow::Login.sign_in
end
it 'has changed the directory' do
initial_wiki.visit!
Page::Project::Wiki::Show.perform(&:click_edit)
Page::Project::Wiki::Edit.perform do |edit|
edit.set_title("#{new_path}/home")
edit.set_message('changing the path of the home page')
end
Page::Project::Wiki::Edit.perform(&:click_save_changes)
Page::Project::Wiki::Show.perform do |wiki|
expect(wiki).to have_directory(new_path)
end
end
end
end
end

View File

@ -1,10 +1,17 @@
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import { GlAlert, GlLoadingIcon, GlTable, GlAvatar } from '@gitlab/ui'; import { GlAlert, GlLoadingIcon, GlTable, GlAvatar } from '@gitlab/ui';
import { visitUrl, joinPaths } from '~/lib/utils/url_utility';
import IncidentsList from '~/incidents/components/incidents_list.vue'; import IncidentsList from '~/incidents/components/incidents_list.vue';
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue'; import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import { I18N } from '~/incidents/constants'; import { I18N } from '~/incidents/constants';
import mockIncidents from '../mocks/incidents.json'; import mockIncidents from '../mocks/incidents.json';
jest.mock('~/lib/utils/url_utility', () => ({
visitUrl: jest.fn().mockName('visitUrlMock'),
joinPaths: jest.fn().mockName('joinPaths'),
mergeUrlParams: jest.fn().mockName('mergeUrlParams'),
}));
describe('Incidents List', () => { describe('Incidents List', () => {
let wrapper; let wrapper;
const newIssuePath = 'namespace/project/-/issues/new'; const newIssuePath = 'namespace/project/-/issues/new';
@ -36,6 +43,7 @@ describe('Incidents List', () => {
projectPath: '/project/path', projectPath: '/project/path',
newIssuePath, newIssuePath,
incidentTemplateName, incidentTemplateName,
issuePath: '/project/isssues',
}, },
stubs: { stubs: {
GlButton: true, GlButton: true,
@ -111,6 +119,13 @@ describe('Incidents List', () => {
expect(label).toBe(name); expect(label).toBe(name);
expect(src).toBe(avatarUrl); expect(src).toBe(avatarUrl);
}); });
it('contains a link to the issue details', () => {
findTableRows()
.at(0)
.trigger('click');
expect(visitUrl).toHaveBeenCalledWith(joinPaths(`/project/isssues/`, mockIncidents[0].iid));
});
}); });
}); });
@ -124,9 +139,6 @@ describe('Incidents List', () => {
it('shows the button linking to new incidents page with prefilled incident template', () => { it('shows the button linking to new incidents page with prefilled incident template', () => {
expect(findCreateIncidentBtn().exists()).toBe(true); expect(findCreateIncidentBtn().exists()).toBe(true);
expect(findCreateIncidentBtn().attributes('href')).toBe(
`${newIssuePath}?issuable_template=${incidentTemplateName}`,
);
}); });
it('sets button loading on click', () => { it('sets button loading on click', () => {

View File

@ -8,6 +8,7 @@ RSpec.describe Projects::IncidentsHelper do
let(:project) { create(:project) } let(:project) { create(:project) }
let(:project_path) { project.full_path } let(:project_path) { project.full_path }
let(:new_issue_path) { new_project_issue_path(project) } let(:new_issue_path) { new_project_issue_path(project) }
let(:issue_path) { project_issues_path(project) }
describe '#incidents_data' do describe '#incidents_data' do
subject(:data) { helper.incidents_data(project) } subject(:data) { helper.incidents_data(project) }
@ -16,7 +17,8 @@ RSpec.describe Projects::IncidentsHelper do
expect(data).to match( expect(data).to match(
'project-path' => project_path, 'project-path' => project_path,
'new-issue-path' => new_issue_path, 'new-issue-path' => new_issue_path,
'incident-template-name' => 'incident' 'incident-template-name' => 'incident',
'issue-path' => issue_path
) )
end end
end end

View File

@ -169,14 +169,6 @@ RSpec.describe API::GroupVariables do
expect(response).to have_gitlab_http_status(:not_found) expect(response).to have_gitlab_http_status(:not_found)
end end
it 'responds with 400 if the update fails' do
put api("/groups/#{group.id}/variables/#{variable.key}", user), params: { value: 'shrt', masked: true }
expect(response).to have_gitlab_http_status(:bad_request)
expect(variable.reload.masked).to eq(false)
expect(json_response['message']).to eq('value' => ['is invalid'])
end
end end
context 'authorized user with invalid permissions' do context 'authorized user with invalid permissions' do

View File

@ -1,68 +0,0 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Ci::ChangeVariableService do
let(:service) { described_class.new(container: group, current_user: user, params: params) }
let_it_be(:user) { create(:user) }
let(:group) { create(:group) }
describe '#execute' do
subject(:execute) { service.execute }
context 'when creating a variable' do
let(:params) { { variable_params: { key: 'new_variable', value: 'variable_value' }, action: :create } }
it 'persists a variable' do
expect { execute }.to change(Ci::GroupVariable, :count).from(0).to(1)
end
end
context 'when updating a variable' do
let!(:variable) { create(:ci_group_variable, value: 'old_value') }
let(:params) { { variable_params: { key: variable.key, value: 'new_value' }, action: :update } }
before do
group.variables << variable
end
it 'updates a variable' do
expect { execute }.to change { variable.reload.value }.from('old_value').to('new_value')
end
context 'when the variable does not exist' do
before do
variable.destroy!
end
it 'raises a record not found error' do
expect { execute }.to raise_error(::ActiveRecord::RecordNotFound)
end
end
end
context 'when destroying a variable' do
let!(:variable) { create(:ci_group_variable) }
let(:params) { { variable_params: { key: variable.key }, action: :destroy } }
before do
group.variables << variable
end
it 'destroys a variable' do
expect { execute }.to change { Ci::GroupVariable.exists?(variable.id) }.from(true).to(false)
end
context 'when the variable does not exist' do
before do
variable.destroy!
end
it 'raises a record not found error' do
expect { execute }.to raise_error(::ActiveRecord::RecordNotFound)
end
end
end
end
end

View File

@ -1,21 +0,0 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Ci::ChangeVariablesService do
let(:service) { described_class.new(container: group, current_user: user, params: params) }
let_it_be(:user) { create(:user) }
let(:group) { spy(:group, variables: []) }
let(:params) { { variables_attributes: [{ key: 'new_variable', value: 'variable_value' }] } }
describe '#execute' do
subject(:execute) { service.execute }
it 'delegates to ActiveRecord update' do
execute
expect(group).to have_received(:update).with(params)
end
end
end