Commit f474a0e3 authored by GitLab Bot's avatar GitLab Bot

Automatic merge of gitlab-org/gitlab master

parents 8e61e9a1 3e372137
......@@ -475,7 +475,11 @@ export default {
},
setDiscussions() {
requestIdleCallback(
() => this.assignDiscussionsToDiff().then(this.$nextTick).then(this.startTaskList),
() =>
this.assignDiscussionsToDiff()
.then(this.$nextTick)
.then(this.startTaskList)
.then(this.scrollVirtualScrollerToDiffNote),
{ timeout: 1000 },
);
},
......@@ -539,6 +543,22 @@ export default {
this.virtualScrollCurrentIndex = -1;
},
scrollVirtualScrollerToDiffNote() {
if (!window.gon?.features?.diffsVirtualScrolling) return;
const id = window?.location?.hash;
if (id.startsWith('#note_')) {
const noteId = id.replace('#note_', '');
const discussion = this.$store.state.notes.discussions.find((d) =>
d.notes.find((n) => n.id === noteId),
);
if (discussion) {
this.scrollVirtualScrollerToFileHash(discussion.diff_file.file_hash);
}
}
},
},
minTreeWidth: MIN_TREE_WIDTH,
maxTreeWidth: MAX_TREE_WIDTH,
......
......@@ -66,3 +66,5 @@ module Mutations
end
end
end
Mutations::Ci::Runner::Update.prepend_mod_with('Mutations::Ci::Runner::Update')
......@@ -3558,6 +3558,8 @@ Input type: `RunnerUpdateInput`
| <a id="mutationrunnerupdateid"></a>`id` | [`CiRunnerID!`](#cirunnerid) | ID of the runner to update. |
| <a id="mutationrunnerupdatelocked"></a>`locked` | [`Boolean`](#boolean) | Indicates the runner is locked. |
| <a id="mutationrunnerupdatemaximumtimeout"></a>`maximumTimeout` | [`Int`](#int) | Maximum timeout (in seconds) for jobs processed by the runner. |
| <a id="mutationrunnerupdateprivateprojectsminutescostfactor"></a>`privateProjectsMinutesCostFactor` | [`Float`](#float) | Private projects' "minutes cost factor" associated with the runner (GitLab.com only). |
| <a id="mutationrunnerupdatepublicprojectsminutescostfactor"></a>`publicProjectsMinutesCostFactor` | [`Float`](#float) | Public projects' "minutes cost factor" associated with the runner (GitLab.com only). |
| <a id="mutationrunnerupdaterununtagged"></a>`runUntagged` | [`Boolean`](#boolean) | Indicates the runner is able to run untagged jobs. |
| <a id="mutationrunnerupdatetaglist"></a>`tagList` | [`[String!]`](#string) | Tags associated with the runner. |
......
# frozen_string_literal: true
module EE
module Mutations
module Ci
module Runner
module Update
extend ActiveSupport::Concern
extend ::Gitlab::Utils::Override
prepended do
argument :public_projects_minutes_cost_factor, GraphQL::FLOAT_TYPE,
required: false,
description: 'Public projects\' "minutes cost factor" associated with the runner (GitLab.com only).'
argument :private_projects_minutes_cost_factor, GraphQL::FLOAT_TYPE,
required: false,
description: 'Private projects\' "minutes cost factor" associated with the runner (GitLab.com only).'
end
end
end
end
end
end
......@@ -15,4 +15,4 @@
= _('The Advanced Search in GitLab is a powerful search service that saves you time. Instead of creating duplicate code and wasting time, you can now search for code within other teams that can help your own project.')
= link_to _('Read more'), help_page_path('user/search/advanced_search.md'), target: '_blank'
= render 'shared/promotions/promotion_link_project'
= render 'shared/promotions/promotion_link_project', location: :advanced_search
......@@ -11,4 +11,4 @@
= _('Audit Events is a way to keep track of important events that happened in GitLab.')
= link_to _('Read more'), help_page_path('administration/audit_events.md'), target: '_blank'
= render 'shared/promotions/promotion_link_project'
= render 'shared/promotions/promotion_link_project', location: :audit_events
......@@ -17,4 +17,4 @@
= s_('Promotions|Burndown Charts are visual representations of the progress of completing a milestone. At a glance, you see the current state for the completion a given milestone. Without them, you would have to organize the data from the milestone and plot it yourself to have the same sense of progress.')
= link_to _('Read more'), help_page_path('user/project/milestones/burndown_and_burnup_charts.md'), target: '_blank'
= render 'shared/promotions/promotion_link_project'
= render 'shared/promotions/promotion_link_project', location: :burndown_charts
......@@ -11,4 +11,4 @@
= s_('Promotions|With Contribution Analytics you can have an overview for the activity of issues, merge requests, and push events of your organization and its members.')
= link_to _('Read more'), help_page_path('user/group/contribution_analytics/index.md'), target: '_blank'
= render 'shared/promotions/promotion_link_project'
= render 'shared/promotions/promotion_link_project', location: :contribution_analytics
......@@ -21,7 +21,7 @@
= s_('Promotions|Epics let you manage your portfolio of projects more efficiently and with less effort by tracking groups of issues that share a theme, across projects and milestones.')
= link_to s_('Read more'), 'https://docs.gitlab.com/ee/user/group/epics/', class: 'btn-link', target: '_blank'
.gl-flex-wrap
= render 'shared/promotions/promotion_link_project', short_form: true
= render 'shared/promotions/promotion_link_project', short_form: true, location: :epics
= link_to s_("Promotions|Don't show me this again"), '#', class: 'gl-button btn js-close js-close-callout gl-mt-2'
.hide-collapsed
......
......@@ -11,4 +11,4 @@
= _('Webhooks allow you to trigger a URL if, for example, new code is pushed or a new issue is created. You can configure webhooks to listen for specific events like pushes, issues or merge requests. Group webhooks will apply to all projects in a group, allowing you to standardize webhook functionality across your entire group.')
= link_to _('Read more'), help_page_path('user/project/integrations/webhooks.md'), target: '_blank'
.gl-mt-5
= render 'shared/promotions/promotion_link_project'
= render 'shared/promotions/promotion_link_project', location: :group_webhooks
......@@ -12,4 +12,4 @@
= _('Description templates allow you to define context-specific templates for issue and merge request description fields for your project.')
= link_to _('Read more'), help_page_path('user/project/description_templates'), class: 'btn-link'
%div
= render 'shared/promotions/promotion_link_project'
= render 'shared/promotions/promotion_link_project', location: :issue_templates
......@@ -30,5 +30,5 @@
- else
= s_('Promotions|Improve issues management with Issue weight and GitLab Enterprise Edition.')
%div
= render 'shared/promotions/promotion_link_project', short_form: true, target_blank: false
= render 'shared/promotions/promotion_link_project', short_form: true, target_blank: false, location: :issue_weights
= link_to s_("Promotions|Not now, thanks!"), '#', class: ['gl-button', 'btn', 'js-close', 'js-close-callout', 'gl-mt-3', 'js-close-session', 'tr-issue-weights-not-now-cta']
......@@ -16,4 +16,4 @@
%p
= _('Set the number of necessary approvals and define a list of approvers needed for every merge request in a project.')
= render 'shared/promotions/promotion_link_project'
= render 'shared/promotions/promotion_link_project', location: :mr_features
......@@ -28,4 +28,4 @@
%p
You can restrict access to protected branches by choosing a role (Maintainers, Developers) as well as certain users.
= render 'shared/promotions/promotion_link_project'
= render 'shared/promotions/promotion_link_project', location: :repository_features
......@@ -4,7 +4,7 @@
- if Gitlab::CurrentSettings.should_check_namespace_plan?
- namespace = @project&.namespace || @group
- if can?(current_user, :admin_namespace, namespace)
= link_to s_('Promotions|Try it for free'), new_trial_registration_path(glm_source: 'gitlab.com', glm_content: 'discover-issue-weights'), class: 'btn gl-button btn-confirm issue-weights-trial-cta', target: target_blank ? '_blank' : '_self'
= link_to s_('Promotions|Try it for free'), new_trial_registration_path(glm_source: 'gitlab.com', glm_content: location), class: 'btn gl-button btn-confirm promotion-trial-cta', target: target_blank ? '_blank' : '_self'
- elsif namespace.is_a?(Group)
%p= s_('Promotions|Contact an owner of group %{namespace_name} to upgrade the plan.') % { namespace_name: namespace.name }
- else
......
......@@ -230,7 +230,7 @@ RSpec.describe 'Promotions', :js do
click_link 'Learn more'
expect(page).to have_link 'Try it for free', href: new_trial_registration_path(glm_source: 'gitlab.com', glm_content: 'discover-issue-weights'), class: 'issue-weights-trial-cta'
expect(page).to have_link 'Try it for free', href: new_trial_registration_path(glm_source: 'gitlab.com', glm_content: 'issue_weights'), class: 'promotion-trial-cta'
expect(find('.js-close-callout.js-close-session.tr-issue-weights-not-now-cta')).to have_content 'Not now, thanks!'
end
end
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Mutations::Ci::Runner::Update do
include GraphqlHelpers
describe '#resolve' do
let(:runner) do
create(:ci_runner, active: true, locked: false, run_untagged: true, public_projects_minutes_cost_factor: 0.0,
private_projects_minutes_cost_factor: 0.0)
end
let(:mutation) { described_class.new(object: nil, context: current_ctx, field: nil) }
subject(:mutation_result) { mutation.resolve(id: runner.to_global_id, **mutation_params) }
def resolve
mutation_result
runner.reload
end
context 'when user can update runner', :enable_admin_mode do
let(:admin_user) { create(:user, :admin) }
let(:current_ctx) { { current_user: admin_user } }
context 'when mutation includes cost factor arguments' do
let(:mutation_params) do
{
public_projects_minutes_cost_factor: 2.5,
private_projects_minutes_cost_factor: 0.5
}
end
it 'updates cost factors to specified values', :aggregate_failures do
expect { resolve }
.to change { runner.public_projects_minutes_cost_factor }.from(0).to(2.5)
.and change { runner.private_projects_minutes_cost_factor }.from(0).to(0.5)
end
end
end
end
end
......@@ -6,6 +6,8 @@ RSpec.describe 'admin/application_settings/general.html.haml' do
let_it_be(:user) { create(:admin) }
let_it_be(:app_settings) { build(:application_setting) }
subject { rendered }
before do
assign(:application_setting, app_settings)
allow(view).to receive(:current_user).and_return(user)
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'shared/_promotion_link_project' do
let_it_be(:user) { create(:user) }
let_it_be(:namespace) { create(:group, name: 'Our group') }
subject do
render 'shared/promotions/promotion_link_project', location: 'some_location'
rendered
end
before do
allow(view).to receive(:current_user).and_return(user)
@group = namespace
end
context 'with namespace plans ' do
before do
stub_application_setting(check_namespace_plan: true)
end
context 'for namespace admin users' do
before do
namespace.add_owner(user)
end
it do
is_expected.to have_link 'Try it for free', href: new_trial_registration_path(glm_source: 'gitlab.com', glm_content: 'some_location')
end
end
context 'for regular users' do
context 'for groups' do
it { is_expected.to have_text("Contact an owner of group Our group to upgrade the plan.") }
end
context 'for a project in a personal namespace' do
let_it_be(:user2) { create(:user, name: 'Joe') }
let_it_be(:project) { create(:project, namespace: user2.namespace) }
before do
@project = project
end
it { is_expected.to have_text("Contact owner Joe to upgrade the plan.") }
end
end
end
context 'with instance plans' do
before do
stub_application_setting(check_namespace_plan: false)
end
context 'for admin users' do
let_it_be(:user) { create(:admin) }
context 'with active license' do
it { is_expected.to have_text('Start GitLab Ultimate trial') }
end
context 'with expired license' do
let_it_be(:expired_license) { create(:license, expired: true) }
before do
allow(License).to receive(:current).and_return(expired_license)
end
it { is_expected.to have_text('Buy GitLab Enterprise Edition') }
end
end
context 'for regular users' do
it { is_expected.to have_text('Contact your Administrator to upgrade your license.') }
end
end
end
......@@ -37,6 +37,7 @@ module Gitlab
allow_webpack_dev_server(settings_hash) if Rails.env.development?
allow_cdn(settings_hash) if ENV['GITLAB_CDN_HOST'].present?
allow_customersdot(settings_hash) if Rails.env.development? && ENV['CUSTOMER_PORTAL_URL'].present?
settings_hash
end
......@@ -85,6 +86,12 @@ module Gitlab
def self.append_to_directive(settings_hash, directive, text)
settings_hash['directives'][directive] = "#{settings_hash['directives'][directive]} #{text}".strip
end
def self.allow_customersdot(settings_hash)
customersdot_host = ENV['CUSTOMER_PORTAL_URL']
append_to_directive(settings_hash, 'frame_src', customersdot_host)
end
end
end
end
......@@ -61,6 +61,36 @@ RSpec.describe Gitlab::ContentSecurityPolicy::ConfigLoader do
expect(directives['font_src']).to eq("'self' https://example.com")
end
end
context 'when CUSTOMER_PORTAL_URL is set' do
before do
stub_env('CUSTOMER_PORTAL_URL', 'https://customers.example.com')
end
context 'when in production' do
before do
allow(Rails).to receive(:env).and_return(ActiveSupport::StringInquirer.new('production'))
end
it 'does not add CUSTOMER_PORTAL_URL to CSP' do
directives = settings['directives']
expect(directives['frame_src']).to eq("'self' https://www.google.com/recaptcha/ https://www.recaptcha.net/ https://content.googleapis.com https://content-compute.googleapis.com https://content-cloudbilling.googleapis.com https://content-cloudresourcemanager.googleapis.com")
end
end
context 'when in development' do
before do
allow(Rails).to receive(:env).and_return(ActiveSupport::StringInquirer.new('development'))
end
it 'adds CUSTOMER_PORTAL_URL to CSP' do
directives = settings['directives']
expect(directives['frame_src']).to eq("'self' https://www.google.com/recaptcha/ https://www.recaptcha.net/ https://content.googleapis.com https://content-compute.googleapis.com https://content-cloudbilling.googleapis.com https://content-cloudresourcemanager.googleapis.com https://customers.example.com")
end
end
end
end
describe '#load' do
......
......@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe Integrations::MicrosoftTeams do
let(:chat_service) { described_class.new }
let(:chat_integration) { described_class.new }
let(:webhook_url) { 'https://example.gitlab.com/' }
describe "Associations" do
......@@ -12,16 +12,16 @@ RSpec.describe Integrations::MicrosoftTeams do
end
describe 'Validations' do
context 'when service is active' do
context 'when integration is active' do
before do
subject.active = true
end
it { is_expected.to validate_presence_of(:webhook) }
it_behaves_like 'issue tracker service URL attribute', :webhook
it_behaves_like 'issue tracker integration URL attribute', :webhook
end
context 'when service is inactive' do
context 'when integration is inactive' do
before do
subject.active = false
end
......@@ -42,7 +42,7 @@ RSpec.describe Integrations::MicrosoftTeams do
let_it_be(:project) { create(:project, :repository, :wiki_repo) }
before do
allow(chat_service).to receive_messages(
allow(chat_integration).to receive_messages(
project: project,
project_id: project.id,
service_hook: true,
......@@ -58,7 +58,7 @@ RSpec.describe Integrations::MicrosoftTeams do
end
it "calls Microsoft Teams API for push events" do
chat_service.execute(push_sample_data)
chat_integration.execute(push_sample_data)
expect(WebMock).to have_requested(:post, webhook_url).once
end
......@@ -67,7 +67,7 @@ RSpec.describe Integrations::MicrosoftTeams do
integration = double(:microsoft_teams_integration).as_null_object
expect(::MicrosoftTeams::Notifier).to receive(:new).with(webhook_url).and_return(integration)
chat_service.execute(push_sample_data)
chat_integration.execute(push_sample_data)
end
end
......@@ -80,7 +80,7 @@ RSpec.describe Integrations::MicrosoftTeams do
end
it "calls Microsoft Teams API" do
chat_service.execute(issues_sample_data)
chat_integration.execute(issues_sample_data)
expect(WebMock).to have_requested(:post, webhook_url).once
end
......@@ -107,7 +107,7 @@ RSpec.describe Integrations::MicrosoftTeams do
end
it "calls Microsoft Teams API" do
chat_service.execute(merge_sample_data)
chat_integration.execute(merge_sample_data)
expect(WebMock).to have_requested(:post, webhook_url).once
end
......@@ -127,7 +127,7 @@ RSpec.describe Integrations::MicrosoftTeams do
let(:wiki_page_sample_data) { Gitlab::DataBuilder::WikiPage.build(wiki_page, user, 'create') }
it "calls Microsoft Teams API" do
chat_service.execute(wiki_page_sample_data)
chat_integration.execute(wiki_page_sample_data)
expect(WebMock).to have_requested(:post, webhook_url).once
end
......@@ -139,7 +139,7 @@ RSpec.describe Integrations::MicrosoftTeams do
let(:project) { create(:project, :repository, creator: user) }
before do
allow(chat_service).to receive_messages(
allow(chat_integration).to receive_messages(
project: project,
project_id: project.id,
service_hook: true,
......@@ -160,7 +160,7 @@ RSpec.describe Integrations::MicrosoftTeams do
it "calls Microsoft Teams API for commit comment events" do
data = Gitlab::DataBuilder::Note.build(commit_note, user)
chat_service.execute(data)
chat_integration.execute(data)
expect(WebMock).to have_requested(:post, webhook_url).once
end
......@@ -175,7 +175,7 @@ RSpec.describe Integrations::MicrosoftTeams do
it "calls Microsoft Teams API for merge request comment events" do
data = Gitlab::DataBuilder::Note.build(merge_request_note, user)
chat_service.execute(data)
chat_integration.execute(data)
expect(WebMock).to have_requested(:post, webhook_url).once
end
......@@ -189,7 +189,7 @@ RSpec.describe Integrations::MicrosoftTeams do
it "calls Microsoft Teams API for issue comment events" do
data = Gitlab::DataBuilder::Note.build(issue_note, user)
chat_service.execute(data)
chat_integration.execute(data)
expect(WebMock).to have_requested(:post, webhook_url).once
end
......@@ -204,7 +204,7 @@ RSpec.describe Integrations::MicrosoftTeams do
it "calls Microsoft Teams API for snippet comment events" do
data = Gitlab::DataBuilder::Note.build(snippet_note, user)
chat_service.execute(data)
chat_integration.execute(data)
expect(WebMock).to have_requested(:post, webhook_url).once
end
......@@ -222,7 +222,7 @@ RSpec.describe Integrations::MicrosoftTeams do
end
before do
allow(chat_service).to receive_messages(
allow(chat_integration).to receive_messages(
project: project,
service_hook: true,
webhook: webhook_url
......@@ -232,14 +232,14 @@ RSpec.describe Integrations::MicrosoftTeams do
shared_examples 'call Microsoft Teams API' do |branches_to_be_notified: nil|
before do
WebMock.stub_request(:post, webhook_url)
chat_service.branches_to_be_notified = branches_to_be_notified if branches_to_be_notified
chat_integration.branches_to_be_notified = branches_to_be_notified if branches_to_be_notified
end
it 'calls Microsoft Teams API for pipeline events' do
data = Gitlab::DataBuilder::Pipeline.build(pipeline)
data[:markdown] = true
chat_service.execute(data)
chat_integration.execute(data)
message = Integrations::ChatMessage::PipelineMessage.new(data)
......@@ -251,11 +251,11 @@ RSpec.describe Integrations::MicrosoftTeams do
shared_examples 'does not call Microsoft Teams API' do |branches_to_be_notified: nil|
before do
chat_service.branches_to_be_notified = branches_to_be_notified if branches_to_be_notified
chat_integration.branches_to_be_notified = branches_to_be_notified if branches_to_be_notified
end
it 'does not call Microsoft Teams API for pipeline events' do
data = Gitlab::DataBuilder::Pipeline.build(pipeline)
result = chat_service.execute(data)
result = chat_integration.execute(data)
expect(result).to be_falsy
end
......@@ -273,7 +273,7 @@ RSpec.describe Integrations::MicrosoftTeams do
context 'with default to notify_only_broken_pipelines' do
it 'does not call Microsoft Teams API for pipeline events' do
data = Gitlab::DataBuilder::Pipeline.build(pipeline)
result = chat_service.execute(data)
result = chat_integration.execute(data)
expect(result).to be_falsy
end
......@@ -281,7 +281,7 @@ RSpec.describe Integrations::MicrosoftTeams do
context 'with setting notify_only_broken_pipelines to false' do
before do
chat_service.notify_only_broken_pipelines = false
chat_integration.notify_only_broken_pipelines = false
end
it_behaves_like 'call Microsoft Teams API'
......
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