Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2020-09-25 12:10:00 +00:00
parent e6bcd6e738
commit f6d19ed8eb
28 changed files with 396 additions and 105 deletions

View File

@ -1,11 +1,11 @@
<script>
import { GlModal, GlModalDirective, GlDeprecatedButton } from '@gitlab/ui';
import { GlModal, GlModalDirective, GlButton } from '@gitlab/ui';
import { s__ } from '~/locale';
export default {
components: {
GlModal,
GlDeprecatedButton,
GlButton,
},
directives: {
'gl-modal': GlModalDirective,
@ -33,9 +33,9 @@ export default {
</script>
<template>
<div class="d-inline-block float-right mr-3">
<gl-deprecated-button v-gl-modal="$options.modalId" variant="danger">
<gl-button v-gl-modal="$options.modalId" variant="danger" category="primary">
{{ __('Delete') }}
</gl-deprecated-button>
</gl-button>
<gl-modal
:title="s__('Metrics|Delete metric?')"
:ok-title="s__('Metrics|Delete metric')"

View File

@ -113,8 +113,8 @@ export default {
},
methods: {
...mapActions('diffs', ['showCommentForm']),
showNewDiscussionForm() {
this.showCommentForm({ lineCode: this.line.line_code, fileHash: this.diffFileHash });
showNewDiscussionForm(lineCode) {
this.showCommentForm({ lineCode, fileHash: this.diffFileHash });
},
},
};
@ -134,7 +134,7 @@ export default {
v-if="!hasDraftLeft"
:has-form="showLeftSideCommentForm"
:render-reply-placeholder="shouldRenderReplyPlaceholderOnLeft"
@showNewDiscussionForm="showNewDiscussionForm"
@showNewDiscussionForm="showNewDiscussionForm(line.left.line_code)"
>
<template #form>
<diff-line-note-form
@ -159,7 +159,7 @@ export default {
v-if="!hasDraftRight"
:has-form="showRightSideCommentForm"
:render-reply-placeholder="shouldRenderReplyPlaceholderOnRight"
@showNewDiscussionForm="showNewDiscussionForm"
@showNewDiscussionForm="showNewDiscussionForm(line.right.line_code)"
>
<template #form>
<diff-line-note-form

View File

@ -45,13 +45,6 @@ export default {
loading() {
return this.$apollo.queries.alert.loading;
},
alertTableFields() {
if (this.alert) {
const { detailsUrl, __typename, ...restDetails } = this.alert;
return restDetails;
}
return null;
},
},
};
</script>
@ -64,7 +57,7 @@ export default {
<description-component v-bind="$attrs" />
</gl-tab>
<gl-tab v-if="alert" class="alert-management-details" :title="s__('Incident|Alert details')">
<alert-details-table :alert="alertTableFields" :loading="loading" />
<alert-details-table :alert="alert" :loading="loading" />
</gl-tab>
</gl-tabs>
</div>

View File

@ -132,7 +132,9 @@ function mountLockComponent() {
({ store }) => store,
);
} else {
importStore = import(/* webpackChunkName: 'mrNotesStore' */ '~/mr_notes/stores');
importStore = import(/* webpackChunkName: 'mrNotesStore' */ '~/mr_notes/stores').then(
store => store.default,
);
}
importStore

View File

@ -31,6 +31,15 @@ export default class TaskList {
init() {
this.disable(); // Prevent duplicate event bindings
const taskListFields = document.querySelectorAll(
`${this.taskListContainerSelector} .js-task-list-field[data-value]`,
);
taskListFields.forEach(taskListField => {
// eslint-disable-next-line no-param-reassign
taskListField.value = taskListField.dataset.value;
});
$(this.taskListContainerSelector).taskList('enable');
$(document).on('tasklist:changed', this.taskListContainerSelector, this.updateHandler);
}

View File

@ -9,6 +9,22 @@ import {
const thClass = 'gl-bg-transparent! gl-border-1! gl-border-b-solid! gl-border-gray-200!';
const tdClass = 'gl-border-gray-100! gl-p-5!';
const allowedFields = [
'iid',
'title',
'severity',
'status',
'startedAt',
'eventCount',
'monitoringTool',
'service',
'description',
'endedAt',
'details',
];
const filterAllowedFields = ([fieldName]) => allowedFields.includes(fieldName);
const arrayToObject = ([fieldName, value]) => ({ fieldName, value });
export default {
components: {
@ -46,10 +62,9 @@ export default {
if (!this.alert) {
return [];
}
return Object.entries(this.alert).map(([fieldName, value]) => ({
fieldName,
value,
}));
return Object.entries(this.alert)
.filter(filterAllowedFields)
.map(arrayToObject);
},
},
};

View File

@ -1050,14 +1050,6 @@ button.mini-pipeline-graph-dropdown-toggle {
line-height: 1.5;
}
.legend-all {
color: $gl-text-color-secondary;
}
.legend-success {
color: $green-500;
}
.test-reports-table {
.build-trace {
@include build-trace();

View File

@ -66,9 +66,8 @@
.title-container
%h2.title= markdown_field(@issue, :title)
- if @issue.description.present?
.description{ class: can?(current_user, :update_issue, @issue) ? 'js-task-list-container' : '' }
.description
.md= markdown_field(@issue, :description)
%textarea.hidden.js-task-list-field= @issue.description
= edited_time_ago_with_tooltip(@issue, placement: 'bottom', html_class: 'issue-edited-ago js-issue-edited-ago')

View File

@ -3,7 +3,6 @@
.description.qa-description{ class: can?(current_user, :update_merge_request, @merge_request) ? 'js-task-list-container' : '' }
.md
= markdown_field(@merge_request, :description)
%textarea.hidden.js-task-list-field
= @merge_request.description
%textarea.hidden.js-task-list-field{ data: { value: @merge_request.description } }
= edited_time_ago_with_tooltip(@merge_request, placement: 'bottom')

View File

@ -1 +1 @@
%textarea.hidden.js-task-list-field.original-task-list{ data: { update_url: note_url(note) } }= note.note
%textarea.hidden.js-task-list-field.original-task-list{ data: { update_url: note_url(note), value: note.note } }

View File

@ -21,8 +21,6 @@
.description
.md
= markdown_field(@snippet, :description)
%textarea.hidden.js-task-list-field
= @snippet.description
- if @snippet.updated_at != @snippet.created_at
= edited_time_ago_with_tooltip(@snippet, placement: 'bottom', exclude_author: true)

View File

@ -0,0 +1,5 @@
---
title: Fix checking of task lists when MR description starts with a blank line
merge_request: 43125
author:
type: fixed

View File

@ -0,0 +1,5 @@
---
title: Fix branches_to_be_notified API param for hangouts chat service
merge_request: 35599
author:
type: fixed

View File

@ -0,0 +1,5 @@
---
title: Remove internal fields from alert details table
merge_request: 43076
author:
type: changed

View File

@ -19,7 +19,6 @@
- auto_devops
- backup_restore
- behavior_analytics
- billing
- chatops
- cloud_native_installation
- cluster_cost_optimization
@ -87,6 +86,8 @@
- planning_analytics
- product_analytics
- projects
- provision
- purchase
- quality_management
- release_evidence
- release_orchestration

View File

@ -67,3 +67,7 @@ That's totally fine. We use HTTP(s) to fetch repository changes from the **prima
## Is this possible to set up a Docker Registry for a **secondary** node that mirrors the one on the **primary** node?
Yes. See [Docker Registry for a **secondary** node](docker_registry.md).
## Can I login to a secondary node?
Yes, but secondary nodes receive all authentication data (like user accounts and logins) from the primary instance. This means you will be re-directed to the primary for authentication and routed back afterwards.

View File

@ -659,7 +659,7 @@ Parameters:
| `webhook` | string | true | The Hangouts Chat webhook. For example, `https://chat.googleapis.com/v1/spaces...`. |
| `notify_only_broken_pipelines` | boolean | false | Send notifications for broken pipelines |
| `notify_only_default_branch` | boolean | false | DEPRECATED: This parameter has been replaced with `branches_to_be_notified` |
| `branches_to_be_notified` | string | all | Branches to send notifications for. Valid options are "all", "default", "protected", and "default_and_protected" |
| `branches_to_be_notified` | string | false | Branches to send notifications for. Valid options are "all", "default", "protected", and "default_and_protected" |
| `push_events` | boolean | false | Enable notifications for push events |
| `issues_events` | boolean | false | Enable notifications for issue events |
| `confidential_issues_events` | boolean | false | Enable notifications for confidential issue events |

View File

@ -91,8 +91,6 @@ module Geo
::Packages::PackageFile
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?
@ -220,8 +218,6 @@ For example, to add support for files referenced by a `Widget` model with a
model_record.file
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_widget_replication`
def self.replication_enabled_by_default?
@ -693,3 +689,33 @@ To do: This should be done as part of
Widget sync and verification data (aggregate and individual) should now be
available in the Admin UI!
#### Releasing the feature
1. In `ee/app/replicators/geo/widget_replicator.rb`, delete the `self.replication_enabled_by_default?` method:
```ruby
module Geo
class WidgetReplicator < Gitlab::Geo::Replicator
...
# REMOVE THIS METHOD
def self.replication_enabled_by_default?
false
end
# REMOVE THIS METHOD
...
end
end
```
1. In `ee/app/graphql/types/geo/geo_node_type.rb`, remove the `feature_flag` option for the released type:
```ruby
field :widget_registries, ::Types::Geo::WidgetRegistryType.connection_type,
null: true,
resolver: ::Resolvers::Geo::WidgetRegistriesResolver,
description: 'Find widget registries on this Geo node',
feature_flag: :geo_widget_replication # REMOVE THIS LINE
```

View File

@ -381,6 +381,12 @@ module API
type: String,
desc: 'The Hangouts Chat webhook. e.g. https://chat.googleapis.com/v1/spaces…'
},
{
required: false,
name: :branches_to_be_notified,
type: String,
desc: 'Branches for which notifications are to be sent'
},
chat_notification_events
].flatten,
'hipchat' => [

View File

@ -8,15 +8,20 @@
# In order to not use a possible complex time consuming query when calculating min and max for batch_distinct_count
# the start and finish can be sent specifically
#
# Grouped relations can be used as well. However, the preferred batch count should be around 10K because group by count is more expensive.
#
# See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/22705
#
# Examples:
# extend ::Gitlab::Database::BatchCount
# batch_count(User.active)
# batch_count(::Clusters::Cluster.aws_installed.enabled, :cluster_id)
# batch_count(Namespace.group(:type))
# batch_distinct_count(::Project, :creator_id)
# batch_distinct_count(::Project.with_active_services.service_desk_enabled.where(time_period), start: ::User.minimum(:id), finish: ::User.maximum(:id))
# batch_distinct_count(Project.group(:visibility_level), :creator_id)
# batch_sum(User, :sign_in_count)
# batch_sum(Issue.group(:state_id), :weight))
module Gitlab
module Database
module BatchCount
@ -77,12 +82,12 @@ module Gitlab
raise "Batch counting expects positive values only for #{@column}" if start < 0 || finish < 0
return FALLBACK if unwanted_configuration?(finish, batch_size, start)
counter = 0
results = nil
batch_start = start
while batch_start <= finish
begin
counter += batch_fetch(batch_start, batch_start + batch_size, mode)
results = merge_results(results, batch_fetch(batch_start, batch_start + batch_size, mode))
batch_start += batch_size
rescue ActiveRecord::QueryCanceled
# retry with a safe batch size & warmer cache
@ -95,7 +100,17 @@ module Gitlab
sleep(SLEEP_TIME_IN_SECONDS)
end
counter
results
end
def merge_results(results, object)
return object unless results
if object.is_a?(Hash)
results.merge!(object) { |_, a, b| a + b }
else
results + object
end
end
def batch_fetch(start, finish, mode)
@ -118,11 +133,11 @@ module Gitlab
end
def actual_start(start)
start || @relation.minimum(@column) || 0
start || @relation.unscope(:group).minimum(@column) || 0
end
def actual_finish(finish)
finish || @relation.maximum(@column) || 0
finish || @relation.unscope(:group).maximum(@column) || 0
end
def check_mode!(mode)

View File

@ -0,0 +1,79 @@
# frozen_string_literal: true
# TODO use shared examples to merge this spec with discussion_lock_spec.rb
# https://gitlab.com/gitlab-org/gitlab/-/issues/255910
require 'spec_helper'
RSpec.describe 'Merge Request Discussion Lock', :js do
let(:user) { create(:user) }
let(:project) { create(:project, :public, :repository) }
let(:merge_request) { create(:merge_request, source_project: project, author: user) }
before do
sign_in(user)
end
context 'when a user is a team member' do
before do
project.add_developer(user)
end
context 'when the discussion is unlocked' do
it 'the user can lock the merge_request' do
visit project_merge_request_path(merge_request.project, merge_request)
expect(find('.issuable-sidebar')).to have_content('Unlocked')
page.within('.issuable-sidebar') do
find('.lock-edit').click
click_button('Lock')
end
expect(find('[data-testid="lock-status"]')).to have_content('Locked')
end
end
context 'when the discussion is locked' do
before do
merge_request.update_attribute(:discussion_locked, true)
visit project_merge_request_path(merge_request.project, merge_request)
end
it 'the user can unlock the merge_request' do
expect(find('.issuable-sidebar')).to have_content('Locked')
page.within('.issuable-sidebar') do
find('.lock-edit').click
click_button('Unlock')
end
expect(find('[data-testid="lock-status"]')).to have_content('Unlocked')
end
end
end
context 'when a user is not a team member' do
context 'when the discussion is unlocked' do
before do
visit project_merge_request_path(merge_request.project, merge_request)
end
it 'the user can not lock the merge_request' do
expect(find('.issuable-sidebar')).to have_content('Unlocked')
expect(find('.issuable-sidebar')).not_to have_selector('.lock-edit')
end
end
context 'when the discussion is locked' do
before do
merge_request.update_attribute(:discussion_locked, true)
visit project_merge_request_path(merge_request.project, merge_request)
end
it 'the user can not unlock the merge_request' do
expect(find('.issuable-sidebar')).to have_content('Locked')
expect(find('.issuable-sidebar')).not_to have_selector('.lock-edit')
end
end
end
end

View File

@ -22,7 +22,7 @@ RSpec.describe 'User views an open merge request' do
# returns the whole document, not the node's actual parent element
expect(find(:xpath, "#{node.path}/..").text).to eq(merge_request.description[2..-1])
expect(page).to have_content(merge_request.title).and have_content(merge_request.description)
expect(page).to have_content(merge_request.title)
end
end

View File

@ -6,19 +6,22 @@ RSpec.describe "User comments on commit", :js do
include Spec::Support::Helpers::Features::NotesHelpers
include RepoHelpers
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
let_it_be(:project) { create(:project, :repository) }
let_it_be(:user) { create(:user) }
let(:comment_text) { "XML attached" }
before_all do
project.add_developer(user)
end
before do
sign_in(user)
project.add_developer(user)
visit(project_commit_path(project, sample_commit.id))
end
context "when adding new comment" do
it "adds comment" do
visit(project_commit_path(project, sample_commit.id))
emoji_code = ":+1:"
page.within(".js-main-target-form") do
@ -57,6 +60,8 @@ RSpec.describe "User comments on commit", :js do
context "when editing comment" do
before do
visit(project_commit_path(project, sample_commit.id))
add_note(comment_text)
end
@ -87,6 +92,8 @@ RSpec.describe "User comments on commit", :js do
context "when deleting comment" do
before do
visit(project_commit_path(project, sample_commit.id))
add_note(comment_text)
end
@ -108,4 +115,35 @@ RSpec.describe "User comments on commit", :js do
expect(page).not_to have_css(".note")
end
end
context 'when checking task lists' do
let(:note_with_task) do
<<-EOT.strip_heredoc
- [ ] Task 1
EOT
end
before do
create(:note_on_commit, project: project, commit_id: sample_commit.id, note: note_with_task, author: user)
create(:note_on_commit, project: project, commit_id: sample_commit.id, note: note_with_task, author: user)
visit(project_commit_path(project, sample_commit.id))
end
it 'allows the tasks to be checked' do
expect(page).to have_selector('li.task-list-item', count: 2)
expect(page).to have_selector('li.task-list-item input[checked]', count: 0)
all('.task-list-item-checkbox').each do |checkbox|
checkbox.click
end
wait_for_requests
visit(project_commit_path(project, sample_commit.id))
expect(page).to have_selector('li.task-list-item', count: 2)
expect(page).to have_selector('li.task-list-item input[checked]', count: 2)
end
end
end

View File

@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe 'Task Lists' do
RSpec.describe 'Task Lists', :js do
include Warden::Test::Helpers
let_it_be(:project) { create(:project, :public, :repository) }
@ -38,41 +38,7 @@ RSpec.describe 'Task Lists' do
MARKDOWN
end
let(:nested_tasks_markdown) do
<<-EOT.strip_heredoc
- [ ] Task a
- [x] Task a.1
- [ ] Task a.2
- [ ] Task b
1. [ ] Task 1
1. [ ] Task 1.1
1. [x] Task 1.2
EOT
end
let(:commented_tasks_markdown) do
<<-EOT.strip_heredoc
<!--
- [ ] a
-->
- [ ] b
EOT
end
let(:summary_no_blank_line_markdown) do
<<-EOT.strip_heredoc
<details>
<summary>No blank line after summary element breaks task list</summary>
1. [ ] People Ops: do such and such
</details>
* [ ] Task 1
EOT
end
before(:all) do
before_all do
project.add_maintainer(user)
project.add_guest(user2)
end
@ -86,7 +52,7 @@ RSpec.describe 'Task Lists' do
end
describe 'for Issues' do
describe 'multiple tasks', :js do
describe 'multiple tasks' do
let!(:issue) { create(:issue, description: markdown, author: user, project: project) }
it 'renders' do
@ -127,7 +93,7 @@ RSpec.describe 'Task Lists' do
end
end
describe 'single incomplete task', :js do
describe 'single incomplete task' do
let!(:issue) { create(:issue, description: singleIncompleteMarkdown, author: user, project: project) }
it 'renders' do
@ -146,7 +112,7 @@ RSpec.describe 'Task Lists' do
end
end
describe 'single complete task', :js do
describe 'single complete task' do
let!(:issue) { create(:issue, description: singleCompleteMarkdown, author: user, project: project) }
it 'renders' do
@ -175,7 +141,7 @@ RSpec.describe 'Task Lists' do
project: project, author: user)
end
it 'renders for note body', :js do
it 'renders for note body' do
visit_issue(project, issue)
expect(page).to have_selector('.note ul.task-list', count: 1)
@ -183,14 +149,14 @@ RSpec.describe 'Task Lists' do
expect(page).to have_selector('.note ul input[checked]', count: 2)
end
it 'contains the required selectors', :js do
it 'contains the required selectors' do
visit_issue(project, issue)
expect(page).to have_selector('.note .js-task-list-container')
expect(page).to have_selector('.note .js-task-list-container .task-list .task-list-item .task-list-item-checkbox')
end
it 'is only editable by author', :js do
it 'is only editable by author' do
visit_issue(project, issue)
expect(page).to have_selector('.js-task-list-container')
@ -209,7 +175,7 @@ RSpec.describe 'Task Lists' do
project: project, author: user)
end
it 'renders for note body', :js do
it 'renders for note body' do
visit_issue(project, issue)
expect(page).to have_selector('.note ul.task-list', count: 1)
@ -224,7 +190,7 @@ RSpec.describe 'Task Lists' do
project: project, author: user)
end
it 'renders for note body', :js do
it 'renders for note body' do
visit_issue(project, issue)
expect(page).to have_selector('.note ul.task-list', count: 1)
@ -240,7 +206,7 @@ RSpec.describe 'Task Lists' do
end
shared_examples 'multiple tasks' do
it 'renders for description', :js do
it 'renders for description' do
visit_merge_request(project, merge)
wait_for_requests
@ -249,7 +215,7 @@ RSpec.describe 'Task Lists' do
expect(page).to have_selector('ul input[checked]', count: 2)
end
it 'contains the required selectors', :js do
it 'contains the required selectors' do
visit_merge_request(project, merge)
wait_for_requests
@ -261,7 +227,7 @@ RSpec.describe 'Task Lists' do
expect(page).to have_selector('form.js-issuable-update')
end
it 'is only editable by author', :js do
it 'is only editable by author' do
visit_merge_request(project, merge)
wait_for_requests
@ -300,7 +266,7 @@ RSpec.describe 'Task Lists' do
describe 'single incomplete task' do
let!(:merge) { create(:merge_request, :simple, description: singleIncompleteMarkdown, author: user, source_project: project) }
it 'renders for description', :js do
it 'renders for description' do
visit_merge_request(project, merge)
wait_for_requests
@ -319,7 +285,7 @@ RSpec.describe 'Task Lists' do
describe 'single complete task' do
let!(:merge) { create(:merge_request, :simple, description: singleCompleteMarkdown, author: user, source_project: project) }
it 'renders for description', :js do
it 'renders for description' do
visit_merge_request(project, merge)
wait_for_requests
@ -337,7 +303,17 @@ RSpec.describe 'Task Lists' do
end
describe 'markdown task edge cases' do
describe 'commented tasks', :js do
describe 'commented tasks' do
let(:commented_tasks_markdown) do
<<-EOT.strip_heredoc
<!--
- [ ] a
-->
- [ ] b
EOT
end
let!(:issue) { create(:issue, description: commented_tasks_markdown, author: user, project: project) }
it 'renders' do
@ -360,7 +336,18 @@ RSpec.describe 'Task Lists' do
end
end
describe 'summary with no blank line', :js do
describe 'summary with no blank line' do
let(:summary_no_blank_line_markdown) do
<<-EOT.strip_heredoc
<details>
<summary>No blank line after summary element breaks task list</summary>
1. [ ] People Ops: do such and such
</details>
* [ ] Task 1
EOT
end
let!(:issue) { create(:issue, description: summary_no_blank_line_markdown, author: user, project: project) }
it 'renders' do
@ -382,5 +369,31 @@ RSpec.describe 'Task Lists' do
expect(page).to have_selector('ul input[checked]', count: 1)
end
end
describe 'markdown starting with new line character' do
let(:markdown_starting_with_new_line) do
<<-EOT.strip_heredoc
- [ ] Task 1
EOT
end
let(:merge_request) { create(:merge_request, description: markdown_starting_with_new_line, author: user, source_project: project) }
it 'allows the task to be checked' do
visit project_merge_request_path(project, merge_request)
wait_for_requests
expect(page).to have_selector('ul input[checked]', count: 0)
find('.task-list-item-checkbox').click
wait_for_requests
visit project_merge_request_path(project, merge_request)
wait_for_requests
expect(page).to have_selector('ul input[checked]', count: 1)
end
end
end
end

View File

@ -79,7 +79,7 @@ describe('Incident Tabs component', () => {
it('renders the alert details table with the correct props', () => {
const alert = { iid: mockAlert.iid };
expect(findAlertDetailsComponent().props('alert')).toEqual(alert);
expect(findAlertDetailsComponent().props('alert')).toMatchObject(alert);
expect(findAlertDetailsComponent().props('loading')).toBe(true);
});

View File

@ -14,6 +14,7 @@ const mockAlert = {
assignees: { nodes: [] },
notes: { nodes: [] },
todos: { nodes: [] },
__typename: 'AlertManagementAlert',
};
describe('AlertDetails', () => {
@ -35,6 +36,8 @@ describe('AlertDetails', () => {
});
const findTableComponent = () => wrapper.find(GlTable);
const findTableKeys = () => findTableComponent().findAll('tbody td:first-child');
const findTableField = (fields, fieldName) => fields.filter(row => row.text() === fieldName);
describe('Alert details', () => {
describe('empty state', () => {
@ -69,6 +72,24 @@ describe('AlertDetails', () => {
it('renders a cell based on alert data', () => {
expect(findTableComponent().text()).toContain('SyntaxError: Invalid or unexpected token');
});
it('should show allowed alert fields', () => {
const fields = findTableKeys();
expect(findTableField(fields, 'Iid').exists()).toBe(true);
expect(findTableField(fields, 'Title').exists()).toBe(true);
expect(findTableField(fields, 'Severity').exists()).toBe(true);
expect(findTableField(fields, 'Status').exists()).toBe(true);
});
it('should not show disallowed alert fields', () => {
const fields = findTableKeys();
expect(findTableField(fields, 'Typename').exists()).toBe(false);
expect(findTableField(fields, 'Todos').exists()).toBe(false);
expect(findTableField(fields, 'Notes').exists()).toBe(false);
expect(findTableField(fields, 'Assignees').exists()).toBe(false);
});
});
});
});

View File

@ -108,6 +108,24 @@ RSpec.describe Gitlab::Database::BatchCount do
expect { described_class.batch_count(model.distinct(column)) }.to raise_error 'Use distinct count for optimized distinct counting'
end
end
context 'when a relation is grouped' do
let!(:one_more_issue) { create(:issue, author: user, project: model.first.project) }
before do
stub_const('Gitlab::Database::BatchCounter::MIN_REQUIRED_BATCH_SIZE', 1)
end
context 'count by default column' do
let(:count) do
described_class.batch_count(model.group(column), batch_size: 2)
end
it 'counts grouped records' do
expect(count).to eq({ user.id => 4, another_user.id => 2 })
end
end
end
end
describe '#batch_distinct_count' do
@ -175,6 +193,24 @@ RSpec.describe Gitlab::Database::BatchCount do
end.to raise_error 'Use distinct count only with non id fields'
end
end
context 'when a relation is grouped' do
let!(:one_more_issue) { create(:issue, author: user, project: model.first.project) }
before do
stub_const('Gitlab::Database::BatchCounter::MIN_REQUIRED_BATCH_SIZE', 1)
end
context 'distinct count by non-unique column' do
let(:count) do
described_class.batch_distinct_count(model.group(column), :project_id, batch_size: 2)
end
it 'counts grouped records' do
expect(count).to eq({ user.id => 3, another_user.id => 2 })
end
end
end
end
describe '#batch_sum' do

View File

@ -264,4 +264,34 @@ RSpec.describe API::Services do
expect(json_response['properties']['notify_only_broken_pipelines']).to eq(true)
end
end
describe 'Hangouts Chat service' do
let(:service_name) { 'hangouts-chat' }
let(:params) do
{
webhook: 'https://hook.example.com',
branches_to_be_notified: 'default'
}
end
before do
project.create_hangouts_chat_service(
active: true,
properties: params
)
end
it 'accepts branches_to_be_notified for update', :aggregate_failures do
put api("/projects/#{project.id}/services/#{service_name}", user), params: params.merge(branches_to_be_notified: 'all')
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['properties']['branches_to_be_notified']).to eq('all')
end
it 'only requires the webhook param' do
put api("/projects/#{project.id}/services/#{service_name}", user), params: { webhook: 'https://hook.example.com' }
expect(response).to have_gitlab_http_status(:ok)
end
end
end