Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2020-04-06 09:09:17 +00:00
parent cce8cf03d3
commit eaea945e03
42 changed files with 459 additions and 242 deletions

View File

@ -392,9 +392,7 @@ RSpec/RepeatedExample:
- 'spec/features/merge_request/user_posts_diff_notes_spec.rb'
- 'spec/features/projects/files/template_type_dropdown_spec.rb'
- 'spec/finders/environments_finder_spec.rb'
- 'spec/frontend/fixtures/merge_requests.rb'
- 'spec/helpers/users_helper_spec.rb'
- 'spec/lib/gitlab/closing_issue_extractor_spec.rb'
- 'spec/lib/gitlab/import_export/project/relation_factory_spec.rb'
- 'spec/services/notification_service_spec.rb'
- 'spec/services/web_hook_service_spec.rb'

View File

@ -1 +1 @@
8.29.0
8.30.0

View File

@ -23,6 +23,8 @@ const popoverStates = {
},
};
export default {
dismissTrackValue: 10,
clickTrackValue: 'click_button',
components: {
GlPopover,
GlSprintf,
@ -109,7 +111,16 @@ export default {
<template #title>
<span v-html="suggestTitle"></span>
<span class="ml-auto">
<gl-deprecated-button :aria-label="__('Close')" class="btn-blank" @click="onDismiss">
<gl-deprecated-button
:aria-label="__('Close')"
class="btn-blank"
name="dismiss"
:data-track-property="humanAccess"
:data-track-value="$options.dismissTrackValue"
:data-track-event="$options.clickTrackValue"
:data-track-label="trackLabel"
@click="onDismiss"
>
<gl-icon name="close" aria-hidden="true" />
</gl-deprecated-button>
</span>

View File

@ -0,0 +1,48 @@
# frozen_string_literal: true
module Projects
module Prometheus
module Metrics
class BaseService
include Gitlab::Utils::StrongMemoize
def initialize(metric, params = {})
@metric = metric
@project = metric.project
@params = params.dup
end
protected
attr_reader :metric, :project, :params
def application
alert.environment.cluster_prometheus_adapter
end
def schedule_alert_update
return unless alert
return unless alert.environment
::Clusters::Applications::ScheduleUpdateService.new(
alert.environment.cluster_prometheus_adapter, project).execute
end
def alert
strong_memoize(:alert) { find_alert(metric) }
end
def find_alert(metric)
Projects::Prometheus::AlertsFinder
.new(project: project, metric: metric)
.execute
.first
end
def has_alert?
alert.present?
end
end
end
end
end

View File

@ -0,0 +1,14 @@
# frozen_string_literal: true
module Projects
module Prometheus
module Metrics
class DestroyService < Metrics::BaseService
def execute
schedule_alert_update if has_alert?
metric.destroy
end
end
end
end
end

View File

@ -0,0 +1,29 @@
# frozen_string_literal: true
module Projects
module Prometheus
module Metrics
class UpdateService < Metrics::BaseService
def execute
metric.update!(params)
schedule_alert_update if requires_alert_update?
metric
end
private
def requires_alert_update?
has_alert? && (changing_title? || changing_query?)
end
def changing_title?
metric.previous_changes.include?(:title)
end
def changing_query?
metric.previous_changes.include?(:query)
end
end
end
end
end

View File

@ -16,4 +16,5 @@
- if @commit
.network-graph{ data: { url: @url, commit_url: @commit_url, ref: @ref, commit_id: @commit.id } }
= spinner nil, true
.text-center.prepend-top-default
.spinner.spinner-md

View File

@ -0,0 +1,5 @@
---
title: Migrate .fa-spinner to .spinner for app/views/projects/network
merge_request: 25050
author: nuwe1
type: other

View File

@ -0,0 +1,5 @@
---
title: Remove duplicate spec from closing issue spec
merge_request: 28803
author: Rajendra Kadam
type: added

View File

@ -0,0 +1,5 @@
---
title: Fix duplciate spec in merge requests
merge_request: 28856
author: Rajendra Kadam
type: added

View File

@ -0,0 +1,18 @@
# frozen_string_literal: true
class AddPartialIndexOnIdToCiJobArtifacts < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
INDEX_NAME = 'index_ci_job_artifacts_file_store_is_null'
disable_ddl_transaction!
def up
add_concurrent_index :ci_job_artifacts, :id, where: 'file_store IS NULL', name: INDEX_NAME
end
def down
remove_concurrent_index_by_name :ci_job_artifacts, INDEX_NAME
end
end

View File

@ -0,0 +1,18 @@
# frozen_string_literal: true
class AddPartialIndexOnIdToLfsObjects < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
INDEX_NAME = 'index_lfs_objects_file_store_is_null'
disable_ddl_transaction!
def up
add_concurrent_index :lfs_objects, :id, where: 'file_store IS NULL', name: INDEX_NAME
end
def down
remove_concurrent_index_by_name :lfs_objects, INDEX_NAME
end
end

View File

@ -0,0 +1,18 @@
# frozen_string_literal: true
class AddPartialIndexOnIdToUploads < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
INDEX_NAME = 'index_uploads_store_is_null'
disable_ddl_transaction!
def up
add_concurrent_index :uploads, :id, where: 'store IS NULL', name: INDEX_NAME
end
def down
remove_concurrent_index_by_name :uploads, INDEX_NAME
end
end

View File

@ -8708,6 +8708,8 @@ CREATE INDEX index_ci_daily_report_results_on_last_pipeline_id ON public.ci_dail
CREATE UNIQUE INDEX index_ci_group_variables_on_group_id_and_key ON public.ci_group_variables USING btree (group_id, key);
CREATE INDEX index_ci_job_artifacts_file_store_is_null ON public.ci_job_artifacts USING btree (id) WHERE (file_store IS NULL);
CREATE INDEX index_ci_job_artifacts_on_expire_at_and_job_id ON public.ci_job_artifacts USING btree (expire_at, job_id);
CREATE INDEX index_ci_job_artifacts_on_file_store ON public.ci_job_artifacts USING btree (file_store);
@ -9328,6 +9330,8 @@ CREATE UNIQUE INDEX index_lfs_file_locks_on_project_id_and_path ON public.lfs_fi
CREATE INDEX index_lfs_file_locks_on_user_id ON public.lfs_file_locks USING btree (user_id);
CREATE INDEX index_lfs_objects_file_store_is_null ON public.lfs_objects USING btree (id) WHERE (file_store IS NULL);
CREATE INDEX index_lfs_objects_on_file_store ON public.lfs_objects USING btree (file_store);
CREATE UNIQUE INDEX index_lfs_objects_on_oid ON public.lfs_objects USING btree (oid);
@ -10094,6 +10098,8 @@ CREATE INDEX index_uploads_on_store ON public.uploads USING btree (store);
CREATE INDEX index_uploads_on_uploader_and_path ON public.uploads USING btree (uploader, path);
CREATE INDEX index_uploads_store_is_null ON public.uploads USING btree (id) WHERE (store IS NULL);
CREATE INDEX index_user_agent_details_on_subject_id_and_subject_type ON public.user_agent_details USING btree (subject_id, subject_type);
CREATE INDEX index_user_callouts_on_user_id ON public.user_callouts USING btree (user_id);
@ -12929,5 +12935,8 @@ COPY "schema_migrations" (version) FROM STDIN;
20200330123739
20200330132913
20200331220930
20200403184110
20200403185127
20200403185422
\.

View File

@ -89,7 +89,7 @@ future GitLab releases.**
| `CI_PAGES_URL` | 11.8 | all | URL to GitLab Pages-built pages. Always belongs to a subdomain of `CI_PAGES_DOMAIN`. |
| `CI_PIPELINE_ID` | 8.10 | all | The unique id of the current pipeline that GitLab CI/CD uses internally |
| `CI_PIPELINE_IID` | 11.0 | all | The unique id of the current pipeline scoped to project |
| `CI_PIPELINE_SOURCE` | 10.0 | all | Indicates how the pipeline was triggered. Possible options are: `push`, `web`, `trigger`, `schedule`, `api`, `pipeline`, `external`, `chat`, `merge_request_event`, and `external_pull_request_event`. For pipelines created before GitLab 9.5, this will show as `unknown` |
| `CI_PIPELINE_SOURCE` | 10.0 | all | Indicates how the pipeline was triggered. Possible options are: `push`, `web`, `trigger`, `schedule`, `api`, `pipeline`, `parent_pipeline`, `external`, `chat`, `merge_request_event`, and `external_pull_request_event`. For pipelines created before GitLab 9.5, this will show as `unknown` |
| `CI_PIPELINE_TRIGGERED` | all | all | The flag to indicate that job was [triggered](../triggers/README.md) |
| `CI_PIPELINE_URL` | 11.1 | 0.5 | Pipeline details URL |
| `CI_PROJECT_DIR` | all | all | The full path where the repository is cloned and where the job is run. If the GitLab Runner `builds_dir` parameter is set, this variable is set relative to the value of `builds_dir`. For more information, see [Advanced configuration](https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runners-section) for GitLab Runner. |

View File

@ -468,7 +468,7 @@ helped us with overall code quality (using delegation, `&.` those
types of things), and making the code more robust.
**["Support multiple assignees for merge requests"](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/10161)**:
A good example of collaboration on an MR touching multiple parts of the codebase. Nick pointed out interesting edge cases, James Lopes also joined in raising concerns on import/export feature.
A good example of collaboration on an MR touching multiple parts of the codebase. Nick pointed out interesting edge cases, James Lopez also joined in raising concerns on import/export feature.
### Credits

View File

@ -410,7 +410,7 @@ merge request with new or changed docs is submitted, are:
- If any code or the `doc/README.md` file is changed, a full pipeline will run, which
runs tests for [`/help`](#gitlab-help-tests).
### Running tests & lint checks locally
### Running tests
Apart from [previewing your changes locally](#previewing-the-changes-live), you can also run all lint checks
and Nanoc tests locally.
@ -462,62 +462,20 @@ The output should be similar to:
Note that this requires you to either have the required lint tools installed on your machine,
or a working Docker installation, in which case an image with these tools pre-installed will be used.
For more information on available linters refer to the [linting](#linting) section.
### Linting
### Local linting
To help adhere to the [documentation style guidelines](styleguide.md), and improve the content
added to documentation, consider locally installing and running documentation linters. This will
help you catch common issues before raising merge requests for review of documentation.
The following are some suggested linters you can install locally and sample configuration:
Running the following locally allows you to match the checks in the build pipeline:
- [`proselint`](#proselint)
- [markdownlint](#markdownlint), which is the same as the test run in [`docs-lint`](#testing)
- [Vale](#vale), for English language grammar and syntax suggestions
- [markdownlint](#markdownlint).
- [Vale](#vale).
NOTE: **Note:**
This list does not limit what other linters you can add to your local documentation writing toolchain.
#### `proselint`
`proselint` checks for common problems with English prose. It provides a
[plethora of checks](http://proselint.com/checks/) that are helpful for technical writing.
`proselint` can be used [on the command line](http://proselint.com/utility/), either on a single
Markdown file or on all Markdown files in a project. For example, to run `proselint` on all
documentation in the [`gitlab` project](https://gitlab.com/gitlab-org/gitlab), run the
following commands from within the `gitlab` project:
```shell
cd doc
proselint **/*.md
```
`proselint` can also be run from within editors using plugins. For example, the following plugins
are available:
- [Sublime Text](https://packagecontrol.io/packages/SublimeLinter-contrib-proselint)
- [Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=PatrykPeszko.vscode-proselint)
- [Others](https://github.com/amperser/proselint#plugins-for-other-software)
##### Sample `proselint` configuration
All of the checks are good to use. However, excluding the `typography.symbols` and `misc.phrasal_adjectives` checks will reduce
noise. The following sample `proselint` configuration disables these checks:
```json
{
"checks": {
"typography.symbols": false,
"misc.phrasal_adjectives": false
}
}
```
A file with `proselint` configuration must be placed in a
[valid location](https://github.com/amperser/proselint#checks). For example, `~/.config/proselint/config`.
#### markdownlint
[markdownlint](https://github.com/DavidAnson/markdownlint) checks that Markdown
@ -596,8 +554,6 @@ You can also
[configure the text editor of your choice](https://errata-ai.github.io/vale/#local-use-by-a-single-writer)
to display the results.
Vale's test results are not currently displayed in CI, but may be displayed in the future.
## Danger Bot
GitLab uses [Danger](https://github.com/danger/danger) for some elements in

View File

@ -8,7 +8,7 @@ This document defines the standards for GitLab's documentation content and files
For broader information about the documentation, see the [Documentation guidelines](index.md).
For programmatic help adhering to the guidelines, see [linting](index.md#linting).
For programmatic help adhering to the guidelines, see [Testing](index.md#testing).
See the GitLab handbook for further [writing style guidelines](https://about.gitlab.com/handbook/communication/#writing-style-guidelines)
that apply to all GitLab content, not just documentation.

View File

@ -19,8 +19,8 @@
module Gitlab
module Database
module BatchCount
def batch_count(relation, column = nil, batch_size: nil)
BatchCounter.new(relation, column: column).count(batch_size: batch_size)
def batch_count(relation, column = nil, batch_size: nil, start: nil, finish: nil)
BatchCounter.new(relation, column: column).count(batch_size: batch_size, start: start, finish: finish)
end
def batch_distinct_count(relation, column = nil, batch_size: nil, start: nil, finish: nil)

View File

@ -240,9 +240,9 @@ module Gitlab
{} # augmented in EE
end
def count(relation, column = nil, fallback: -1, batch: true)
def count(relation, column = nil, fallback: -1, batch: true, start: nil, finish: nil)
if batch && Feature.enabled?(:usage_ping_batch_counter, default_enabled: true)
Gitlab::Database::BatchCount.batch_count(relation, column)
Gitlab::Database::BatchCount.batch_count(relation, column, start: start, finish: finish)
else
relation.count
end

View File

@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
context 'Release' do
context 'Release', quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/213222', type: :flaky } do
describe 'Deploy token creation' do
it 'user adds a deploy token' do
Flow::Login.sign_in

View File

@ -3,23 +3,14 @@
require 'spec_helper'
describe 'User activates Asana' do
let(:project) { create(:project) }
let(:user) { create(:user) }
include_context 'project service activation'
before do
project.add_maintainer(user)
sign_in(user)
visit(project_settings_integrations_path(project))
click_link('Asana')
end
it 'activates service' do
check('Active')
it 'activates service', :js do
visit_project_integration('Asana')
fill_in('Api key', with: 'verySecret')
fill_in('Restrict to branch', with: 'verySecret')
click_button('Save')
click_test_then_save_integration
expect(page).to have_content('Asana activated.')
end

View File

@ -3,22 +3,17 @@
require 'spec_helper'
describe 'User activates Assembla' do
let(:project) { create(:project) }
let(:user) { create(:user) }
include_context 'project service activation'
before do
project.add_maintainer(user)
sign_in(user)
visit(project_settings_integrations_path(project))
click_link('Assembla')
stub_request(:post, /.*atlas.assembla.com.*/)
end
it 'activates service' do
check('Active')
it 'activates service', :js do
visit_project_integration('Assembla')
fill_in('Token', with: 'verySecret')
click_button('Save')
click_test_integration
expect(page).to have_content('Assembla activated.')
end

View File

@ -3,31 +3,26 @@
require 'spec_helper'
describe 'User activates Atlassian Bamboo CI' do
let(:project) { create(:project) }
let(:user) { create(:user) }
include_context 'project service activation'
before do
project.add_maintainer(user)
sign_in(user)
visit(project_settings_integrations_path(project))
click_link('Atlassian Bamboo CI')
stub_request(:get, /.*bamboo.example.com.*/)
end
it 'activates service' do
check('Active')
it 'activates service', :js do
visit_project_integration('Atlassian Bamboo CI')
fill_in('Bamboo url', with: 'http://bamboo.example.com')
fill_in('Build key', with: 'KEY')
fill_in('Username', with: 'user')
fill_in('Password', with: 'verySecret')
click_button('Save')
click_test_integration
expect(page).to have_content('Atlassian Bamboo CI activated.')
# Password field should not be filled in.
click_link('Atlassian Bamboo CI')
expect(find_field('Enter new password').value).to be_nil
expect(find_field('Enter new password').value).to be_blank
end
end

View File

@ -3,22 +3,13 @@
require 'spec_helper'
describe 'User activates Emails on push' do
let(:project) { create(:project) }
let(:user) { create(:user) }
include_context 'project service activation'
before do
project.add_maintainer(user)
sign_in(user)
visit(project_settings_integrations_path(project))
click_link('Emails on push')
end
it 'activates service' do
check('Active')
it 'activates service', :js do
visit_project_integration('Emails on push')
fill_in('Recipients', with: 'qa@company.name')
click_button('Save')
click_test_integration
expect(page).to have_content('Emails on push activated.')
end

View File

@ -3,22 +3,19 @@
require 'spec_helper'
describe 'User activates Flowdock' do
let(:project) { create(:project) }
let(:user) { create(:user) }
before do
project.add_maintainer(user)
sign_in(user)
visit(project_settings_integrations_path(project))
click_link('Flowdock')
include_context 'project service activation' do
let(:project) { create(:project, :repository) }
end
it 'activates service' do
check('Active')
before do
stub_request(:post, /.*api.flowdock.com.*/)
end
it 'activates service', :js do
visit_project_integration('Flowdock')
fill_in('Token', with: 'verySecret')
click_button('Save')
click_test_integration
expect(page).to have_content('Flowdock activated.')
end

View File

@ -2,37 +2,37 @@
require 'spec_helper'
describe 'User activates HipChat' do
let(:project) { create(:project) }
let(:user) { create(:user) }
before do
project.add_maintainer(user)
sign_in(user)
visit(project_settings_integrations_path(project))
click_link('HipChat')
end
describe 'User activates HipChat', :js do
include_context 'project service activation'
context 'with standart settings' do
before do
stub_request(:post, /.*api.hipchat.com.*/)
end
it 'activates service' do
check('Active')
visit_project_integration('HipChat')
fill_in('Room', with: 'gitlab')
fill_in('Token', with: 'verySecret')
click_button('Save')
click_test_integration
expect(page).to have_content('HipChat activated.')
end
end
context 'with custom settings' do
before do
stub_request(:post, /.*chat.example.com.*/)
end
it 'activates service' do
check('Active')
visit_project_integration('HipChat')
fill_in('Room', with: 'gitlab_custom')
fill_in('Token', with: 'secretCustom')
fill_in('Server', with: 'https://chat.example.com')
click_button('Save')
click_test_integration
expect(page).to have_content('HipChat activated.')
end

View File

@ -3,23 +3,14 @@
require 'spec_helper'
describe 'User activates Irker (IRC gateway)' do
let(:project) { create(:project) }
let(:user) { create(:user) }
include_context 'project service activation'
before do
project.add_maintainer(user)
sign_in(user)
visit(project_settings_integrations_path(project))
click_link('Irker (IRC gateway)')
end
it 'activates service' do
check('Active')
it 'activates service', :js do
visit_project_integration('Irker (IRC gateway)')
check('Colorize messages')
fill_in('Recipients', with: 'irc://chat.freenode.net/#commits')
click_button('Save')
click_test_integration
expect(page).to have_content('Irker (IRC gateway) activated.')
end

View File

@ -3,27 +3,22 @@
require 'spec_helper'
describe 'User activates JetBrains TeamCity CI' do
let(:project) { create(:project) }
let(:user) { create(:user) }
include_context 'project service activation'
before do
project.add_maintainer(user)
sign_in(user)
visit(project_settings_integrations_path(project))
click_link('JetBrains TeamCity CI')
stub_request(:post, /.*teamcity.example.com.*/)
end
it 'activates service' do
check('Active')
it 'activates service', :js do
visit_project_integration('JetBrains TeamCity CI')
check('Push')
check('Merge request')
fill_in('Teamcity url', with: 'http://teamcity.example.com')
fill_in('Build type', with: 'GitlabTest_Build')
fill_in('Username', with: 'user')
fill_in('Password', with: 'verySecret')
click_button('Save')
click_test_integration
expect(page).to have_content('JetBrains TeamCity CI activated.')
end

View File

@ -3,23 +3,18 @@
require 'spec_helper'
describe 'User activates Packagist' do
let(:project) { create(:project) }
let(:user) { create(:user) }
include_context 'project service activation'
before do
project.add_maintainer(user)
sign_in(user)
visit(project_settings_integrations_path(project))
click_link('Packagist')
stub_request(:post, /.*packagist.org.*/)
end
it 'activates service' do
check('Active')
it 'activates service', :js do
visit_project_integration('Packagist')
fill_in('Username', with: 'theUser')
fill_in('Token', with: 'verySecret')
click_button('Save')
click_test_then_save_integration
expect(page).to have_content('Packagist activated.')
end

View File

@ -3,22 +3,17 @@
require 'spec_helper'
describe 'User activates PivotalTracker' do
let(:project) { create(:project) }
let(:user) { create(:user) }
include_context 'project service activation'
before do
project.add_maintainer(user)
sign_in(user)
visit(project_settings_integrations_path(project))
click_link('PivotalTracker')
stub_request(:post, /.*www.pivotaltracker.com.*/)
end
it 'activates service' do
check('Active')
it 'activates service', :js do
visit_project_integration('PivotalTracker')
fill_in('Token', with: 'verySecret')
click_button('Save')
click_test_integration
expect(page).to have_content('PivotalTracker activated.')
end

View File

@ -3,21 +3,17 @@
require 'spec_helper'
describe 'User activates Prometheus' do
let(:project) { create(:project) }
let(:user) { create(:user) }
include_context 'project service activation'
before do
project.add_maintainer(user)
sign_in(user)
visit(project_settings_integrations_path(project))
click_link('Prometheus')
stub_request(:get, /.*prometheus.example.com.*/)
end
it 'does not activate service and informs about deprecation' do
it 'does not activate service and informs about deprecation', :js do
visit_project_integration('Prometheus')
check('Active')
fill_in('API URL', with: 'http://prometheus.example.com')
click_button('Save changes')
expect(page).not_to have_content('Prometheus activated.')

View File

@ -3,26 +3,21 @@
require 'spec_helper'
describe 'User activates Pushover' do
let(:project) { create(:project) }
let(:user) { create(:user) }
include_context 'project service activation'
before do
project.add_maintainer(user)
sign_in(user)
visit(project_settings_integrations_path(project))
click_link('Pushover')
stub_request(:post, /.*api.pushover.net.*/)
end
it 'activates service' do
check('Active')
it 'activates service', :js do
visit_project_integration('Pushover')
fill_in('Api key', with: 'verySecret')
fill_in('User key', with: 'verySecret')
fill_in('Device', with: 'myDevice')
select('High Priority', from: 'Priority')
select('Bike', from: 'Sound')
click_button('Save')
click_test_integration
expect(page).to have_content('Pushover activated.')
end

View File

@ -3,32 +3,26 @@
require 'spec_helper'
describe 'User activates Slack notifications' do
let(:user) { create(:user) }
let(:service) { SlackService.new }
let(:project) { create(:project, slack_service: service) }
before do
project.add_maintainer(user)
sign_in(user)
end
include_context 'project service activation'
context 'when service is not configured yet' do
before do
visit(project_settings_integrations_path(project))
click_link('Slack notifications')
visit_project_integration('Slack notifications')
end
it 'activates service' do
check('Active')
it 'activates service', :js do
fill_in('Webhook', with: 'https://hooks.slack.com/services/SVRWFV0VVAR97N/B02R25XN3/ZBqu7xMupaEEICInN685')
click_button('Save')
click_test_then_save_integration
expect(page).to have_content('Slack notifications activated.')
end
end
context 'when service is already configured' do
let(:service) { SlackService.new }
let(:project) { create(:project, slack_service: service) }
before do
service.fields
service.update(

View File

@ -3,17 +3,11 @@
require 'spec_helper'
describe 'User views services' do
let(:project) { create(:project) }
let(:user) { create(:user) }
before do
project.add_maintainer(user)
sign_in(user)
visit(project_settings_integrations_path(project))
end
include_context 'project service activation'
it 'shows the list of available services' do
visit_project_integrations
expect(page).to have_content('Integrations')
expect(page).to have_content('Campfire')
expect(page).to have_content('HipChat')

View File

@ -1,7 +1,8 @@
import { shallowMount } from '@vue/test-utils';
import Popover from '~/blob/suggest_gitlab_ci_yml/components/popover.vue';
import { mockTracking, unmockTracking } from 'helpers/tracking_helper';
import { mockTracking, unmockTracking, triggerEvent } from 'helpers/tracking_helper';
import * as utils from '~/lib/utils/common_utils';
import { GlDeprecatedButton } from '@gitlab/ui';
jest.mock('~/lib/utils/common_utils', () => ({
...jest.requireActual('~/lib/utils/common_utils'),
@ -27,6 +28,9 @@ describe('Suggest gitlab-ci.yml Popover', () => {
dismissKey,
humanAccess,
},
stubs: {
'gl-popover': '<div><slot name="title"></slot><slot></slot></div>',
},
});
}
@ -88,6 +92,22 @@ describe('Suggest gitlab-ci.yml Popover', () => {
property: expectedProperty,
});
});
it('sends a tracking event when the popover is dismissed', () => {
const expectedLabel = commitTrackLabel;
const expectedAction = 'click_button';
const expectedProperty = 'owner';
const expectedValue = '10';
const dismissButton = wrapper.find(GlDeprecatedButton);
triggerEvent(dismissButton.element);
expect(trackingSpy).toHaveBeenCalledWith('_category_', expectedAction, {
label: expectedLabel,
property: expectedProperty,
value: expectedValue,
});
});
});
describe('when the popover is mounted with the trackLabel of the Confirm button popover at the bottom of the page', () => {

View File

@ -94,7 +94,7 @@ describe Projects::MergeRequestsController, '(JavaScript fixtures)', type: :cont
end
it 'merge_requests/discussions.json' do
create(:diff_note_on_merge_request, project: project, author: admin, position: position, noteable: merge_request)
create(:discussion_note_on_merge_request, project: project, author: admin, position: position, noteable: merge_request)
render_discussions_json(merge_request)
end

View File

@ -103,7 +103,7 @@ describe Gitlab::ClosingIssueExtractor do
end
it do
message = "Awesome commit (Fixes: #{reference})"
message = "Awesome commit (fixes: #{reference})"
expect(subject.closed_by_message(message)).to eq([issue])
end
@ -396,7 +396,7 @@ describe Gitlab::ClosingIssueExtractor do
end
it 'allows mixed comma-separated and non-comma-separated issue numbers in single line message' do
message = "Closes #{reference}, #{reference2} and #{reference3}"
message = "Closes #{reference}, #{reference2} #{reference3}"
expect(subject.closed_by_message(message))
.to match_array([issue, other_issue, third_issue])

View File

@ -3,6 +3,8 @@
require 'spec_helper'
describe Gitlab::Database::BatchCount do
let_it_be(:fallback) { ::Gitlab::Database::BatchCounter::FALLBACK }
let_it_be(:small_batch_size) { ::Gitlab::Database::BatchCounter::MIN_REQUIRED_BATCH_SIZE - 1 }
let(:model) { Issue }
let(:column) { :author_id }
@ -37,9 +39,8 @@ describe Gitlab::Database::BatchCount do
expect(described_class.batch_count(model, batch_size: 50_000)).to eq(5)
end
it 'will not count table with batch_size 1K' do
fallback = ::Gitlab::Database::BatchCounter::FALLBACK
expect(described_class.batch_count(model, batch_size: fallback / 2)).to eq(fallback)
it 'will not count table with a batch size less than allowed' do
expect(described_class.batch_count(model, batch_size: small_batch_size)).to eq(fallback)
end
it 'counts with a small edge case batch_sizes than result' do
@ -57,6 +58,25 @@ describe Gitlab::Database::BatchCount do
end.to raise_error 'BatchCount can not be run inside a transaction'
end
end
it 'counts with a start and finish' do
expect(described_class.batch_count(model, start: model.minimum(:id), finish: model.maximum(:id))).to eq(5)
end
context 'disallowed configurations' do
it 'returns fallback if start is bigger than finish' do
expect(described_class.batch_count(model, start: 1, finish: 0)).to eq(fallback)
end
it 'returns fallback if loops more than allowed' do
large_finish = Gitlab::Database::BatchCounter::MAX_ALLOWED_LOOPS * Gitlab::Database::BatchCounter::DEFAULT_BATCH_SIZE + 1
expect(described_class.batch_count(model, start: 1, finish: large_finish)).to eq(fallback)
end
it 'returns fallback if batch size is less than min required' do
expect(described_class.batch_count(model, batch_size: small_batch_size)).to eq(fallback)
end
end
end
describe '#batch_distinct_count' do
@ -80,9 +100,8 @@ describe Gitlab::Database::BatchCount do
expect(described_class.batch_distinct_count(model, column, batch_size: 50_000)).to eq(2)
end
it 'will not count table with batch_size 1K' do
fallback = ::Gitlab::Database::BatchCounter::FALLBACK
expect(described_class.batch_distinct_count(model, column, batch_size: fallback / 2)).to eq(fallback)
it 'will not count table with a batch size less than allowed' do
expect(described_class.batch_distinct_count(model, column, batch_size: small_batch_size)).to eq(fallback)
end
it 'counts with a small edge case batch_sizes than result' do
@ -98,5 +117,20 @@ describe Gitlab::Database::BatchCount do
it 'counts with User min and max as start and finish' do
expect(described_class.batch_distinct_count(model, column, start: User.minimum(:id), finish: User.maximum(:id))).to eq(2)
end
context 'disallowed configurations' do
it 'returns fallback if start is bigger than finish' do
expect(described_class.batch_distinct_count(model, column, start: 1, finish: 0)).to eq(fallback)
end
it 'returns fallback if loops more than allowed' do
large_finish = Gitlab::Database::BatchCounter::MAX_ALLOWED_LOOPS * Gitlab::Database::BatchCounter::DEFAULT_DISTINCT_BATCH_SIZE + 1
expect(described_class.batch_distinct_count(model, column, start: 1, finish: large_finish)).to eq(fallback)
end
it 'returns fallback if batch size is less than min required' do
expect(described_class.batch_distinct_count(model, column, batch_size: small_batch_size)).to eq(fallback)
end
end
end
end

View File

@ -0,0 +1,28 @@
# frozen_string_literal: true
require 'spec_helper'
describe Projects::Prometheus::Metrics::DestroyService do
let(:metric) { create(:prometheus_metric) }
subject { described_class.new(metric) }
it 'destroys metric' do
subject.execute
expect(PrometheusMetric.find_by(id: metric.id)).to be_nil
end
context 'when metric has a prometheus alert associated' do
it 'schedules a prometheus alert update' do
create(:prometheus_alert, project: metric.project, prometheus_metric: metric)
schedule_update_service = spy
allow(::Clusters::Applications::ScheduleUpdateService).to receive(:new).and_return(schedule_update_service)
subject.execute
expect(schedule_update_service).to have_received(:execute)
end
end
end

View File

@ -0,0 +1,44 @@
# frozen_string_literal: true
require 'spec_helper'
describe Projects::Prometheus::Metrics::UpdateService do
let(:metric) { create(:prometheus_metric) }
it 'updates the prometheus metric' do
expect do
described_class.new(metric, { title: "bar" }).execute
end.to change { metric.reload.title }.to("bar")
end
context 'when metric has a prometheus alert associated' do
let(:schedule_update_service) { spy }
before do
create(:prometheus_alert, project: metric.project, prometheus_metric: metric)
allow(::Clusters::Applications::ScheduleUpdateService).to receive(:new).and_return(schedule_update_service)
end
context 'when updating title' do
it 'schedules a prometheus alert update' do
described_class.new(metric, { title: "bar" }).execute
expect(schedule_update_service).to have_received(:execute)
end
end
context 'when updating query' do
it 'schedules a prometheus alert update' do
described_class.new(metric, { query: "sum(bar)" }).execute
expect(schedule_update_service).to have_received(:execute)
end
end
it 'does not schedule a prometheus alert update without title nor query being changed' do
described_class.new(metric, { y_label: "bar" }).execute
expect(schedule_update_service).not_to have_received(:execute)
end
end
end

View File

@ -0,0 +1,32 @@
# frozen_string_literal: true
shared_context 'project service activation' do
let(:project) { create(:project) }
let(:user) { create(:user) }
before do
project.add_maintainer(user)
sign_in(user)
end
def visit_project_integrations
visit project_settings_integrations_path(project)
end
def visit_project_integration(name)
visit_project_integrations
click_link(name)
end
def click_test_integration
click_button('Test settings and save changes')
end
def click_test_then_save_integration
click_test_integration
expect(page).to have_content('Test failed.')
click_link('Save anyway')
end
end