Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
7f305b576b
commit
028bb5dda7
|
@ -30,7 +30,7 @@ workflow:
|
|||
# merge requests used for this merge a branch release-tools/X into a stable
|
||||
# branch. For these merge requests we don't want to run any pipelines, as
|
||||
# they serve no purpose and will run anyway when the changes are merged.
|
||||
- if: '$CI_COMMIT_BRANCH =~ /^release-tools\/\d+\.\d+\.\d+-rc\d+$/ && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME =~ /^[\d-]+-stable(-ee)?$/ && $CI_PROJECT_PATH == "gitlab-org/gitlab"'
|
||||
- if: '$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME =~ /^release-tools\/\d+\.\d+\.\d+-rc\d+$/ && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME =~ /^[\d-]+-stable(-ee)?$/ && $CI_PROJECT_PATH == "gitlab-org/gitlab"'
|
||||
when: never
|
||||
# For merge requests, create a pipeline.
|
||||
- if: '$CI_MERGE_REQUEST_IID'
|
||||
|
|
|
@ -16,6 +16,7 @@ export const getSettings = (state, getters) => ({
|
|||
older_than: getters.getOlderThan,
|
||||
keep_n: getters.getKeepN,
|
||||
name_regex: state.settings.name_regex,
|
||||
name_regex_keep: state.settings.name_regex_keep,
|
||||
});
|
||||
|
||||
export const getIsEdited = state => !isEqual(state.original, state.settings);
|
||||
|
|
|
@ -1,8 +1,23 @@
|
|||
<script>
|
||||
import { uniqueId } from 'lodash';
|
||||
import { GlFormGroup, GlToggle, GlFormSelect, GlFormTextarea, GlSprintf } from '@gitlab/ui';
|
||||
import { s__, __ } from '~/locale';
|
||||
import { NAME_REGEX_LENGTH } from '../constants';
|
||||
import {
|
||||
NAME_REGEX_LENGTH,
|
||||
ENABLED_TEXT,
|
||||
DISABLED_TEXT,
|
||||
TEXT_AREA_INVALID_FEEDBACK,
|
||||
EXPIRATION_INTERVAL_LABEL,
|
||||
EXPIRATION_SCHEDULE_LABEL,
|
||||
KEEP_N_LABEL,
|
||||
NAME_REGEX_LABEL,
|
||||
NAME_REGEX_PLACEHOLDER,
|
||||
NAME_REGEX_DESCRIPTION,
|
||||
NAME_REGEX_KEEP_LABEL,
|
||||
NAME_REGEX_KEEP_PLACEHOLDER,
|
||||
NAME_REGEX_KEEP_DESCRIPTION,
|
||||
ENABLE_TOGGLE_LABEL,
|
||||
ENABLE_TOGGLE_DESCRIPTION,
|
||||
} from '../constants';
|
||||
import { mapComputedToEvent } from '../utils';
|
||||
|
||||
export default {
|
||||
|
@ -40,42 +55,73 @@ export default {
|
|||
default: 'right',
|
||||
},
|
||||
},
|
||||
nameRegexPlaceholder: '.*',
|
||||
i18n: {
|
||||
textAreaInvalidFeedback: TEXT_AREA_INVALID_FEEDBACK,
|
||||
enableToggleLabel: ENABLE_TOGGLE_LABEL,
|
||||
enableToggleDescription: ENABLE_TOGGLE_DESCRIPTION,
|
||||
},
|
||||
selectList: [
|
||||
{
|
||||
name: 'expiration-policy-interval',
|
||||
label: s__('ContainerRegistry|Expiration interval:'),
|
||||
label: EXPIRATION_INTERVAL_LABEL,
|
||||
model: 'older_than',
|
||||
optionKey: 'olderThan',
|
||||
},
|
||||
{
|
||||
name: 'expiration-policy-schedule',
|
||||
label: s__('ContainerRegistry|Expiration schedule:'),
|
||||
label: EXPIRATION_SCHEDULE_LABEL,
|
||||
model: 'cadence',
|
||||
optionKey: 'cadence',
|
||||
},
|
||||
{
|
||||
name: 'expiration-policy-latest',
|
||||
label: s__('ContainerRegistry|Number of tags to retain:'),
|
||||
label: KEEP_N_LABEL,
|
||||
model: 'keep_n',
|
||||
optionKey: 'keepN',
|
||||
},
|
||||
],
|
||||
textAreaList: [
|
||||
{
|
||||
name: 'expiration-policy-name-matching',
|
||||
label: NAME_REGEX_LABEL,
|
||||
model: 'name_regex',
|
||||
placeholder: NAME_REGEX_PLACEHOLDER,
|
||||
stateVariable: 'nameRegexState',
|
||||
description: NAME_REGEX_DESCRIPTION,
|
||||
},
|
||||
{
|
||||
name: 'expiration-policy-keep-name',
|
||||
label: NAME_REGEX_KEEP_LABEL,
|
||||
model: 'name_regex_keep',
|
||||
placeholder: NAME_REGEX_KEEP_PLACEHOLDER,
|
||||
stateVariable: 'nameKeepRegexState',
|
||||
description: NAME_REGEX_KEEP_DESCRIPTION,
|
||||
},
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
uniqueId: uniqueId(),
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapComputedToEvent(['enabled', 'cadence', 'older_than', 'keep_n', 'name_regex'], 'value'),
|
||||
...mapComputedToEvent(
|
||||
['enabled', 'cadence', 'older_than', 'keep_n', 'name_regex', 'name_regex_keep'],
|
||||
'value',
|
||||
),
|
||||
policyEnabledText() {
|
||||
return this.enabled ? __('enabled') : __('disabled');
|
||||
return this.enabled ? ENABLED_TEXT : DISABLED_TEXT;
|
||||
},
|
||||
nameRegexState() {
|
||||
return this.name_regex ? this.name_regex.length <= NAME_REGEX_LENGTH : null;
|
||||
textAreaState() {
|
||||
return {
|
||||
nameRegexState: this.validateNameRegex(this.name_regex),
|
||||
nameKeepRegexState: this.validateNameRegex(this.name_regex_keep),
|
||||
};
|
||||
},
|
||||
fieldsValidity() {
|
||||
return this.nameRegexState !== false;
|
||||
return (
|
||||
this.textAreaState.nameRegexState !== false &&
|
||||
this.textAreaState.nameKeepRegexState !== false
|
||||
);
|
||||
},
|
||||
isFormElementDisabled() {
|
||||
return !this.enabled || this.isLoading;
|
||||
|
@ -94,6 +140,9 @@ export default {
|
|||
},
|
||||
},
|
||||
methods: {
|
||||
validateNameRegex(value) {
|
||||
return value ? value.length <= NAME_REGEX_LENGTH : null;
|
||||
},
|
||||
idGenerator(id) {
|
||||
return `${id}_${this.uniqueId}`;
|
||||
},
|
||||
|
@ -111,7 +160,7 @@ export default {
|
|||
:label-cols="labelCols"
|
||||
:label-align="labelAlign"
|
||||
:label-for="idGenerator('expiration-policy-toggle')"
|
||||
:label="s__('ContainerRegistry|Expiration policy:')"
|
||||
:label="$options.i18n.enableToggleLabel"
|
||||
>
|
||||
<div class="d-flex align-items-start">
|
||||
<gl-toggle
|
||||
|
@ -120,9 +169,7 @@ export default {
|
|||
:disabled="isLoading"
|
||||
/>
|
||||
<span class="mb-2 ml-1 lh-2">
|
||||
<gl-sprintf
|
||||
:message="s__('ContainerRegistry|Docker tag expiration policy is %{toggleStatus}')"
|
||||
>
|
||||
<gl-sprintf :message="$options.i18n.enableToggleDescription">
|
||||
<template #toggleStatus>
|
||||
<strong>{{ policyEnabledText }}</strong>
|
||||
</template>
|
||||
|
@ -157,35 +204,34 @@ export default {
|
|||
</gl-form-group>
|
||||
|
||||
<gl-form-group
|
||||
:id="idGenerator('expiration-policy-name-matching-group')"
|
||||
v-for="textarea in $options.textAreaList"
|
||||
:id="idGenerator(`${textarea.name}-group`)"
|
||||
:key="textarea.name"
|
||||
:label-cols="labelCols"
|
||||
:label-align="labelAlign"
|
||||
:label-for="idGenerator('expiration-policy-name-matching')"
|
||||
:label="
|
||||
s__('ContainerRegistry|Docker tags with names matching this regex pattern will expire:')
|
||||
"
|
||||
:state="nameRegexState"
|
||||
:invalid-feedback="
|
||||
s__('ContainerRegistry|The value of this input should be less than 255 characters')
|
||||
"
|
||||
:label-for="idGenerator(textarea.name)"
|
||||
:state="textAreaState[textarea.stateVariable]"
|
||||
:invalid-feedback="$options.i18n.textAreaInvalidFeedback"
|
||||
>
|
||||
<template #label>
|
||||
<gl-sprintf :message="textarea.label">
|
||||
<template #italic="{content}">
|
||||
<i>{{ content }}</i>
|
||||
</template>
|
||||
</gl-sprintf>
|
||||
</template>
|
||||
<gl-form-textarea
|
||||
:id="idGenerator('expiration-policy-name-matching')"
|
||||
v-model="name_regex"
|
||||
:placeholder="$options.nameRegexPlaceholder"
|
||||
:state="nameRegexState"
|
||||
:id="idGenerator(textarea.name)"
|
||||
:value="value[textarea.model]"
|
||||
:placeholder="textarea.placeholder"
|
||||
:state="textAreaState[textarea.stateVariable]"
|
||||
:disabled="isFormElementDisabled"
|
||||
trim
|
||||
@input="updateModel($event, textarea.model)"
|
||||
/>
|
||||
<template #description>
|
||||
<span ref="regex-description">
|
||||
<gl-sprintf
|
||||
:message="
|
||||
s__(
|
||||
'ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}',
|
||||
)
|
||||
"
|
||||
>
|
||||
<gl-sprintf :message="textarea.description">
|
||||
<template #code="{content}">
|
||||
<code>{{ content }}</code>
|
||||
</template>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { s__ } from '~/locale';
|
||||
import { s__, __ } from '~/locale';
|
||||
|
||||
export const FETCH_SETTINGS_ERROR_MESSAGE = s__(
|
||||
'ContainerRegistry|Something went wrong while fetching the expiration policy.',
|
||||
|
@ -13,3 +13,33 @@ export const UPDATE_SETTINGS_SUCCESS_MESSAGE = s__(
|
|||
);
|
||||
|
||||
export const NAME_REGEX_LENGTH = 255;
|
||||
|
||||
export const ENABLED_TEXT = __('enabled');
|
||||
export const DISABLED_TEXT = __('disabled');
|
||||
|
||||
export const ENABLE_TOGGLE_LABEL = s__('ContainerRegistry|Expiration policy:');
|
||||
export const ENABLE_TOGGLE_DESCRIPTION = s__(
|
||||
'ContainerRegistry|Docker tag expiration policy is %{toggleStatus}',
|
||||
);
|
||||
|
||||
export const TEXT_AREA_INVALID_FEEDBACK = s__(
|
||||
'ContainerRegistry|The value of this input should be less than 255 characters',
|
||||
);
|
||||
|
||||
export const EXPIRATION_INTERVAL_LABEL = s__('ContainerRegistry|Expiration interval:');
|
||||
export const EXPIRATION_SCHEDULE_LABEL = s__('ContainerRegistry|Expiration schedule:');
|
||||
export const KEEP_N_LABEL = s__('ContainerRegistry|Number of tags to retain:');
|
||||
export const NAME_REGEX_LABEL = s__(
|
||||
'ContainerRegistry|Tags with names matching this regex pattern will %{italicStart}expire:%{italicEnd}',
|
||||
);
|
||||
export const NAME_REGEX_PLACEHOLDER = '.*';
|
||||
export const NAME_REGEX_DESCRIPTION = s__(
|
||||
'ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}',
|
||||
);
|
||||
export const NAME_REGEX_KEEP_LABEL = s__(
|
||||
'ContainerRegistry|Tags with names matching this regex pattern will %{italicStart}be preserved:%{italicEnd}',
|
||||
);
|
||||
export const NAME_REGEX_KEEP_PLACEHOLDER = '';
|
||||
export const NAME_REGEX_KEEP_DESCRIPTION = s__(
|
||||
'ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported',
|
||||
);
|
||||
|
|
|
@ -28,7 +28,8 @@ export default {
|
|||
},
|
||||
returnUrl: {
|
||||
type: String,
|
||||
required: true,
|
||||
required: false,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -46,7 +47,7 @@ export default {
|
|||
}}
|
||||
</p>
|
||||
<div class="d-flex justify-content-end">
|
||||
<gl-button ref="returnToSiteButton" :href="returnUrl">{{
|
||||
<gl-button v-if="returnUrl" ref="returnToSiteButton" :href="returnUrl">{{
|
||||
s__('StaticSiteEditor|Return to site')
|
||||
}}</gl-button>
|
||||
<gl-button ref="mergeRequestButton" class="ml-2" :href="mergeRequest.url" variant="success">
|
||||
|
@ -60,7 +61,7 @@ export default {
|
|||
<ul>
|
||||
<li>
|
||||
{{ s__('StaticSiteEditor|You created a new branch:') }}
|
||||
<span ref="branchLink">{{ branch.label }}</span>
|
||||
<gl-link ref="branchLink" :href="branch.url">{{ branch.label }}</gl-link>
|
||||
</li>
|
||||
<li>
|
||||
{{ s__('StaticSiteEditor|You created a merge request:') }}
|
||||
|
|
|
@ -48,6 +48,7 @@ export default {
|
|||
<!-- Success view -->
|
||||
<saved-changes-message
|
||||
v-if="savedContentMeta"
|
||||
class="w-75"
|
||||
:branch="savedContentMeta.branch"
|
||||
:commit="savedContentMeta.commit"
|
||||
:merge-request="savedContentMeta.mergeRequest"
|
||||
|
|
|
@ -56,8 +56,8 @@ const submitContentChanges = ({ username, projectId, sourcePath, content }) => {
|
|||
const meta = {};
|
||||
|
||||
return createBranch(projectId, branch)
|
||||
.then(() => {
|
||||
Object.assign(meta, { branch: { label: branch } });
|
||||
.then(({ data: { web_url: url } }) => {
|
||||
Object.assign(meta, { branch: { label: branch, url } });
|
||||
|
||||
return commitContent(projectId, mergeRequestTitle, branch, sourcePath, content);
|
||||
})
|
||||
|
@ -67,7 +67,7 @@ const submitContentChanges = ({ username, projectId, sourcePath, content }) => {
|
|||
return createMergeRequest(projectId, mergeRequestTitle, branch);
|
||||
})
|
||||
.then(({ data: { iid: label, web_url: url } }) => {
|
||||
Object.assign(meta, { mergeRequest: { label, url } });
|
||||
Object.assign(meta, { mergeRequest: { label: label.toString(), url } });
|
||||
|
||||
return meta;
|
||||
});
|
||||
|
|
|
@ -43,7 +43,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
|
|||
def usage_data
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
usage_data_json = JSON.pretty_generate(Gitlab::UsageData.data)
|
||||
usage_data_json = Gitlab::Json.pretty_generate(Gitlab::UsageData.data)
|
||||
|
||||
render html: Gitlab::Highlight.highlight('payload.json', usage_data_json, language: 'json')
|
||||
end
|
||||
|
|
|
@ -15,7 +15,7 @@ class Import::GoogleCodeController < Import::BaseController
|
|||
end
|
||||
|
||||
begin
|
||||
dump = JSON.parse(dump_file.read)
|
||||
dump = Gitlab::Json.parse(dump_file.read)
|
||||
rescue
|
||||
return redirect_back_or_default(options: { alert: _("The uploaded file is not a valid Google Takeout archive.") })
|
||||
end
|
||||
|
@ -42,7 +42,7 @@ class Import::GoogleCodeController < Import::BaseController
|
|||
user_map_json = "{}" if user_map_json.blank?
|
||||
|
||||
begin
|
||||
user_map = JSON.parse(user_map_json)
|
||||
user_map = Gitlab::Json.parse(user_map_json)
|
||||
rescue
|
||||
flash.now[:alert] = _("The entered user map is not a valid JSON user map.")
|
||||
|
||||
|
|
|
@ -158,6 +158,6 @@ module IconsHelper
|
|||
def known_sprites
|
||||
return if Rails.env.production?
|
||||
|
||||
@known_sprites ||= JSON.parse(File.read(Rails.root.join('node_modules/@gitlab/svgs/dist/icons.json')))['icons']
|
||||
@known_sprites ||= Gitlab::Json.parse(File.read(Rails.root.join('node_modules/@gitlab/svgs/dist/icons.json')))['icons']
|
||||
end
|
||||
end
|
||||
|
|
|
@ -32,7 +32,7 @@ module BlobViewer
|
|||
def json_data
|
||||
@json_data ||= begin
|
||||
prepare!
|
||||
JSON.parse(blob.data)
|
||||
Gitlab::Json.parse(blob.data)
|
||||
rescue
|
||||
{}
|
||||
end
|
||||
|
|
|
@ -5,7 +5,7 @@ require 'securerandom'
|
|||
module Clusters
|
||||
module Applications
|
||||
class Jupyter < ApplicationRecord
|
||||
VERSION = '0.9.0-beta.2'
|
||||
VERSION = '0.9.0'
|
||||
|
||||
self.table_name = 'clusters_applications_jupyter'
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ module DiffPositionableNote
|
|||
%i(original_position position change_position).each do |meth|
|
||||
define_method "#{meth}=" do |new_position|
|
||||
if new_position.is_a?(String)
|
||||
new_position = JSON.parse(new_position) rescue nil
|
||||
new_position = Gitlab::Json.parse(new_position) rescue nil
|
||||
end
|
||||
|
||||
if new_position.is_a?(Hash)
|
||||
|
|
|
@ -43,7 +43,7 @@ module RedisCacheable
|
|||
strong_memoize(:cached_attributes) do
|
||||
Gitlab::Redis::Cache.with do |redis|
|
||||
data = redis.get(cache_attribute_key)
|
||||
JSON.parse(data, symbolize_names: true) if data
|
||||
Gitlab::Json.parse(data, symbolize_names: true) if data
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -14,7 +14,7 @@ class MockMonitoringService < MonitoringService
|
|||
end
|
||||
|
||||
def metrics(environment)
|
||||
JSON.parse(File.read(Rails.root + 'spec/fixtures/metrics.json'))
|
||||
Gitlab::Json.parse(File.read(Rails.root + 'spec/fixtures/metrics.json'))
|
||||
end
|
||||
|
||||
def can_test?
|
||||
|
|
|
@ -76,7 +76,7 @@ class SentNotification < ApplicationRecord
|
|||
|
||||
def position=(new_position)
|
||||
if new_position.is_a?(String)
|
||||
new_position = JSON.parse(new_position) rescue nil
|
||||
new_position = Gitlab::Json.parse(new_position) rescue nil
|
||||
end
|
||||
|
||||
if new_position.is_a?(Hash)
|
||||
|
|
|
@ -113,7 +113,7 @@ module Metrics
|
|||
end
|
||||
|
||||
def parse_json(json)
|
||||
JSON.parse(json, symbolize_names: true)
|
||||
Gitlab::Json.parse(json, symbolize_names: true)
|
||||
rescue JSON::ParserError
|
||||
raise DashboardProcessingError.new('Grafana response contains invalid json')
|
||||
end
|
||||
|
|
|
@ -23,7 +23,7 @@ module Metrics
|
|||
|
||||
override :get_raw_dashboard
|
||||
def get_raw_dashboard
|
||||
JSON.parse(params[:embed_json])
|
||||
Gitlab::Json.parse(params[:embed_json])
|
||||
rescue JSON::ParserError => e
|
||||
invalid_embed_json!(e.message)
|
||||
end
|
||||
|
|
|
@ -69,7 +69,7 @@ module Projects
|
|||
# application/vnd.git-lfs+json
|
||||
# (https://github.com/git-lfs/git-lfs/blob/master/docs/api/batch.md#requests),
|
||||
# HTTParty does not know this is actually JSON.
|
||||
data = JSON.parse(response.body)
|
||||
data = Gitlab::Json.parse(response.body)
|
||||
|
||||
raise DownloadLinksError, "LFS Batch API did return any objects" unless data.is_a?(Hash) && data.key?('objects')
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ module Projects
|
|||
|
||||
file.open do |stream|
|
||||
Zlib::GzipReader.wrap(stream) do |gz_stream|
|
||||
data = JSON.parse(gz_stream.read)
|
||||
data = Gitlab::Json.parse(gz_stream.read)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ class IrkerWorker # rubocop:disable Scalability/IdempotentWorker
|
|||
|
||||
def sendtoirker(privmsg)
|
||||
to_send = { to: @channels, privmsg: privmsg }
|
||||
@socket.puts JSON.dump(to_send)
|
||||
@socket.puts Gitlab::Json.dump(to_send)
|
||||
end
|
||||
|
||||
def close_connection
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Add new keep regex to expiration policy settings ui
|
||||
merge_request: 29940
|
||||
author:
|
||||
type: changed
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Update managed jupyter chart to 0.9.0 (stable)
|
||||
merge_request: 30393
|
||||
author:
|
||||
type: changed
|
|
@ -503,7 +503,7 @@ then goes through a process of excluding tags from it until only the ones to be
|
|||
1. Evaluates the `name_regex`, excluding non-matching names from the list.
|
||||
1. Excludes any tags that do not have a manifest (not part of the options).
|
||||
1. Orders the remaining tags by `created_date`.
|
||||
1. Excludes from the list the N tags based on the `keep_n` value (Expiration latest).
|
||||
1. Excludes from the list the N tags based on the `keep_n` value (Number of tags to retain).
|
||||
1. Excludes from the list the tags older than the `older_than` value (Expiration interval).
|
||||
1. Finally, the remaining tags in the list are deleted from the Container Registry.
|
||||
|
||||
|
@ -518,7 +518,7 @@ The UI allows you to configure the following:
|
|||
- **Expiration policy:** enable or disable the expiration policy.
|
||||
- **Expiration interval:** how long tags are exempt from being deleted.
|
||||
- **Expiration schedule:** how often the cron job checking the tags should run.
|
||||
- **Expiration latest:** how many tags to _always_ keep for each image.
|
||||
- **Number of tags to retain:** how many tags to _always_ keep for each image.
|
||||
- **Docker tags with names matching this regex pattern will expire:** the regex used to determine what tags should be expired. To qualify all tags for expiration, use the default value of `.*`.
|
||||
|
||||
### Managing project expiration policy through the API
|
||||
|
|
|
@ -42,7 +42,7 @@ The importer will create any new namespaces (groups) if they don't exist or in
|
|||
the case the namespace is taken, the repository will be imported under the user's
|
||||
namespace that started the import process.
|
||||
|
||||
## Importing your Bitbucket repositories
|
||||
## Import your Bitbucket repositories
|
||||
|
||||
1. Sign in to GitLab and go to your dashboard.
|
||||
1. Click on **New project**.
|
||||
|
@ -60,3 +60,12 @@ namespace that started the import process.
|
|||
each project will be imported.
|
||||
|
||||
![Import projects](img/bitbucket_import_select_project_v12_3.png)
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
If you have more than one Bitbucket account, be sure to sign in to the correct account.
|
||||
If you've accidentally started the import process with the wrong account, follow these steps:
|
||||
|
||||
1. Revoke GitLab access to your Bitbucket account, essentially reversing the process in the following procedure: [Import your Bitbucket repositories](#import-your-bitbucket-repositories).
|
||||
|
||||
1. Sign out of the Bitbucket account. Follow the procedure linked from the previous step.
|
||||
|
|
|
@ -73,3 +73,7 @@ namespace that started the import process.
|
|||
imported.
|
||||
|
||||
![Import projects](img/bitbucket_server_import_select_project_v12_3.png)
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
See the [troubleshooting](bitbucket.md#troubleshooting) section for [Bitbucket](bitbucket.md).
|
||||
|
|
|
@ -65,10 +65,10 @@ also requires the GitLab Runner 11.5 or later. For earlier versions, use the
|
|||
|
||||
This example shows how to run Code Quality on your code by using GitLab CI/CD and Docker.
|
||||
|
||||
First, you need GitLab Runner with:
|
||||
First, you need GitLab Runner configured:
|
||||
|
||||
- The [docker-in-docker executor](../../../ci/docker/using_docker_build.md#use-docker-in-docker-workflow-with-docker-executor).
|
||||
- Enough disk space to handle generated Code Quality files. For example on the [GitLab project](https://gitlab.com/gitlab-org/gitlab) the files are approximately 7 GB.
|
||||
- For the [docker-in-docker workflow](../../../ci/docker/using_docker_build.md#use-docker-in-docker-workflow-with-docker-executor).
|
||||
- With enough disk space to handle generated Code Quality files. For example on the [GitLab project](https://gitlab.com/gitlab-org/gitlab) the files are approximately 7 GB.
|
||||
|
||||
Once you set up the Runner, include the CodeQuality template in your CI config:
|
||||
|
||||
|
|
|
@ -41,7 +41,10 @@ groups:
|
|||
- [Label](../project/labels.md)
|
||||
- My-reaction
|
||||
- Confidential
|
||||
- Epic ([Introduced](https://gitlab.com/gitlab-org/gitlab/issues/195704) in GitLab 12.9)
|
||||
- Epic ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/195704) in GitLab 12.9),
|
||||
including [child epic](../group/epics/index.md#multi-level-child-epics-ultimate)
|
||||
([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9029) in
|
||||
[GitLab Ultimate](https://about.gitlab.com/pricing/) 13.0)
|
||||
- Search for this text
|
||||
1. Select or type the operator to use for filtering the attribute. The following operators are
|
||||
available:
|
||||
|
|
|
@ -78,12 +78,18 @@ module Gitlab
|
|||
run_block_with_transaction
|
||||
rescue ActiveRecord::LockWaitTimeout
|
||||
if retry_with_lock_timeout?
|
||||
disable_idle_in_transaction_timeout
|
||||
wait_until_next_retry
|
||||
reset_db_settings
|
||||
|
||||
retry
|
||||
else
|
||||
reset_db_settings
|
||||
run_block_without_lock_timeout
|
||||
end
|
||||
|
||||
ensure
|
||||
reset_db_settings
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -153,6 +159,14 @@ module Gitlab
|
|||
def current_sleep_time_in_seconds
|
||||
timing_configuration[current_iteration - 1][1].to_f
|
||||
end
|
||||
|
||||
def disable_idle_in_transaction_timeout
|
||||
execute("SET LOCAL idle_in_transaction_session_timeout TO '0'")
|
||||
end
|
||||
|
||||
def reset_db_settings
|
||||
execute('RESET idle_in_transaction_session_timeout; RESET lock_timeout')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5606,9 +5606,6 @@ msgstr ""
|
|||
msgid "ContainerRegistry|Docker tag expiration policy is %{toggleStatus}"
|
||||
msgstr ""
|
||||
|
||||
msgid "ContainerRegistry|Docker tags with names matching this regex pattern will expire:"
|
||||
msgstr ""
|
||||
|
||||
msgid "ContainerRegistry|Edit Settings"
|
||||
msgstr ""
|
||||
|
||||
|
@ -5654,7 +5651,10 @@ msgstr ""
|
|||
msgid "ContainerRegistry|Quick Start"
|
||||
msgstr ""
|
||||
|
||||
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
|
||||
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported"
|
||||
msgstr ""
|
||||
|
||||
msgid "ContainerRegistry|Regular expressions such as %{codeStart}.*-test%{codeEnd} or %{codeStart}dev-.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}"
|
||||
msgstr ""
|
||||
|
||||
msgid "ContainerRegistry|Remove repository"
|
||||
|
@ -5707,6 +5707,12 @@ msgstr ""
|
|||
msgid "ContainerRegistry|Tags deleted successfully"
|
||||
msgstr ""
|
||||
|
||||
msgid "ContainerRegistry|Tags with names matching this regex pattern will %{italicStart}be preserved:%{italicEnd}"
|
||||
msgstr ""
|
||||
|
||||
msgid "ContainerRegistry|Tags with names matching this regex pattern will %{italicStart}expire:%{italicEnd}"
|
||||
msgstr ""
|
||||
|
||||
msgid "ContainerRegistry|The Container Registry tag expiration and retention policies for this project have not been enabled."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ RSpec.describe Oauth::TokenInfoController do
|
|||
get :show
|
||||
|
||||
expect(response).to have_gitlab_http_status(:unauthorized)
|
||||
expect(JSON.parse(response.body)).to include('error' => 'invalid_request')
|
||||
expect(Gitlab::Json.parse(response.body)).to include('error' => 'invalid_request')
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -23,7 +23,7 @@ RSpec.describe Oauth::TokenInfoController do
|
|||
get :show, params: { access_token: access_token.token }
|
||||
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
expect(JSON.parse(response.body)).to eq(
|
||||
expect(Gitlab::Json.parse(response.body)).to eq(
|
||||
'scope' => %w[api],
|
||||
'scopes' => %w[api],
|
||||
'created_at' => access_token.created_at.to_i,
|
||||
|
@ -40,7 +40,7 @@ RSpec.describe Oauth::TokenInfoController do
|
|||
get :show, params: { access_token: 'unknown_token' }
|
||||
|
||||
expect(response).to have_gitlab_http_status(:unauthorized)
|
||||
expect(JSON.parse(response.body)).to include('error' => 'invalid_request')
|
||||
expect(Gitlab::Json.parse(response.body)).to include('error' => 'invalid_request')
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -53,7 +53,7 @@ RSpec.describe Oauth::TokenInfoController do
|
|||
get :show, params: { access_token: access_token.token }
|
||||
|
||||
expect(response).to have_gitlab_http_status(:unauthorized)
|
||||
expect(JSON.parse(response.body)).to include('error' => 'invalid_request')
|
||||
expect(Gitlab::Json.parse(response.body)).to include('error' => 'invalid_request')
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -64,7 +64,7 @@ RSpec.describe Oauth::TokenInfoController do
|
|||
get :show, params: { access_token: access_token.token }
|
||||
|
||||
expect(response).to have_gitlab_http_status(:unauthorized)
|
||||
expect(JSON.parse(response.body)).to include('error' => 'invalid_request')
|
||||
expect(Gitlab::Json.parse(response.body)).to include('error' => 'invalid_request')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -334,7 +334,7 @@ describe Projects::ArtifactsController do
|
|||
def params
|
||||
@params ||= begin
|
||||
base64_params = send_data.sub(/\Aartifacts\-entry:/, '')
|
||||
JSON.parse(Base64.urlsafe_decode64(base64_params))
|
||||
Gitlab::Json.parse(Base64.urlsafe_decode64(base64_params))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -17,7 +17,7 @@ describe Projects::CycleAnalytics::EventsController do
|
|||
get_issue
|
||||
|
||||
expect(response).to be_successful
|
||||
expect(JSON.parse(response.body)['events']).to be_empty
|
||||
expect(Gitlab::Json.parse(response.body)['events']).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -38,7 +38,7 @@ describe Projects::CycleAnalytics::EventsController do
|
|||
it 'contains event detais' do
|
||||
get_issue
|
||||
|
||||
events = JSON.parse(response.body)['events']
|
||||
events = Gitlab::Json.parse(response.body)['events']
|
||||
|
||||
expect(events).not_to be_empty
|
||||
expect(events.first).to include('title', 'author', 'iid', 'total_time', 'created_at', 'url')
|
||||
|
@ -51,7 +51,7 @@ describe Projects::CycleAnalytics::EventsController do
|
|||
|
||||
expect(response).to be_successful
|
||||
|
||||
expect(JSON.parse(response.body)['events']).to be_empty
|
||||
expect(Gitlab::Json.parse(response.body)['events']).to be_empty
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -38,7 +38,7 @@ describe Projects::Environments::PrometheusApiController do
|
|||
context 'with success result' do
|
||||
let(:service_result) { { status: :success, body: prometheus_body } }
|
||||
let(:prometheus_body) { '{"status":"success"}' }
|
||||
let(:prometheus_json_body) { JSON.parse(prometheus_body) }
|
||||
let(:prometheus_json_body) { Gitlab::Json.parse(prometheus_body) }
|
||||
|
||||
it 'returns prometheus response' do
|
||||
get :proxy, params: environment_params
|
||||
|
|
|
@ -50,7 +50,7 @@ describe Projects::LogsController do
|
|||
container_name: container
|
||||
}
|
||||
end
|
||||
let(:service_result_json) { JSON.parse(service_result.to_json) }
|
||||
let(:service_result_json) { Gitlab::Json.parse(service_result.to_json) }
|
||||
|
||||
let_it_be(:cluster) { create(:cluster, :provided_by_gcp, environment_scope: '*', projects: [project]) }
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ describe 'When a user filters Sentry errors by status', :js, :use_clean_rails_me
|
|||
include_context 'sentry error tracking context feature'
|
||||
|
||||
let_it_be(:issues_response_body) { fixture_file('sentry/issues_sample_response.json') }
|
||||
let_it_be(:filtered_errors_by_status_response) { JSON.parse(issues_response_body).filter { |error| error['status'] == 'ignored' }.to_json }
|
||||
let_it_be(:filtered_errors_by_status_response) { Gitlab::Json.parse(issues_response_body).filter { |error| error['status'] == 'ignored' }.to_json }
|
||||
let(:issues_api_url) { "#{sentry_api_urls.issues_url}?limit=20&query=is:unresolved" }
|
||||
let(:issues_api_url_filter) { "#{sentry_api_urls.issues_url}?limit=20&query=is:ignored" }
|
||||
let(:auth_token) {{ 'Authorization' => 'Bearer access_token_123' }}
|
||||
|
|
|
@ -6,7 +6,7 @@ describe 'View error index page', :js, :use_clean_rails_memory_store_caching, :s
|
|||
include_context 'sentry error tracking context feature'
|
||||
|
||||
let_it_be(:issues_response_body) { fixture_file('sentry/issues_sample_response.json') }
|
||||
let_it_be(:issues_response) { JSON.parse(issues_response_body) }
|
||||
let_it_be(:issues_response) { Gitlab::Json.parse(issues_response_body) }
|
||||
let(:issues_api_url) { "#{sentry_api_urls.issues_url}?limit=20&query=is:unresolved" }
|
||||
|
||||
before do
|
||||
|
|
|
@ -52,7 +52,7 @@ describe 'Import/Export - project export integration test', :js do
|
|||
project_json_path = File.join(tmpdir, 'project.json')
|
||||
expect(File).to exist(project_json_path)
|
||||
|
||||
project_hash = JSON.parse(IO.read(project_json_path))
|
||||
project_hash = Gitlab::Json.parse(IO.read(project_json_path))
|
||||
|
||||
sensitive_words.each do |sensitive_word|
|
||||
found = find_sensitive_attributes(sensitive_word, project_hash)
|
||||
|
@ -78,7 +78,7 @@ describe 'Import/Export - project export integration test', :js do
|
|||
expect(File).to exist(project_json_path)
|
||||
|
||||
relations = []
|
||||
relations << JSON.parse(IO.read(project_json_path))
|
||||
relations << Gitlab::Json.parse(IO.read(project_json_path))
|
||||
Dir.glob(File.join(tmpdir, 'tree/project', '*.ndjson')) do |rb_filename|
|
||||
File.foreach(rb_filename) do |line|
|
||||
json = ActiveSupport::JSON.decode(line)
|
||||
|
|
|
@ -76,7 +76,7 @@ describe 'Projects > Settings > For a forked project', :js do
|
|||
context 'success path' do
|
||||
let(:projects_sample_response) do
|
||||
Gitlab::Utils.deep_indifferent_access(
|
||||
JSON.parse(fixture_file('sentry/list_projects_sample_response.json'))
|
||||
Gitlab::Json.parse(fixture_file('sentry/list_projects_sample_response.json'))
|
||||
)
|
||||
end
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ describe 'Project > Settings > CI/CD > Container registry tag expiration policy'
|
|||
select('7 days until tags are automatically removed', from: 'Expiration interval:')
|
||||
select('Every day', from: 'Expiration schedule:')
|
||||
select('50 tags per image name', from: 'Number of tags to retain:')
|
||||
fill_in('Docker tags with names matching this regex pattern will expire:', with: '*-production')
|
||||
fill_in('Tags with names matching this regex pattern will expire:', with: '*-production')
|
||||
end
|
||||
submit_button = find('.card-footer .btn.btn-success')
|
||||
expect(submit_button).not_to be_disabled
|
||||
|
|
|
@ -16,7 +16,7 @@ describe('IntegrationSettingsForm', () => {
|
|||
|
||||
beforeEach(() => {
|
||||
integrationSettingsForm = new IntegrationSettingsForm('.js-integration-settings-form');
|
||||
spyOn(integrationSettingsForm, 'init');
|
||||
jest.spyOn(integrationSettingsForm, 'init').mockImplementation(() => {});
|
||||
});
|
||||
|
||||
it('should initialize form element refs on class object', () => {
|
||||
|
@ -130,7 +130,7 @@ describe('IntegrationSettingsForm', () => {
|
|||
beforeEach(() => {
|
||||
mock = new MockAdaptor(axios);
|
||||
|
||||
spyOn(axios, 'put').and.callThrough();
|
||||
jest.spyOn(axios, 'put');
|
||||
|
||||
integrationSettingsForm = new IntegrationSettingsForm('.js-integration-settings-form');
|
||||
// eslint-disable-next-line no-jquery/no-serialize
|
||||
|
@ -141,18 +141,13 @@ describe('IntegrationSettingsForm', () => {
|
|||
mock.restore();
|
||||
});
|
||||
|
||||
it('should make an ajax request with provided `formData`', done => {
|
||||
integrationSettingsForm
|
||||
.testSettings(formData)
|
||||
.then(() => {
|
||||
expect(axios.put).toHaveBeenCalledWith(integrationSettingsForm.testEndPoint, formData);
|
||||
|
||||
done();
|
||||
})
|
||||
.catch(done.fail);
|
||||
it('should make an ajax request with provided `formData`', () => {
|
||||
return integrationSettingsForm.testSettings(formData).then(() => {
|
||||
expect(axios.put).toHaveBeenCalledWith(integrationSettingsForm.testEndPoint, formData);
|
||||
});
|
||||
});
|
||||
|
||||
it('should show error Flash with `Save anyway` action if ajax request responds with error in test', done => {
|
||||
it('should show error Flash with `Save anyway` action if ajax request responds with error in test', () => {
|
||||
const errorMessage = 'Test failed.';
|
||||
mock.onPut(integrationSettingsForm.testEndPoint).reply(200, {
|
||||
error: true,
|
||||
|
@ -161,32 +156,27 @@ describe('IntegrationSettingsForm', () => {
|
|||
test_failed: true,
|
||||
});
|
||||
|
||||
integrationSettingsForm
|
||||
.testSettings(formData)
|
||||
.then(() => {
|
||||
const $flashContainer = $('.flash-container');
|
||||
return integrationSettingsForm.testSettings(formData).then(() => {
|
||||
const $flashContainer = $('.flash-container');
|
||||
|
||||
expect(
|
||||
$flashContainer
|
||||
.find('.flash-text')
|
||||
.text()
|
||||
.trim(),
|
||||
).toEqual('Test failed. some error');
|
||||
expect(
|
||||
$flashContainer
|
||||
.find('.flash-text')
|
||||
.text()
|
||||
.trim(),
|
||||
).toEqual('Test failed. some error');
|
||||
|
||||
expect($flashContainer.find('.flash-action')).toBeDefined();
|
||||
expect(
|
||||
$flashContainer
|
||||
.find('.flash-action')
|
||||
.text()
|
||||
.trim(),
|
||||
).toEqual('Save anyway');
|
||||
|
||||
done();
|
||||
})
|
||||
.catch(done.fail);
|
||||
expect($flashContainer.find('.flash-action')).toBeDefined();
|
||||
expect(
|
||||
$flashContainer
|
||||
.find('.flash-action')
|
||||
.text()
|
||||
.trim(),
|
||||
).toEqual('Save anyway');
|
||||
});
|
||||
});
|
||||
|
||||
it('should not show error Flash with `Save anyway` action if ajax request responds with error in validation', done => {
|
||||
it('should not show error Flash with `Save anyway` action if ajax request responds with error in validation', () => {
|
||||
const errorMessage = 'Validations failed.';
|
||||
mock.onPut(integrationSettingsForm.testEndPoint).reply(200, {
|
||||
error: true,
|
||||
|
@ -195,50 +185,40 @@ describe('IntegrationSettingsForm', () => {
|
|||
test_failed: false,
|
||||
});
|
||||
|
||||
integrationSettingsForm
|
||||
.testSettings(formData)
|
||||
.then(() => {
|
||||
const $flashContainer = $('.flash-container');
|
||||
return integrationSettingsForm.testSettings(formData).then(() => {
|
||||
const $flashContainer = $('.flash-container');
|
||||
|
||||
expect(
|
||||
$flashContainer
|
||||
.find('.flash-text')
|
||||
.text()
|
||||
.trim(),
|
||||
).toEqual('Validations failed. some error');
|
||||
expect(
|
||||
$flashContainer
|
||||
.find('.flash-text')
|
||||
.text()
|
||||
.trim(),
|
||||
).toEqual('Validations failed. some error');
|
||||
|
||||
expect($flashContainer.find('.flash-action')).toBeDefined();
|
||||
expect(
|
||||
$flashContainer
|
||||
.find('.flash-action')
|
||||
.text()
|
||||
.trim(),
|
||||
).toEqual('');
|
||||
|
||||
done();
|
||||
})
|
||||
.catch(done.fail);
|
||||
expect($flashContainer.find('.flash-action')).toBeDefined();
|
||||
expect(
|
||||
$flashContainer
|
||||
.find('.flash-action')
|
||||
.text()
|
||||
.trim(),
|
||||
).toEqual('');
|
||||
});
|
||||
});
|
||||
|
||||
it('should submit form if ajax request responds without any error in test', done => {
|
||||
spyOn(integrationSettingsForm.$form, 'submit');
|
||||
it('should submit form if ajax request responds without any error in test', () => {
|
||||
jest.spyOn(integrationSettingsForm.$form, 'submit').mockImplementation(() => {});
|
||||
|
||||
mock.onPut(integrationSettingsForm.testEndPoint).reply(200, {
|
||||
error: false,
|
||||
});
|
||||
|
||||
integrationSettingsForm
|
||||
.testSettings(formData)
|
||||
.then(() => {
|
||||
expect(integrationSettingsForm.$form.submit).toHaveBeenCalled();
|
||||
|
||||
done();
|
||||
})
|
||||
.catch(done.fail);
|
||||
return integrationSettingsForm.testSettings(formData).then(() => {
|
||||
expect(integrationSettingsForm.$form.submit).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
it('should submit form when clicked on `Save anyway` action of error Flash', done => {
|
||||
spyOn(integrationSettingsForm.$form, 'submit');
|
||||
it('should submit form when clicked on `Save anyway` action of error Flash', () => {
|
||||
jest.spyOn(integrationSettingsForm.$form, 'submit').mockImplementation(() => {});
|
||||
|
||||
const errorMessage = 'Test failed.';
|
||||
mock.onPut(integrationSettingsForm.testEndPoint).reply(200, {
|
||||
|
@ -247,7 +227,7 @@ describe('IntegrationSettingsForm', () => {
|
|||
test_failed: true,
|
||||
});
|
||||
|
||||
integrationSettingsForm
|
||||
return integrationSettingsForm
|
||||
.testSettings(formData)
|
||||
.then(() => {
|
||||
const $flashAction = $('.flash-container .flash-action');
|
||||
|
@ -258,44 +238,31 @@ describe('IntegrationSettingsForm', () => {
|
|||
})
|
||||
.then(() => {
|
||||
expect(integrationSettingsForm.$form.submit).toHaveBeenCalled();
|
||||
|
||||
done();
|
||||
})
|
||||
.catch(done.fail);
|
||||
});
|
||||
});
|
||||
|
||||
it('should show error Flash if ajax request failed', done => {
|
||||
it('should show error Flash if ajax request failed', () => {
|
||||
const errorMessage = 'Something went wrong on our end.';
|
||||
|
||||
mock.onPut(integrationSettingsForm.testEndPoint).networkError();
|
||||
|
||||
integrationSettingsForm
|
||||
.testSettings(formData)
|
||||
.then(() => {
|
||||
expect(
|
||||
$('.flash-container .flash-text')
|
||||
.text()
|
||||
.trim(),
|
||||
).toEqual(errorMessage);
|
||||
|
||||
done();
|
||||
})
|
||||
.catch(done.fail);
|
||||
return integrationSettingsForm.testSettings(formData).then(() => {
|
||||
expect(
|
||||
$('.flash-container .flash-text')
|
||||
.text()
|
||||
.trim(),
|
||||
).toEqual(errorMessage);
|
||||
});
|
||||
});
|
||||
|
||||
it('should always call `toggleSubmitBtnState` with `false` once request is completed', done => {
|
||||
it('should always call `toggleSubmitBtnState` with `false` once request is completed', () => {
|
||||
mock.onPut(integrationSettingsForm.testEndPoint).networkError();
|
||||
|
||||
spyOn(integrationSettingsForm, 'toggleSubmitBtnState');
|
||||
jest.spyOn(integrationSettingsForm, 'toggleSubmitBtnState').mockImplementation(() => {});
|
||||
|
||||
integrationSettingsForm
|
||||
.testSettings(formData)
|
||||
.then(() => {
|
||||
expect(integrationSettingsForm.toggleSubmitBtnState).toHaveBeenCalledWith(false);
|
||||
|
||||
done();
|
||||
})
|
||||
.catch(done.fail);
|
||||
return integrationSettingsForm.testSettings(formData).then(() => {
|
||||
expect(integrationSettingsForm.toggleSubmitBtnState).toHaveBeenCalledWith(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -4,9 +4,12 @@ import { formOptions } from '../../shared/mock_data';
|
|||
|
||||
describe('Getters registry settings store', () => {
|
||||
const settings = {
|
||||
enabled: true,
|
||||
cadence: 'foo',
|
||||
keep_n: 'bar',
|
||||
older_than: 'baz',
|
||||
name_regex: 'name-foo',
|
||||
name_regex_keep: 'name-keep-bar',
|
||||
};
|
||||
|
||||
describe.each`
|
||||
|
@ -29,6 +32,17 @@ describe('Getters registry settings store', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('getSettings', () => {
|
||||
it('returns the content of settings', () => {
|
||||
const computedGetters = {
|
||||
getCadence: settings.cadence,
|
||||
getOlderThan: settings.older_than,
|
||||
getKeepN: settings.keep_n,
|
||||
};
|
||||
expect(getters.getSettings({ settings }, computedGetters)).toEqual(settings);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getIsEdited', () => {
|
||||
it('returns false when original is equal to settings', () => {
|
||||
const same = { foo: 'bar' };
|
||||
|
|
|
@ -117,11 +117,11 @@ exports[`Expiration Policy Form renders 1`] = `
|
|||
<gl-form-group-stub
|
||||
id="expiration-policy-name-matching-group"
|
||||
invalid-feedback="The value of this input should be less than 255 characters"
|
||||
label="Docker tags with names matching this regex pattern will expire:"
|
||||
label-align="right"
|
||||
label-cols="3"
|
||||
label-for="expiration-policy-name-matching"
|
||||
>
|
||||
|
||||
<gl-form-textarea-stub
|
||||
disabled="true"
|
||||
id="expiration-policy-name-matching"
|
||||
|
@ -130,5 +130,21 @@ exports[`Expiration Policy Form renders 1`] = `
|
|||
value=""
|
||||
/>
|
||||
</gl-form-group-stub>
|
||||
<gl-form-group-stub
|
||||
id="expiration-policy-keep-name-group"
|
||||
invalid-feedback="The value of this input should be less than 255 characters"
|
||||
label-align="right"
|
||||
label-cols="3"
|
||||
label-for="expiration-policy-keep-name"
|
||||
>
|
||||
|
||||
<gl-form-textarea-stub
|
||||
disabled="true"
|
||||
id="expiration-policy-keep-name"
|
||||
placeholder=""
|
||||
trim=""
|
||||
value=""
|
||||
/>
|
||||
</gl-form-group-stub>
|
||||
</div>
|
||||
`;
|
||||
|
|
|
@ -40,12 +40,13 @@ describe('Expiration Policy Form', () => {
|
|||
});
|
||||
|
||||
describe.each`
|
||||
elementName | modelName | value | disabledByToggle
|
||||
${'toggle'} | ${'enabled'} | ${true} | ${'not disabled'}
|
||||
${'interval'} | ${'older_than'} | ${'foo'} | ${'disabled'}
|
||||
${'schedule'} | ${'cadence'} | ${'foo'} | ${'disabled'}
|
||||
${'latest'} | ${'keep_n'} | ${'foo'} | ${'disabled'}
|
||||
${'name-matching'} | ${'name_regex'} | ${'foo'} | ${'disabled'}
|
||||
elementName | modelName | value | disabledByToggle
|
||||
${'toggle'} | ${'enabled'} | ${true} | ${'not disabled'}
|
||||
${'interval'} | ${'older_than'} | ${'foo'} | ${'disabled'}
|
||||
${'schedule'} | ${'cadence'} | ${'foo'} | ${'disabled'}
|
||||
${'latest'} | ${'keep_n'} | ${'foo'} | ${'disabled'}
|
||||
${'name-matching'} | ${'name_regex'} | ${'foo'} | ${'disabled'}
|
||||
${'keep-name'} | ${'name_regex_keep'} | ${'bar'} | ${'disabled'}
|
||||
`(
|
||||
`${FORM_ELEMENTS_ID_PREFIX}-$elementName form element`,
|
||||
({ elementName, modelName, value, disabledByToggle }) => {
|
||||
|
@ -118,21 +119,26 @@ describe('Expiration Policy Form', () => {
|
|||
${'schedule'}
|
||||
${'latest'}
|
||||
${'name-matching'}
|
||||
${'keep-name'}
|
||||
`(`${FORM_ELEMENTS_ID_PREFIX}-$elementName is disabled`, ({ elementName }) => {
|
||||
expect(findFormElements(elementName).attributes('disabled')).toBe('true');
|
||||
});
|
||||
});
|
||||
|
||||
describe('form validation', () => {
|
||||
describe.each`
|
||||
modelName | elementName | stateVariable
|
||||
${'name_regex'} | ${'name-matching'} | ${'nameRegexState'}
|
||||
${'name_regex_keep'} | ${'keep-name'} | ${'nameKeepRegexState'}
|
||||
`('regex textarea validation', ({ modelName, elementName, stateVariable }) => {
|
||||
describe(`when name regex is longer than ${NAME_REGEX_LENGTH}`, () => {
|
||||
const invalidString = new Array(NAME_REGEX_LENGTH + 2).join(',');
|
||||
|
||||
beforeEach(() => {
|
||||
mountComponent({ value: { name_regex: invalidString } });
|
||||
mountComponent({ value: { [modelName]: invalidString } });
|
||||
});
|
||||
|
||||
it('nameRegexState is false', () => {
|
||||
expect(wrapper.vm.nameRegexState).toBe(false);
|
||||
it(`${stateVariable} is false`, () => {
|
||||
expect(wrapper.vm.textAreaState[stateVariable]).toBe(false);
|
||||
});
|
||||
|
||||
it('emit the @invalidated event', () => {
|
||||
|
@ -141,17 +147,20 @@ describe('Expiration Policy Form', () => {
|
|||
});
|
||||
|
||||
it('if the user did not type validation is null', () => {
|
||||
mountComponent({ value: { name_regex: '' } });
|
||||
mountComponent({ value: { [modelName]: '' } });
|
||||
return wrapper.vm.$nextTick().then(() => {
|
||||
expect(wrapper.vm.nameRegexState).toBe(null);
|
||||
expect(wrapper.vm.textAreaState[stateVariable]).toBe(null);
|
||||
expect(wrapper.emitted('validated')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
it(`if the user typed and is less than ${NAME_REGEX_LENGTH} state is true`, () => {
|
||||
mountComponent({ value: { name_regex: 'foo' } });
|
||||
mountComponent({ value: { [modelName]: 'foo' } });
|
||||
return wrapper.vm.$nextTick().then(() => {
|
||||
expect(wrapper.vm.nameRegexState).toBe(true);
|
||||
const formGroup = findFormGroup(elementName);
|
||||
const formElement = findFormElements(elementName, formGroup);
|
||||
expect(formGroup.attributes('state')).toBeTruthy();
|
||||
expect(formElement.attributes('state')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -46,14 +46,11 @@ describe('~/static_site_editor/components/saved_changes_message.vue', () => {
|
|||
${'branch'} | ${findBranchLink} | ${props.branch}
|
||||
${'commit'} | ${findCommitLink} | ${props.commit}
|
||||
${'merge request'} | ${findMergeRequestLink} | ${props.mergeRequest}
|
||||
`('renders $desc link', ({ desc, findEl, prop }) => {
|
||||
`('renders $desc link', ({ findEl, prop }) => {
|
||||
const el = findEl();
|
||||
|
||||
expect(el.exists()).toBe(true);
|
||||
expect(el.text()).toBe(prop.label);
|
||||
|
||||
if (desc !== 'branch') {
|
||||
expect(el.attributes('href')).toBe(prop.url);
|
||||
}
|
||||
expect(el.attributes('href')).toBe(prop.url);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -34,6 +34,9 @@ export const savedContentMeta = {
|
|||
};
|
||||
|
||||
export const submitChangesError = 'Could not save changes';
|
||||
export const commitBranchResponse = {
|
||||
web_url: '/tree/root-master-patch-88195',
|
||||
};
|
||||
export const commitMultipleResponse = {
|
||||
short_id: 'ed899a2f4b5',
|
||||
web_url: '/commit/ed899a2f4b5',
|
||||
|
|
|
@ -13,6 +13,7 @@ import submitContentChanges from '~/static_site_editor/services/submit_content_c
|
|||
import {
|
||||
username,
|
||||
projectId,
|
||||
commitBranchResponse,
|
||||
commitMultipleResponse,
|
||||
createMergeRequestResponse,
|
||||
sourcePath,
|
||||
|
@ -26,7 +27,7 @@ describe('submitContentChanges', () => {
|
|||
const branch = 'branch-name';
|
||||
|
||||
beforeEach(() => {
|
||||
jest.spyOn(Api, 'createBranch').mockResolvedValue();
|
||||
jest.spyOn(Api, 'createBranch').mockResolvedValue({ data: commitBranchResponse });
|
||||
jest.spyOn(Api, 'commitMultiple').mockResolvedValue({ data: commitMultipleResponse });
|
||||
jest
|
||||
.spyOn(Api, 'createProjectMergeRequest')
|
||||
|
|
|
@ -32,7 +32,7 @@ describe TodosHelper do
|
|||
{ 'id' => projects.first.id, 'text' => projects.first.full_name }
|
||||
]
|
||||
|
||||
expect(JSON.parse(helper.todo_projects_options)).to match_array(expected_results)
|
||||
expect(Gitlab::Json.parse(helper.todo_projects_options)).to match_array(expected_results)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -123,7 +123,7 @@ describe 'lograge', type: :request do
|
|||
let(:logger) do
|
||||
Logger.new(log_output).tap { |logger| logger.formatter = ->(_, _, _, msg) { msg } }
|
||||
end
|
||||
let(:log_data) { JSON.parse(log_output.string) }
|
||||
let(:log_data) { Gitlab::Json.parse(log_output.string) }
|
||||
|
||||
before do
|
||||
Lograge.logger = logger
|
||||
|
|
|
@ -84,7 +84,7 @@ describe Gitlab::Database::WithLockRetries do
|
|||
subject.run do
|
||||
lock_attempts += 1
|
||||
|
||||
if lock_attempts == retry_count # we reached the last retry iteration, if we kill the thread, the last try (no lock_timeout) will succeed)
|
||||
if lock_attempts == retry_count # we reached the last retry iteration, if we kill the thread, the last try (no lock_timeout) will succeed
|
||||
lock_fiber.resume
|
||||
end
|
||||
|
||||
|
@ -106,9 +106,13 @@ describe Gitlab::Database::WithLockRetries do
|
|||
end
|
||||
|
||||
context 'after the retries, without setting lock_timeout' do
|
||||
let(:retry_count) { timing_configuration.size }
|
||||
let(:retry_count) { timing_configuration.size + 1 }
|
||||
|
||||
it_behaves_like 'retriable exclusive lock on `projects`'
|
||||
it_behaves_like 'retriable exclusive lock on `projects`' do
|
||||
before do
|
||||
expect(subject).to receive(:run_block_without_lock_timeout).and_call_original
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when statement timeout is reached' do
|
||||
|
@ -129,11 +133,22 @@ describe Gitlab::Database::WithLockRetries do
|
|||
end
|
||||
end
|
||||
|
||||
context 'restore local database variables' do
|
||||
it do
|
||||
expect { subject.run {} }.not_to change { ActiveRecord::Base.connection.execute("SHOW lock_timeout").to_a }
|
||||
end
|
||||
|
||||
it do
|
||||
expect { subject.run {} }.not_to change { ActiveRecord::Base.connection.execute("SHOW idle_in_transaction_session_timeout").to_a }
|
||||
end
|
||||
end
|
||||
|
||||
context 'casting durations correctly' do
|
||||
let(:timing_configuration) { [[0.015.seconds, 0.025.seconds], [0.015.seconds, 0.025.seconds]] } # 15ms, 25ms
|
||||
|
||||
it 'executes `SET LOCAL lock_timeout` using the configured timeout value in milliseconds' do
|
||||
expect(ActiveRecord::Base.connection).to receive(:execute).with("SAVEPOINT active_record_1").and_call_original
|
||||
expect(ActiveRecord::Base.connection).to receive(:execute).with('RESET idle_in_transaction_session_timeout; RESET lock_timeout').and_call_original
|
||||
expect(ActiveRecord::Base.connection).to receive(:execute).with("SET LOCAL lock_timeout TO '15ms'").and_call_original
|
||||
expect(ActiveRecord::Base.connection).to receive(:execute).with("RELEASE SAVEPOINT active_record_1").and_call_original
|
||||
|
||||
|
|
|
@ -2351,7 +2351,7 @@ describe Ci::Pipeline, :mailer do
|
|||
|
||||
def have_requested_pipeline_hook(status)
|
||||
have_requested(:post, stubbed_hostname(hook.url)).with do |req|
|
||||
json_body = JSON.parse(req.body)
|
||||
json_body = Gitlab::Json.parse(req.body)
|
||||
json_body['object_attributes']['status'] == status &&
|
||||
json_body['builds'].length == 2
|
||||
end
|
||||
|
|
|
@ -57,7 +57,7 @@ describe Clusters::Applications::Jupyter do
|
|||
it 'is initialized with 4 arguments' do
|
||||
expect(subject.name).to eq('jupyter')
|
||||
expect(subject.chart).to eq('jupyter/jupyterhub')
|
||||
expect(subject.version).to eq('0.9.0-beta.2')
|
||||
expect(subject.version).to eq('0.9.0')
|
||||
|
||||
expect(subject).to be_rbac
|
||||
expect(subject.repository).to eq('https://jupyterhub.github.io/helm-chart/')
|
||||
|
@ -76,7 +76,7 @@ describe Clusters::Applications::Jupyter do
|
|||
let(:jupyter) { create(:clusters_applications_jupyter, :errored, version: '0.0.1') }
|
||||
|
||||
it 'is initialized with the locked version' do
|
||||
expect(subject.version).to eq('0.9.0-beta.2')
|
||||
expect(subject.version).to eq('0.9.0')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -19,7 +19,7 @@ describe ContainerRepository do
|
|||
.with(headers: { 'Accept' => ContainerRegistry::Client::ACCEPTED_TYPES.join(', ') })
|
||||
.to_return(
|
||||
status: 200,
|
||||
body: JSON.dump(tags: ['test_tag']),
|
||||
body: Gitlab::Json.dump(tags: ['test_tag']),
|
||||
headers: { 'Content-Type' => 'application/json' })
|
||||
end
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ describe IrkerService do
|
|||
|
||||
conn = @irker_server.accept
|
||||
conn.each_line do |line|
|
||||
msg = JSON.parse(line.chomp("\n"))
|
||||
msg = Gitlab::Json.parse(line.chomp("\n"))
|
||||
expect(msg.keys).to match_array(%w(to privmsg))
|
||||
expect(msg['to']).to match_array(["irc://chat.freenode.net/#commits",
|
||||
"irc://test.net/#test"])
|
||||
|
|
|
@ -529,11 +529,11 @@ describe Snippet do
|
|||
let(:snippet) { build(:snippet) }
|
||||
|
||||
it 'excludes secret_token from generated json' do
|
||||
expect(JSON.parse(to_json).keys).not_to include("secret_token")
|
||||
expect(Gitlab::Json.parse(to_json).keys).not_to include("secret_token")
|
||||
end
|
||||
|
||||
it 'does not override existing exclude option value' do
|
||||
expect(JSON.parse(to_json(except: [:id])).keys).not_to include("secret_token", "id")
|
||||
expect(Gitlab::Json.parse(to_json(except: [:id])).keys).not_to include("secret_token", "id")
|
||||
end
|
||||
|
||||
def to_json(params = {})
|
||||
|
|
|
@ -132,6 +132,6 @@ describe 'get board lists' do
|
|||
end
|
||||
|
||||
def grab_list_data(response_body)
|
||||
JSON.parse(response_body)['data'][board_parent_type]['boards']['edges'][0]['node']['lists']['edges']
|
||||
Gitlab::Json.parse(response_body)['data'][board_parent_type]['boards']['edges'][0]['node']['lists']['edges']
|
||||
end
|
||||
end
|
||||
|
|
|
@ -171,7 +171,7 @@ describe 'getting an issue list for a project' do
|
|||
|
||||
cursored_query = query("sort: DUE_DATE_ASC, after: \"#{end_cursor}\"")
|
||||
post_graphql(cursored_query, current_user: current_user)
|
||||
response_data = JSON.parse(response.body)['data']['project']['issues']['edges']
|
||||
response_data = Gitlab::Json.parse(response.body)['data']['project']['issues']['edges']
|
||||
|
||||
expect(grab_iids(response_data)).to eq([due_issue1.iid, due_issue4.iid, due_issue2.iid])
|
||||
end
|
||||
|
@ -193,7 +193,7 @@ describe 'getting an issue list for a project' do
|
|||
|
||||
cursored_query = query("sort: DUE_DATE_DESC, after: \"#{end_cursor}\"")
|
||||
post_graphql(cursored_query, current_user: current_user)
|
||||
response_data = JSON.parse(response.body)['data']['project']['issues']['edges']
|
||||
response_data = Gitlab::Json.parse(response.body)['data']['project']['issues']['edges']
|
||||
|
||||
expect(grab_iids(response_data)).to eq([due_issue3.iid, due_issue4.iid, due_issue2.iid])
|
||||
end
|
||||
|
@ -239,7 +239,7 @@ describe 'getting an issue list for a project' do
|
|||
|
||||
cursored_query = query("sort: RELATIVE_POSITION_ASC, after: \"#{end_cursor}\"")
|
||||
post_graphql(cursored_query, current_user: current_user)
|
||||
response_data = JSON.parse(response.body)['data']['project']['issues']['edges']
|
||||
response_data = Gitlab::Json.parse(response.body)['data']['project']['issues']['edges']
|
||||
|
||||
expect(grab_iids(response_data)).to eq([relative_issue1.iid, relative_issue4.iid, relative_issue2.iid])
|
||||
end
|
||||
|
@ -288,7 +288,7 @@ describe 'getting an issue list for a project' do
|
|||
|
||||
cursored_query = query("sort: PRIORITY_ASC, after: \"#{end_cursor}\"")
|
||||
post_graphql(cursored_query, current_user: current_user)
|
||||
response_data = JSON.parse(response.body)['data']['project']['issues']['edges']
|
||||
response_data = Gitlab::Json.parse(response.body)['data']['project']['issues']['edges']
|
||||
|
||||
expect(grab_iids(response_data)).to eq([priority_issue2.iid, priority_issue4.iid])
|
||||
end
|
||||
|
@ -310,7 +310,7 @@ describe 'getting an issue list for a project' do
|
|||
|
||||
cursored_query = query("sort: PRIORITY_DESC, after: \"#{end_cursor}\"")
|
||||
post_graphql(cursored_query, current_user: current_user)
|
||||
response_data = JSON.parse(response.body)['data']['project']['issues']['edges']
|
||||
response_data = Gitlab::Json.parse(response.body)['data']['project']['issues']['edges']
|
||||
|
||||
expect(grab_iids(response_data)).to eq([priority_issue2.iid, priority_issue4.iid])
|
||||
end
|
||||
|
|
|
@ -24,7 +24,7 @@ shared_examples 'languages and percentages JSON response' do
|
|||
get api("/projects/#{project.id}/languages", user)
|
||||
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
expect(JSON.parse(response.body)).to eq(expected_languages)
|
||||
expect(Gitlab::Json.parse(response.body)).to eq(expected_languages)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -672,7 +672,7 @@ describe API::Projects do
|
|||
match[1]
|
||||
end
|
||||
|
||||
ids += JSON.parse(response.body).map { |p| p['id'] }
|
||||
ids += Gitlab::Json.parse(response.body).map { |p| p['id'] }
|
||||
end
|
||||
|
||||
expect(ids).to contain_exactly(*projects.map(&:id))
|
||||
|
|
|
@ -217,7 +217,7 @@ describe Metrics::Dashboard::DatasourceNameParser do
|
|||
include GrafanaApiHelpers
|
||||
|
||||
let(:grafana_url) { valid_grafana_dashboard_link('https://gitlab.grafana.net') }
|
||||
let(:grafana_dashboard) { JSON.parse(fixture_file('grafana/dashboard_response.json'), symbolize_names: true) }
|
||||
let(:grafana_dashboard) { Gitlab::Json.parse(fixture_file('grafana/dashboard_response.json'), symbolize_names: true) }
|
||||
|
||||
subject { described_class.new(grafana_url, grafana_dashboard).parse }
|
||||
|
||||
|
|
|
@ -86,7 +86,7 @@ module StubGitlabCalls
|
|||
def stub_container_registry_tag_manifest_content
|
||||
fixture_path = 'spec/fixtures/container_registry/tag_manifest.json'
|
||||
|
||||
JSON.parse(File.read(Rails.root + fixture_path))
|
||||
Gitlab::Json.parse(File.read(Rails.root + fixture_path))
|
||||
end
|
||||
|
||||
def stub_container_registry_blob_content
|
||||
|
@ -113,12 +113,12 @@ module StubGitlabCalls
|
|||
|
||||
def stub_project_8
|
||||
data = File.read(Rails.root.join('spec/support/gitlab_stubs/project_8.json'))
|
||||
allow_any_instance_of(Network).to receive(:project).and_return(JSON.parse(data))
|
||||
allow_any_instance_of(Network).to receive(:project).and_return(Gitlab::Json.parse(data))
|
||||
end
|
||||
|
||||
def stub_project_8_hooks
|
||||
data = File.read(Rails.root.join('spec/support/gitlab_stubs/project_8_hooks.json'))
|
||||
allow_any_instance_of(Network).to receive(:project_hooks).and_return(JSON.parse(data))
|
||||
allow_any_instance_of(Network).to receive(:project_hooks).and_return(Gitlab::Json.parse(data))
|
||||
end
|
||||
|
||||
def stub_projects
|
||||
|
@ -143,7 +143,7 @@ module StubGitlabCalls
|
|||
|
||||
def project_hash_array
|
||||
f = File.read(Rails.root.join('spec/support/gitlab_stubs/projects.json'))
|
||||
JSON.parse f
|
||||
Gitlab::Json.parse(f)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ module WorkhorseHelpers
|
|||
header = split_header.join(':')
|
||||
[
|
||||
type,
|
||||
JSON.parse(Base64.urlsafe_decode64(header))
|
||||
Gitlab::Json.parse(Base64.urlsafe_decode64(header))
|
||||
]
|
||||
end
|
||||
end
|
||||
|
|
|
@ -44,8 +44,8 @@ module ConfigurationHelper
|
|||
import_export_config = config_hash(config)
|
||||
excluded_attributes = import_export_config[:excluded_attributes][relation_name.to_sym]
|
||||
included_attributes = import_export_config[:included_attributes][relation_name.to_sym]
|
||||
attributes = attributes - JSON.parse(excluded_attributes.to_json) if excluded_attributes
|
||||
attributes = attributes & JSON.parse(included_attributes.to_json) if included_attributes
|
||||
attributes = attributes - Gitlab::Json.parse(excluded_attributes.to_json) if excluded_attributes
|
||||
attributes = attributes & Gitlab::Json.parse(included_attributes.to_json) if included_attributes
|
||||
|
||||
attributes
|
||||
end
|
||||
|
|
|
@ -11,7 +11,7 @@ end
|
|||
|
||||
RSpec::Matchers.define :disallow_request_in_json do
|
||||
match do |response|
|
||||
json_response = JSON.parse(response.body)
|
||||
json_response = Gitlab::Json.parse(response.body)
|
||||
response.body.include?('You cannot perform write operations') && json_response.key?('message')
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,9 +6,9 @@ shared_context 'sentry error tracking context feature' do
|
|||
let_it_be(:project) { create(:project) }
|
||||
let_it_be(:project_error_tracking_settings) { create(:project_error_tracking_setting, project: project) }
|
||||
let_it_be(:issue_response_body) { fixture_file('sentry/issue_sample_response.json') }
|
||||
let_it_be(:issue_response) { JSON.parse(issue_response_body) }
|
||||
let_it_be(:issue_response) { Gitlab::Json.parse(issue_response_body) }
|
||||
let_it_be(:event_response_body) { fixture_file('sentry/issue_latest_event_sample_response.json') }
|
||||
let_it_be(:event_response) { JSON.parse(event_response_body) }
|
||||
let_it_be(:event_response) { Gitlab::Json.parse(event_response_body) }
|
||||
let(:sentry_api_urls) { Sentry::ApiUrls.new(project_error_tracking_settings.api_url) }
|
||||
let(:issue_id) { issue_response['id'] }
|
||||
let(:issue_seen) { 1.year.ago.utc }
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.shared_context 'JSON response' do
|
||||
let(:json_response) { JSON.parse(response.body) }
|
||||
let(:json_response) { Gitlab::Json.parse(response.body) }
|
||||
end
|
||||
|
|
|
@ -82,7 +82,7 @@ RSpec.shared_examples 'sorted paginated query' do
|
|||
|
||||
cursored_query = pagination_query("sort: #{sort_param}, after: \"#{end_cursor}\"", page_info)
|
||||
post_graphql(cursored_query, current_user: current_user)
|
||||
response_data = graphql_dig_at(JSON.parse(response.body), :data, *data_path, :edges)
|
||||
response_data = graphql_dig_at(Gitlab::Json.parse(response.body), :data, *data_path, :edges)
|
||||
|
||||
expect(pagination_results_data(response_data)).to eq expected_results.drop(first_param)
|
||||
end
|
||||
|
|
|
@ -80,7 +80,7 @@ RSpec.shared_examples 'group and project boards query' do
|
|||
cursored_query = query("after: \"#{end_cursor}\"")
|
||||
post_graphql(cursored_query, current_user: current_user)
|
||||
|
||||
response_data = JSON.parse(response.body)['data'][board_parent_type]['boards']['edges']
|
||||
response_data = Gitlab::Json.parse(response.body)['data'][board_parent_type]['boards']['edges']
|
||||
|
||||
expect(grab_names(response_data)).to eq expected_boards.drop(2).first(2).map(&:name)
|
||||
end
|
||||
|
|
|
@ -23,7 +23,7 @@ RSpec.shared_examples 'valid dashboard service response for schema' do
|
|||
end
|
||||
|
||||
RSpec.shared_examples 'valid dashboard service response' do
|
||||
let(:dashboard_schema) { JSON.parse(fixture_file('lib/gitlab/metrics/dashboard/schemas/dashboard.json')) }
|
||||
let(:dashboard_schema) { Gitlab::Json.parse(fixture_file('lib/gitlab/metrics/dashboard/schemas/dashboard.json')) }
|
||||
|
||||
it_behaves_like 'valid dashboard service response for schema'
|
||||
end
|
||||
|
@ -38,7 +38,7 @@ RSpec.shared_examples 'caches the unprocessed dashboard for subsequent calls' do
|
|||
end
|
||||
|
||||
RSpec.shared_examples 'valid embedded dashboard service response' do
|
||||
let(:dashboard_schema) { JSON.parse(fixture_file('lib/gitlab/metrics/dashboard/schemas/embedded_dashboard.json')) }
|
||||
let(:dashboard_schema) { Gitlab::Json.parse(fixture_file('lib/gitlab/metrics/dashboard/schemas/embedded_dashboard.json')) }
|
||||
|
||||
it_behaves_like 'valid dashboard service response for schema'
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue