Commit 20308a92 authored by GitLab Bot's avatar GitLab Bot

Automatic merge of gitlab-org/gitlab master

parents 1b0cdd5d 73756dad
...@@ -224,7 +224,7 @@ export default { ...@@ -224,7 +224,7 @@ export default {
<a <a
ref="titleWrapper" ref="titleWrapper"
:v-once="!viewDiffsFileByFile" :v-once="!viewDiffsFileByFile"
class="gl-mr-2" class="gl-mr-2 gl-text-decoration-none!"
:href="titleLink" :href="titleLink"
@click="handleFileNameClick" @click="handleFileNameClick"
> >
......
...@@ -170,13 +170,13 @@ export default { ...@@ -170,13 +170,13 @@ export default {
.map(({ variable_type, key, value }) => ({ .map(({ variable_type, key, value }) => ({
variable_type, variable_type,
key, key,
value, secret_value: value,
})); }));
return axios return axios
.post(this.pipelinesPath, { .post(this.pipelinesPath, {
ref: this.refValue, ref: this.refValue,
variables: filteredVariables, variables_attributes: filteredVariables,
}) })
.then(({ data }) => { .then(({ data }) => {
redirectTo(`${this.pipelinesPath}/${data.id}`); redirectTo(`${this.pipelinesPath}/${data.id}`);
......
<script> <script>
import { GlIcon } from '@gitlab/ui'; import { GlIcon, GlTooltipDirective } from '@gitlab/ui';
import '~/lib/utils/datetime_utility'; import '~/lib/utils/datetime_utility';
import tooltip from '~/vue_shared/directives/tooltip';
import timeagoMixin from '~/vue_shared/mixins/timeago'; import timeagoMixin from '~/vue_shared/mixins/timeago';
export default { export default {
directives: { directives: {
tooltip, GlTooltip: GlTooltipDirective,
}, },
components: { GlIcon }, components: { GlIcon },
mixins: [timeagoMixin], mixins: [timeagoMixin],
...@@ -63,7 +62,7 @@ export default { ...@@ -63,7 +62,7 @@ export default {
<gl-icon name="calendar" class="gl-vertical-align-baseline!" aria-hidden="true" /> <gl-icon name="calendar" class="gl-vertical-align-baseline!" aria-hidden="true" />
<time <time
v-tooltip v-gl-tooltip
:title="tooltipTitle(finishedTime)" :title="tooltipTitle(finishedTime)"
data-placement="top" data-placement="top"
data-container="body" data-container="body"
......
import LineHighlighter from '~/line_highlighter';
import BlobViewer from '~/blob/viewer';
import ZenMode from '~/zen_mode';
import initNotes from '~/init_notes'; import initNotes from '~/init_notes';
import snippetEmbed from '~/snippet/snippet_embed';
import { SnippetShowInit } from '~/snippets';
import loadAwardsHandler from '~/awards_handler'; import loadAwardsHandler from '~/awards_handler';
document.addEventListener('DOMContentLoaded', () => { if (!gon.features.snippetsVue) {
if (!gon.features.snippetsVue) { const LineHighlighterModule = import('~/line_highlighter');
new LineHighlighter(); // eslint-disable-line no-new const BlobViewerModule = import('~/blob/viewer');
new BlobViewer(); // eslint-disable-line no-new const ZenModeModule = import('~/zen_mode');
initNotes(); const SnippetEmbedModule = import('~/snippet/snippet_embed');
new ZenMode(); // eslint-disable-line no-new
snippetEmbed(); Promise.all([LineHighlighterModule, BlobViewerModule, ZenModeModule, SnippetEmbedModule])
} else { .then(
SnippetShowInit(); ([
initNotes(); { default: LineHighlighter },
} { default: BlobViewer },
loadAwardsHandler(); { default: ZenMode },
}); { default: SnippetEmbed },
]) => {
new LineHighlighter(); // eslint-disable-line no-new
new BlobViewer(); // eslint-disable-line no-new
new ZenMode(); // eslint-disable-line no-new
SnippetEmbed();
},
)
.catch(() => {});
} else {
import('~/snippets')
.then(({ SnippetShowInit }) => {
SnippetShowInit();
})
.catch(() => {});
}
initNotes();
loadAwardsHandler();
...@@ -3,8 +3,6 @@ import VueApollo from 'vue-apollo'; ...@@ -3,8 +3,6 @@ import VueApollo from 'vue-apollo';
import Translate from '~/vue_shared/translate'; import Translate from '~/vue_shared/translate';
import createDefaultClient from '~/lib/graphql'; import createDefaultClient from '~/lib/graphql';
import SnippetsShow from './components/show.vue';
import SnippetsEdit from './components/edit.vue';
import { SNIPPET_LEVELS_MAP, SNIPPET_VISIBILITY_PRIVATE } from '~/snippets/constants'; import { SNIPPET_LEVELS_MAP, SNIPPET_VISIBILITY_PRIVATE } from '~/snippets/constants';
Vue.use(VueApollo); Vue.use(VueApollo);
...@@ -48,9 +46,17 @@ function appFactory(el, Component) { ...@@ -48,9 +46,17 @@ function appFactory(el, Component) {
} }
export const SnippetShowInit = () => { export const SnippetShowInit = () => {
appFactory(document.getElementById('js-snippet-view'), SnippetsShow); import('./components/show.vue')
.then(({ default: SnippetsShow }) => {
appFactory(document.getElementById('js-snippet-view'), SnippetsShow);
})
.catch(() => {});
}; };
export const SnippetEditInit = () => { export const SnippetEditInit = () => {
appFactory(document.getElementById('js-snippet-edit'), SnippetsEdit); import('./components/edit.vue')
.then(({ default: SnippetsEdit }) => {
appFactory(document.getElementById('js-snippet-edit'), SnippetsEdit);
})
.catch(() => {});
}; };
...@@ -189,15 +189,6 @@ ...@@ -189,15 +189,6 @@
background-color: $gray-darker; background-color: $gray-darker;
color: $gl-text-color; color: $gl-text-color;
outline: 0; outline: 0;
// make sure the text color is not overridden
&.text-danger {
color: $brand-danger;
}
.avatar {
border-color: $white;
}
} }
@mixin dropdown-link { @mixin dropdown-link {
...@@ -216,11 +207,6 @@ ...@@ -216,11 +207,6 @@
text-align: left; text-align: left;
width: 100%; width: 100%;
// make sure the text color is not overridden
&.text-danger {
color: $brand-danger;
}
&.disable-hover { &.disable-hover {
text-decoration: none; text-decoration: none;
} }
...@@ -232,10 +218,6 @@ ...@@ -232,10 +218,6 @@
@include dropdown-item-hover; @include dropdown-item-hover;
text-decoration: none; text-decoration: none;
.badge.badge-pill {
background-color: darken($blue-50, 5%);
}
} }
&.dropdown-menu-user-link { &.dropdown-menu-user-link {
......
...@@ -28,10 +28,6 @@ ...@@ -28,10 +28,6 @@
text-decoration: none; text-decoration: none;
color: $black; color: $black;
border-bottom: 2px solid $gray-darkest; border-bottom: 2px solid $gray-darkest;
.badge.badge-pill {
color: $black;
}
} }
} }
......
...@@ -439,10 +439,6 @@ ...@@ -439,10 +439,6 @@
content: '\f0c6'; content: '\f0c6';
} }
&:hover::before {
text-decoration: none;
}
&.no-attachment-icon { &.no-attachment-icon {
&::before { &::before {
display: none; display: none;
......
...@@ -29,11 +29,6 @@ ...@@ -29,11 +29,6 @@
.ref-name { .ref-name {
font-size: 12px; font-size: 12px;
&:hover {
text-decoration: underline;
color: $gl-text-color;
}
} }
} }
......
...@@ -70,10 +70,6 @@ ...@@ -70,10 +70,6 @@
} }
} }
a:hover {
text-decoration: none;
}
&:hover { &:hover {
background-color: $gray-normal; background-color: $gray-normal;
} }
......
...@@ -80,7 +80,7 @@ module Mutations ...@@ -80,7 +80,7 @@ module Mutations
raise Gitlab::Graphql::Errors::ArgumentError, ANNOTATION_SOURCE_ARGUMENT_ERROR raise Gitlab::Graphql::Errors::ArgumentError, ANNOTATION_SOURCE_ARGUMENT_ERROR
end end
super(args) super(**args)
end end
def find_object(id:) def find_object(id:)
......
...@@ -1690,6 +1690,10 @@ class MergeRequest < ApplicationRecord ...@@ -1690,6 +1690,10 @@ class MergeRequest < ApplicationRecord
Feature.enabled?(:merge_request_reviewers, project) Feature.enabled?(:merge_request_reviewers, project)
end end
def allows_multiple_reviewers?
false
end
private private
def with_rebase_lock def with_rebase_lock
......
...@@ -110,6 +110,10 @@ module MergeRequests ...@@ -110,6 +110,10 @@ module MergeRequests
return return
end end
unless merge_request.allows_multiple_reviewers?
params[:reviewer_ids] = params[:reviewer_ids].first(1)
end
reviewer_ids = params[:reviewer_ids].select { |reviewer_id| user_can_read?(merge_request, reviewer_id) } reviewer_ids = params[:reviewer_ids].select { |reviewer_id| user_can_read?(merge_request, reviewer_id) }
if params[:reviewer_ids].map(&:to_s) == [IssuableFinder::Params::NONE] if params[:reviewer_ids].map(&:to_s) == [IssuableFinder::Params::NONE]
......
...@@ -21,12 +21,12 @@ if app.config.public_file_server.enabled ...@@ -21,12 +21,12 @@ if app.config.public_file_server.enabled
settings = { settings = {
enabled: true, enabled: true,
host: dev_server.host, host: dev_server.host,
manifest_host: dev_server.host,
manifest_port: dev_server.port,
port: dev_server.port port: dev_server.port
} }
if Rails.env.development? if Rails.env.development?
# /assets are proxied through a Rails middlware to the Webpack
# server, so we have to use the local Rails settings.
settings.merge!( settings.merge!(
host: Gitlab.config.gitlab.host, host: Gitlab.config.gitlab.host,
port: Gitlab.config.gitlab.port, port: Gitlab.config.gitlab.port,
......
...@@ -9,8 +9,6 @@ type: howto ...@@ -9,8 +9,6 @@ type: howto
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/20912) in GitLab 12.6. > [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/20912) in GitLab 12.6.
## Overview
GitLab administrators are responsible for the overall security of their instance. To assist, GitLab provides a Credentials inventory to keep track of all the credentials that can be used to access their self-managed instance. GitLab administrators are responsible for the overall security of their instance. To assist, GitLab provides a Credentials inventory to keep track of all the credentials that can be used to access their self-managed instance.
Using Credentials inventory, you can see all the personal access tokens (PAT) and SSH keys that exist in your GitLab instance. In addition, you can [revoke them](#revoke-a-users-personal-access-token) and see: Using Credentials inventory, you can see all the personal access tokens (PAT) and SSH keys that exist in your GitLab instance. In addition, you can [revoke them](#revoke-a-users-personal-access-token) and see:
......
...@@ -9,8 +9,6 @@ info: To determine the technical writer assigned to the Stage/Group associated w ...@@ -9,8 +9,6 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> - Introduced in [GitLab Starter](https://about.gitlab.com/pricing/) 8.3. > - Introduced in [GitLab Starter](https://about.gitlab.com/pricing/) 8.3.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/3090) for subgroups in GitLab 12.2. > - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/3090) for subgroups in GitLab 12.2.
## Overview
With Contribution Analytics you can get an overview of the following activity in your With Contribution Analytics you can get an overview of the following activity in your
group: group:
......
...@@ -51,7 +51,7 @@ Furthermore, the bot user can not be added to any other project. ...@@ -51,7 +51,7 @@ Furthermore, the bot user can not be added to any other project.
- The username is set to `project_{project_id}_bot` for the first access token, such as `project_123_bot`. - The username is set to `project_{project_id}_bot` for the first access token, such as `project_123_bot`.
- The username is set to `project_{project_id}_bot{bot_count}` for further access tokens, such as `project_123_bot1`. - The username is set to `project_{project_id}_bot{bot_count}` for further access tokens, such as `project_123_bot1`.
After the project access token is [revoked](#revoking-a-project-access-token), the bot user is removed from the project and blocked. All associated records are moved to a system-wide user named "Ghost User". For more information, see [Associated Records](../../profile/account/delete_account.md#associated-records). When the project access token is [revoked](#revoking-a-project-access-token) the bot user is then deleted and all records are moved to a system-wide user with the username "Ghost User". For more information, see [Associated Records](../../profile/account/delete_account.md#associated-records).
Project bot users are a [GitLab-created service account](../../../subscriptions/self_managed/index.md#choose-the-number-of-users), but count as a licensed seat. Project bot users are a [GitLab-created service account](../../../subscriptions/self_managed/index.md#choose-the-number-of-users), but count as a licensed seat.
These users will not count against your licensed seat in the future when [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/223695) is resolved. These users will not count against your licensed seat in the future when [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/223695) is resolved.
......
...@@ -8,6 +8,7 @@ class TrialsController < ApplicationController ...@@ -8,6 +8,7 @@ class TrialsController < ApplicationController
before_action :check_if_gl_com_or_dev before_action :check_if_gl_com_or_dev
before_action :authenticate_user! before_action :authenticate_user!
before_action :find_or_create_namespace, only: :apply before_action :find_or_create_namespace, only: :apply
before_action :record_user_for_group_only_trials_experiment, only: :select
def new def new
end end
...@@ -97,4 +98,8 @@ class TrialsController < ApplicationController ...@@ -97,4 +98,8 @@ class TrialsController < ApplicationController
group group
end end
def record_user_for_group_only_trials_experiment
record_experiment_user(:group_only_trials)
end
end end
...@@ -66,6 +66,8 @@ module EE ...@@ -66,6 +66,8 @@ module EE
end end
def trial_user_namespaces def trial_user_namespaces
return [] if experiment_enabled?(:group_only_trials)
strong_memoize(:trial_user_namespaces) do strong_memoize(:trial_user_namespaces) do
user_namespace = current_user.namespace user_namespace = current_user.namespace
user_namespace.eligible_for_trial? ? [user_namespace] : [] user_namespace.eligible_for_trial? ? [user_namespace] : []
......
...@@ -120,6 +120,10 @@ module EE ...@@ -120,6 +120,10 @@ module EE
project.feature_available?(:multiple_merge_request_assignees) project.feature_available?(:multiple_merge_request_assignees)
end end
def allows_multiple_reviewers?
project.feature_available?(:multiple_merge_request_reviewers)
end
def visible_blocking_merge_requests(user) def visible_blocking_merge_requests(user)
Ability.merge_requests_readable_by_user(blocking_merge_requests, user) Ability.merge_requests_readable_by_user(blocking_merge_requests, user)
end end
......
...@@ -29,6 +29,7 @@ class License < ApplicationRecord ...@@ -29,6 +29,7 @@ class License < ApplicationRecord
multiple_issue_assignees multiple_issue_assignees
multiple_ldap_servers multiple_ldap_servers
multiple_merge_request_assignees multiple_merge_request_assignees
multiple_merge_request_reviewers
project_merge_request_analytics project_merge_request_analytics
protected_refs_for_users protected_refs_for_users
push_rules push_rules
......
...@@ -16,7 +16,7 @@ module Geo ...@@ -16,7 +16,7 @@ module Geo
rescue Gitlab::Shell::Error, Gitlab::Git::BaseError => e rescue Gitlab::Shell::Error, Gitlab::Git::BaseError => e
# In some cases repository does not exist, the only way to know about this is to parse the error text. # In some cases repository does not exist, the only way to know about this is to parse the error text.
# If it does not exist we should consider it as successfully downloaded. # If it does not exist we should consider it as successfully downloaded.
if e.message.include? Gitlab::GitAccess::ERROR_MESSAGES[:no_repo] # rubocop:disable Cop/LineBreakAroundConditionalBlock if e.message.include? Gitlab::GitAccessDesign::ERROR_MESSAGES[:no_repo] # rubocop:disable Cop/LineBreakAroundConditionalBlock
log_info('Design repository is not found, marking it as successfully synced') log_info('Design repository is not found, marking it as successfully synced')
mark_sync_as_successful(missing_on_primary: true) mark_sync_as_successful(missing_on_primary: true)
else else
......
...@@ -16,7 +16,7 @@ module Geo ...@@ -16,7 +16,7 @@ module Geo
rescue Gitlab::Shell::Error, Gitlab::Git::BaseError, Wiki::CouldNotCreateWikiError => e rescue Gitlab::Shell::Error, Gitlab::Git::BaseError, Wiki::CouldNotCreateWikiError => e
# In some cases repository does not exist, the only way to know about this is to parse the error text. # In some cases repository does not exist, the only way to know about this is to parse the error text.
# If it does not exist we should consider it as successfully downloaded. # If it does not exist we should consider it as successfully downloaded.
if e.message.include? Gitlab::GitAccess::ERROR_MESSAGES[:no_repo] # rubocop:disable Cop/LineBreakAroundConditionalBlock if e.message.include? Gitlab::GitAccessWiki::ERROR_MESSAGES[:no_repo] # rubocop:disable Cop/LineBreakAroundConditionalBlock
if repository_presumably_exists_on_primary? if repository_presumably_exists_on_primary?
log_info('Wiki is not found, but it seems to exist on the primary') log_info('Wiki is not found, but it seems to exist on the primary')
fail_registry_sync!('Wiki is not found', e) fail_registry_sync!('Wiki is not found', e)
......
...@@ -3,5 +3,6 @@ ...@@ -3,5 +3,6 @@
- api_paths = @group.present? ? { milestones_path: group_milestones_path(@group), labels_path: group_labels_path(@group) } : {} - api_paths = @group.present? ? { milestones_path: group_milestones_path(@group), labels_path: group_labels_path(@group) } : {}
- image_paths = { empty_state_svg_path: image_path("illustrations/analytics/cycle-analytics-empty-chart.svg"), no_data_svg_path: image_path("illustrations/analytics/cycle-analytics-empty-chart.svg"), no_access_svg_path: image_path("illustrations/analytics/no-access.svg")} - image_paths = { empty_state_svg_path: image_path("illustrations/analytics/cycle-analytics-empty-chart.svg"), no_data_svg_path: image_path("illustrations/analytics/cycle-analytics-empty-chart.svg"), no_access_svg_path: image_path("illustrations/analytics/no-access.svg")}
- data_attributes.merge!(api_paths, image_paths) - data_attributes.merge!(api_paths, image_paths)
- add_page_specific_style 'page_bundles/cycle_analytics'
#js-cycle-analytics-app{ data: data_attributes } #js-cycle-analytics-app{ data: data_attributes }
---
title: Geo - Fix wikis with no repository on the primary trying to sync over and over
merge_request: 43765
author:
type: fixed
--- ---
name: gitlab_employee_badge name: gitlab_employee_badge
introduced_by_url: introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/issues/212259
rollout_issue_url: rollout_issue_url:
group: group: group::access
type: development type: development
default_enabled: false default_enabled: false
...@@ -7,7 +7,7 @@ module Gitlab ...@@ -7,7 +7,7 @@ module Gitlab
def wrap_errors(**args) def wrap_errors(**args)
yield yield
rescue Aws::Errors::ServiceError => e rescue Aws::Errors::ServiceError => e
raise Error, bucket: bucket_name, error: e, **args raise Error.new(bucket: bucket_name, error: e, **args)
end end
end end
end end
......
...@@ -120,13 +120,43 @@ RSpec.describe TrialsController do ...@@ -120,13 +120,43 @@ RSpec.describe TrialsController do
end end
describe '#select' do describe '#select' do
subject do def get_select
get :select get :select
end
subject do
get_select
response response
end end
it_behaves_like 'an authenticated endpoint' it_behaves_like 'an authenticated endpoint'
it_behaves_like 'a dot-com only feature' it_behaves_like 'a dot-com only feature'
context 'when the group-only trials experiment is active' do
before do
stub_experiment(group_only_trials: true)
stub_experiment_for_user(group_only_trials: user_is_in_experiment?)
end
def expected_group_type
user_is_in_experiment? ? 'experimental' : 'control'
end
where(user_is_in_experiment?: [true, false])
with_them do
it 'records the user as being part of the experiment' do
expect { get_select }.to change { ExperimentUser.count }.by(1)
expect(ExperimentUser.last.group_type).to eq(expected_group_type)
end
end
end
context 'when the group-only trials experiment is not active' do
it 'does not record the user as being part of the experiment' do
expect { get_select }.not_to change { ExperimentUser.count }
end
end
end end
describe '#apply' do describe '#apply' do
......
...@@ -118,6 +118,24 @@ RSpec.describe MergeRequest do ...@@ -118,6 +118,24 @@ RSpec.describe MergeRequest do
end end
end end
describe '#allows_multiple_reviewers?' do
it 'returns false without license' do
stub_licensed_features(multiple_merge_request_reviewers: false)
merge_request = build_stubbed(:merge_request)
expect(merge_request.allows_multiple_reviewers?).to be(false)
end
it 'returns true when licensed' do
stub_licensed_features(multiple_merge_request_reviewers: true)
merge_request = build(:merge_request)
expect(merge_request.allows_multiple_reviewers?).to be(true)
end
end
describe '#participants' do describe '#participants' do
context 'with approval rule' do context 'with approval rule' do
before do before do
......
...@@ -111,7 +111,7 @@ RSpec.describe Geo::DesignRepositorySyncService do ...@@ -111,7 +111,7 @@ RSpec.describe Geo::DesignRepositorySyncService do
allow(repository).to receive(:fetch_as_mirror) allow(repository).to receive(:fetch_as_mirror)
.with(url_to_repo, remote_name: 'geo', forced: true) .with(url_to_repo, remote_name: 'geo', forced: true)
.and_raise(Gitlab::Shell::Error.new(Gitlab::GitAccess::ERROR_MESSAGES[:no_repo])) .and_raise(Gitlab::Shell::Error.new(Gitlab::GitAccessDesign::ERROR_MESSAGES[:no_repo]))
subject.execute subject.execute
......
...@@ -85,7 +85,7 @@ RSpec.describe Geo::WikiSyncService, :geo do ...@@ -85,7 +85,7 @@ RSpec.describe Geo::WikiSyncService, :geo do
allow(repository).to receive(:fetch_as_mirror) allow(repository).to receive(:fetch_as_mirror)
.with(url_to_repo, remote_name: 'geo', forced: true) .with(url_to_repo, remote_name: 'geo', forced: true)
.and_raise(Gitlab::Shell::Error.new(Gitlab::GitAccess::ERROR_MESSAGES[:no_repo])) .and_raise(Gitlab::Shell::Error.new(Gitlab::GitAccessWiki::ERROR_MESSAGES[:no_repo]))
subject.execute subject.execute
...@@ -115,7 +115,7 @@ RSpec.describe Geo::WikiSyncService, :geo do ...@@ -115,7 +115,7 @@ RSpec.describe Geo::WikiSyncService, :geo do
allow(repository).to receive(:fetch_as_mirror) allow(repository).to receive(:fetch_as_mirror)
.with(url_to_repo, remote_name: 'geo', forced: true) .with(url_to_repo, remote_name: 'geo', forced: true)
.and_raise(Gitlab::Shell::Error.new(Gitlab::GitAccess::ERROR_MESSAGES[:no_repo])) .and_raise(Gitlab::Shell::Error.new(Gitlab::GitAccessWiki::ERROR_MESSAGES[:no_repo]))
subject.execute subject.execute
......
...@@ -57,11 +57,11 @@ module Gitlab ...@@ -57,11 +57,11 @@ module Gitlab
end end
def duration def duration
Time.current - @started (Time.current - @started).ceil
end end
def slot def slot
return 0 if duration <= 1 return 0 if duration < 2
Math.log(duration, 2).floor - 1 Math.log(duration, 2).floor - 1
end end
......
...@@ -65,6 +65,9 @@ module Gitlab ...@@ -65,6 +65,9 @@ module Gitlab
}, },
invitation_reminders: { invitation_reminders: {
tracking_category: 'Growth::Acquisition::Experiment::InvitationReminders' tracking_category: 'Growth::Acquisition::Experiment::InvitationReminders'
},
group_only_trials: {
tracking_category: 'Growth::Conversion::Experiment::GroupOnlyTrials'
} }
}.freeze }.freeze
......
...@@ -46,7 +46,7 @@ module Gitlab ...@@ -46,7 +46,7 @@ module Gitlab
links&.each do |link| links&.each do |link|
next unless link.is_a? Hash next unless link.is_a? Hash
Gitlab::UrlBlocker.validate!(link[:url], blocker_args) Gitlab::UrlBlocker.validate!(link[:url], **blocker_args)
rescue Gitlab::UrlBlocker::BlockedUrlError rescue Gitlab::UrlBlocker::BlockedUrlError
link[:url] = '' link[:url] = ''
end end
......
...@@ -88,10 +88,9 @@ module Gitlab ...@@ -88,10 +88,9 @@ module Gitlab
end end
def load_dev_server_manifest def load_dev_server_manifest
host = ::Rails.configuration.webpack.dev_server.host host = ::Rails.configuration.webpack.dev_server.manifest_host
port = ::Rails.configuration.webpack.dev_server.port port = ::Rails.configuration.webpack.dev_server.manifest_port
scheme = ::Rails.configuration.webpack.dev_server.https ? 'https' : 'http' uri = Addressable::URI.new(scheme: 'http', host: host, port: port, path: dev_server_path)
uri = Addressable::URI.new(scheme: scheme, host: host, port: port, path: dev_server_path)
# localhost could be blocked via Gitlab::HTTP # localhost could be blocked via Gitlab::HTTP
response = HTTParty.get(uri.to_s, verify: false) # rubocop:disable Gitlab/HTTParty response = HTTParty.get(uri.to_s, verify: false) # rubocop:disable Gitlab/HTTParty
......
...@@ -14,9 +14,9 @@ export const mockProjectId = '21'; ...@@ -14,9 +14,9 @@ export const mockProjectId = '21';
export const mockPostParams = { export const mockPostParams = {
ref: 'tag-1', ref: 'tag-1',
variables: [ variables_attributes: [
{ key: 'test_var', value: 'test_var_val', variable_type: 'env_var' }, { key: 'test_var', secret_value: 'test_var_val', variable_type: 'env_var' },
{ key: 'test_file', value: 'test_file_val', variable_type: 'file' }, { key: 'test_file', secret_value: 'test_file_val', variable_type: 'file' },
], ],
}; };
......
...@@ -5,6 +5,7 @@ import initSnippet from '~/snippet/snippet_bundle'; ...@@ -5,6 +5,7 @@ import initSnippet from '~/snippet/snippet_bundle';
jest.mock('~/snippet/snippet_bundle'); jest.mock('~/snippet/snippet_bundle');
jest.mock('~/snippets'); jest.mock('~/snippets');
jest.mock('~/gl_form');
describe('Snippet edit form initialization', () => { describe('Snippet edit form initialization', () => {
const setFF = flag => { const setFF = flag => {
......
...@@ -15,14 +15,36 @@ RSpec.describe Gitlab::Ci::Runner::Backoff do ...@@ -15,14 +15,36 @@ RSpec.describe Gitlab::Ci::Runner::Backoff do
end end
end end
end end
it 'returns an integer value' do
freeze_time do
described_class.new(5.seconds.ago).then do |backoff|
expect(backoff.duration).to be 5
end
end
end
it 'returns the smallest number greater than or equal to duration' do
freeze_time do
described_class.new(0.5.seconds.ago).then do |backoff|
expect(backoff.duration).to be 1
end
end
end
end end
describe '#slot' do describe '#slot' do
using RSpec::Parameterized::TableSyntax using RSpec::Parameterized::TableSyntax
where(:started, :slot) do where(:started, :slot) do
0 | 0
0.1 | 0
0.9 | 0
1 | 0 1 | 0
1.1 | 0
1.9 | 0
2 | 0 2 | 0
2.9 | 0
3 | 0 3 | 0
4 | 1 4 | 1
5 | 1 5 | 1
...@@ -30,6 +52,7 @@ RSpec.describe Gitlab::Ci::Runner::Backoff do ...@@ -30,6 +52,7 @@ RSpec.describe Gitlab::Ci::Runner::Backoff do
7 | 1 7 | 1
8 | 2 8 | 2
9 | 2 9 | 2
9.9 | 2
10 | 2 10 | 2
15 | 2 15 | 2
16 | 3 16 | 3
...@@ -59,15 +82,22 @@ RSpec.describe Gitlab::Ci::Runner::Backoff do ...@@ -59,15 +82,22 @@ RSpec.describe Gitlab::Ci::Runner::Backoff do
using RSpec::Parameterized::TableSyntax using RSpec::Parameterized::TableSyntax
where(:started, :backoff) do where(:started, :backoff) do
0 | 1
0.1 | 1
0.9 | 1
1 | 1 1 | 1
1.1 | 1
1.9 | 1
2 | 1 2 | 1
3 | 1 3 | 1
4 | 2 4 | 2
5 | 2 5 | 2
6 | 2 6 | 2
6.5 | 2
7 | 2 7 | 2
8 | 4 8 | 4
9 | 4 9 | 4
9.9 | 4
10 | 4 10 | 4
15 | 4 15 | 4
16 | 8 16 | 8
......
...@@ -4,12 +4,12 @@ require 'spec_helper' ...@@ -4,12 +4,12 @@ require 'spec_helper'
RSpec.describe Gitlab::Prometheus::QueryVariables do RSpec.describe Gitlab::Prometheus::QueryVariables do
describe '.call' do describe '.call' do
let_it_be_with_refind(:environment) { create(:environment) }
let(:project) { environment.project } let(:project) { environment.project }
let(:environment) { create(:environment) }
let(:slug) { environment.slug } let(:slug) { environment.slug }
let(:params) { {} } let(:params) { {} }
subject { described_class.call(environment, params) } subject { described_class.call(environment, **params) }
it { is_expected.to include(ci_environment_slug: slug) } it { is_expected.to include(ci_environment_slug: slug) }
it { is_expected.to include(ci_project_name: project.name) } it { is_expected.to include(ci_project_name: project.name) }
......
...@@ -41,7 +41,9 @@ RSpec.describe Gitlab::Webpack::Manifest do ...@@ -41,7 +41,9 @@ RSpec.describe Gitlab::Webpack::Manifest do
before do before do
# Test that config variables work while we're here # Test that config variables work while we're here
::Rails.configuration.webpack.dev_server.host = 'hostname' ::Rails.configuration.webpack.dev_server.host = 'hostname'
::Rails.configuration.webpack.dev_server.port = 2000 ::Rails.configuration.webpack.dev_server.port = 1999
::Rails.configuration.webpack.dev_server.manifest_host = 'hostname'
::Rails.configuration.webpack.dev_server.manifest_port = 2000
::Rails.configuration.webpack.manifest_filename = "my_manifest.json" ::Rails.configuration.webpack.manifest_filename = "my_manifest.json"
::Rails.configuration.webpack.public_path = "public_path" ::Rails.configuration.webpack.public_path = "public_path"
::Rails.configuration.webpack.output_dir = "manifest_output" ::Rails.configuration.webpack.output_dir = "manifest_output"
......
...@@ -34,6 +34,26 @@ RSpec.shared_examples 'reviewer_ids filter' do ...@@ -34,6 +34,26 @@ RSpec.shared_examples 'reviewer_ids filter' do
it 'contains reviewers who can read the merge_request' do it 'contains reviewers who can read the merge_request' do
expect(execute.reviewers).to contain_exactly(reviewer1, reviewer2) expect(execute.reviewers).to contain_exactly(reviewer1, reviewer2)
end end
context 'with multiple_merge_request_reviewers feature on' do
before do
stub_licensed_features(multiple_merge_request_reviewers: true)
end
it 'allows multiple reviewers' do
expect(execute.reviewers).to contain_exactly(reviewer1, reviewer2)
end
end
context 'with multiple_merge_request_reviewers feature off' do
before do
stub_licensed_features(multiple_merge_request_reviewers: false)
end
it 'only allows one reviewer' do
expect(execute.reviewers).to contain_exactly(reviewer1)
end
end
end end
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment