Commit 3269a206 authored by GitLab Bot's avatar GitLab Bot

Add latest changes from gitlab-org/gitlab@master

parent c02f5328
......@@ -40,13 +40,13 @@ export default {
<div :class="cssContainerClass">
<stop-environment-modal :environment="environmentInStopModal" />
<div v-if="!isLoading" class="top-area">
<h4 class="js-folder-name environments-folder-name">
{{ s__('Environments|Environments') }} /
<b>{{ folderName }}</b>
</h4>
<h4 class="js-folder-name environments-folder-name">
{{ s__('Environments|Environments') }} /
<b>{{ folderName }}</b>
</h4>
<tabs :tabs="tabs" scope="environments" @onChangeTab="onChangeTab" />
<div class="top-area">
<tabs v-if="!isLoading" :tabs="tabs" scope="environments" @onChangeTab="onChangeTab" />
</div>
<container
......
......@@ -7,7 +7,6 @@
.environments-folder-name {
font-weight: $gl-font-weight-normal;
padding-top: 20px;
}
.environments-container {
......
......@@ -4,9 +4,6 @@ module Ci
class BuildTraceSection < ApplicationRecord
extend Gitlab::Ci::Model
# Only remove > 2019-11-22 and > 12.5
self.ignored_columns += %i[id]
belongs_to :build, class_name: 'Ci::Build'
belongs_to :project
belongs_to :section_name, class_name: 'Ci::BuildTraceSectionName'
......
......@@ -420,15 +420,6 @@ class MergeRequest < ApplicationRecord
limit ? shas.take(limit) : shas
end
# Returns true if there are commits that match at least one commit SHA.
def includes_any_commits?(shas)
if persisted?
merge_request_diff.commits_by_shas(shas).exists?
else
(commit_shas & shas).present?
end
end
def supports_suggestion?
true
end
......
......@@ -10,6 +10,7 @@ class MergeRequestDiff < ApplicationRecord
# Don't display more than 100 commits at once
COMMITS_SAFE_SIZE = 100
BATCH_SIZE = 1000
# Applies to closed or merged MRs when determining whether to migrate their
# diffs to external storage
......@@ -254,10 +255,14 @@ class MergeRequestDiff < ApplicationRecord
merge_request_diff_commits.limit(limit).pluck(:sha)
end
def commits_by_shas(shas)
return MergeRequestDiffCommit.none unless shas.present?
def includes_any_commits?(shas)
return false if shas.blank?
merge_request_diff_commits.where(sha: shas)
# when the number of shas is huge (1000+) we don't want
# to pass them all as an SQL param, let's pass them in batches
shas.each_slice(BATCH_SIZE).any? do |batched_shas|
merge_request_diff_commits.where(sha: batched_shas).exists?
end
end
def diff_refs=(new_diff_refs)
......
......@@ -62,20 +62,6 @@ class Project < ApplicationRecord
cache_markdown_field :description, pipeline: :description
delegate :feature_available?, :builds_enabled?, :wiki_enabled?, :merge_requests_enabled?,
:issues_enabled?, :pages_enabled?, :public_pages?, :private_pages?,
:merge_requests_access_level, :issues_access_level, :wiki_access_level,
:snippets_access_level, :builds_access_level, :repository_access_level,
to: :project_feature, allow_nil: true
delegate :base_dir, :disk_path, to: :storage
delegate :scheduled?, :started?, :in_progress?,
:failed?, :finished?,
prefix: :import, to: :import_state, allow_nil: true
delegate :no_import?, to: :import_state, allow_nil: true
# TODO: remove once GitLab 12.5 is released
# https://gitlab.com/gitlab-org/gitlab/issues/34638
self.ignored_columns += %i[merge_requests_require_code_owner_approval]
......@@ -323,6 +309,15 @@ class Project < ApplicationRecord
accepts_nested_attributes_for :metrics_setting, update_only: true, allow_destroy: true
accepts_nested_attributes_for :grafana_integration, update_only: true, allow_destroy: true
delegate :feature_available?, :builds_enabled?, :wiki_enabled?, :merge_requests_enabled?,
:issues_enabled?, :pages_enabled?, :public_pages?, :private_pages?,
:merge_requests_access_level, :issues_access_level, :wiki_access_level,
:snippets_access_level, :builds_access_level, :repository_access_level,
to: :project_feature, allow_nil: true
delegate :scheduled?, :started?, :in_progress?, :failed?, :finished?,
prefix: :import, to: :import_state, allow_nil: true
delegate :base_dir, :disk_path, to: :storage
delegate :no_import?, to: :import_state, allow_nil: true
delegate :name, to: :owner, allow_nil: true, prefix: true
delegate :members, to: :team, prefix: true
delegate :add_user, :add_users, to: :team
......
......@@ -106,7 +106,7 @@ module MergeRequests
filter_merge_requests(merge_requests).each do |merge_request|
if branch_and_project_match?(merge_request) || @push.force_push?
merge_request.reload_diff(current_user)
elsif merge_request.includes_any_commits?(push_commit_ids)
elsif merge_request.merge_request_diff.includes_any_commits?(push_commit_ids)
merge_request.reload_diff(current_user)
end
......
......@@ -13,7 +13,7 @@ module Metrics
def dashboard_path
params[:dashboard_path].presence ||
::Metrics::Dashboard::SystemDashboardService::SYSTEM_DASHBOARD_PATH
::Metrics::Dashboard::SystemDashboardService::DASHBOARD_PATH
end
def group
......
......@@ -40,7 +40,7 @@ module Metrics
# All custom metrics are displayed on the system dashboard.
# Nil is acceptable as we'll default to the system dashboard.
def valid_dashboard?(dashboard)
dashboard.nil? || ::Metrics::Dashboard::SystemDashboardService.system_dashboard?(dashboard)
dashboard.nil? || ::Metrics::Dashboard::SystemDashboardService.matching_dashboard?(dashboard)
end
end
......
# frozen_string_literal: true
module Metrics
module Dashboard
class PredefinedDashboardService < ::Metrics::Dashboard::BaseService
# These constants should be overridden in the inheriting class. For Ex:
# DASHBOARD_PATH = 'config/prometheus/common_metrics.yml'
# DASHBOARD_NAME = 'Default'
DASHBOARD_PATH = nil
DASHBOARD_NAME = nil
SEQUENCE = [
STAGES::EndpointInserter,
STAGES::Sorter
].freeze
class << self
def matching_dashboard?(filepath)
filepath == self::DASHBOARD_PATH
end
end
private
def cache_key
"metrics_dashboard_#{dashboard_path}"
end
def dashboard_path
self.class::DASHBOARD_PATH
end
# Returns the base metrics shipped with every GitLab service.
def get_raw_dashboard
yml = File.read(Rails.root.join(dashboard_path))
YAML.safe_load(yml)
end
def sequence
self.class::SEQUENCE
end
end
end
end
# frozen_string_literal: true
# Fetches the system metrics dashboard and formats the output.
# Use Gitlab::Metrics::Dashboard::Finder to retrive dashboards.
# Use Gitlab::Metrics::Dashboard::Finder to retrieve dashboards.
module Metrics
module Dashboard
class SystemDashboardService < ::Metrics::Dashboard::BaseService
SYSTEM_DASHBOARD_PATH = 'config/prometheus/common_metrics.yml'
SYSTEM_DASHBOARD_NAME = 'Default'
class SystemDashboardService < ::Metrics::Dashboard::PredefinedDashboardService
DASHBOARD_PATH = 'config/prometheus/common_metrics.yml'
DASHBOARD_NAME = 'Default'
SEQUENCE = [
STAGES::CommonMetricsInserter,
......@@ -18,37 +18,12 @@ module Metrics
class << self
def all_dashboard_paths(_project)
[{
path: SYSTEM_DASHBOARD_PATH,
display_name: SYSTEM_DASHBOARD_NAME,
path: DASHBOARD_PATH,
display_name: DASHBOARD_NAME,
default: true,
system_dashboard: true
}]
end
def system_dashboard?(filepath)
filepath == SYSTEM_DASHBOARD_PATH
end
end
private
def cache_key
"metrics_dashboard_#{dashboard_path}"
end
def dashboard_path
SYSTEM_DASHBOARD_PATH
end
# Returns the base metrics shipped with every GitLab service.
def get_raw_dashboard
yml = File.read(Rails.root.join(dashboard_path))
YAML.safe_load(yml)
end
def sequence
SEQUENCE
end
end
end
......
- page_title _("Environments")
- add_to_breadcrumbs _("Environments"), project_environments_path(@project)
- breadcrumb_title _("Folder/%{name}") % { name: @folder }
- page_title _("Environments in %{name}") % { name: @folder }
#environments-folder-list-view{ data: { environments_data: environments_folder_list_view_data } }
---
title: Fix broken UI on Environment folder
merge_request: 17427
author: Takuya Noguchi
type: fixed
---
title: Expose moved_to_id in issues API
merge_request: 20083
author: Lee Tickett
type: added
---
title: Remove build badge path from route
merge_request: 20188
author: Lee Tickett
type: other
......@@ -494,8 +494,6 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
collection do
scope '*ref', constraints: { ref: Gitlab::PathRegex.git_reference_regex } do
constraints format: /svg/ do
# Keep around until 10.0, see gitlab-org/gitlab-ce#35307
get :build, to: "badges#pipeline"
get :pipeline
get :coverage
end
......
# FIXME: git.info_for_file raises the following error
# /usr/local/bundle/gems/git-1.4.0/lib/git/lib.rb:956:in `command': (Danger::DSLError)
# [!] Invalid `Dangerfile` file:
# [!] Invalid `Dangerfile` file: git '--git-dir=/builds/gitlab-org/gitlab-foss/.git' '--work-tree=/builds/gitlab-org/gitlab-foss' cat-file '-t' '' 2>&1:fatal: Not a valid object name
# [!] Invalid `Dangerfile` file: git '--git-dir=/builds/gitlab-org/gitlab/.git' '--work-tree=/builds/gitlab-org/gitlab' cat-file '-t' '' 2>&1:fatal: Not a valid object name
# This seems to be the same as https://github.com/danger/danger/issues/535.
# locale_files_updated = git.modified_files.select { |path| path.start_with?('locale') }
......
......@@ -20,7 +20,7 @@ changes are reviewed, take the following steps:
1. Ensure the merge request has ~database and ~"database::review pending" labels.
If the merge request modifies database files, Danger will do this for you.
1. Use the [Database changes checklist](https://gitlab.com/gitlab-org/gitlab-foss/blob/master/.gitlab/merge_request_templates/Database%20changes.md)
1. Use the [Database changes checklist](https://gitlab.com/gitlab-org/gitlab/blob/master/.gitlab/merge_request_templates/Database%20changes.md)
template or add the appropriate items to the MR description.
1. Assign and mention the database reviewer suggested by Reviewer Roulette.
MSG
......
......@@ -27,7 +27,7 @@ UNKNOWN_FILES_MESSAGE = <<MARKDOWN
These files couldn't be categorised, so Danger was unable to suggest a reviewer.
Please consider creating a merge request to
[add support](https://gitlab.com/gitlab-org/gitlab-foss/blob/master/lib/gitlab/danger/helper.rb)
[add support](https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/danger/helper.rb)
for them.
MARKDOWN
......@@ -46,7 +46,7 @@ def spin_for_category(team, project, category, branch_name)
end
# TODO: take CODEOWNERS into account?
# https://gitlab.com/gitlab-org/gitlab-foss/issues/57653
# https://gitlab.com/gitlab-org/gitlab/issues/26723
# Make traintainers have triple the chance to be picked as a reviewer
reviewer = roulette.spin_for_person(reviewers + traintainers + traintainers, random: random)
......
......@@ -113,6 +113,7 @@ Example response:
"id" : 76,
"title" : "Consequatur vero maxime deserunt laboriosam est voluptas dolorem.",
"created_at" : "2016-01-04T15:31:51.081Z",
"moved_to_id" : null,
"iid" : 6,
"labels" : ["foo", "bar"],
"upvotes": 4,
......
......@@ -147,7 +147,7 @@ You can also edit an existing tag to add release notes:
## Release Evidence
> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/26019) in GitLab 12.5.
> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/26019) in GitLab 12.6.
Each time a new release is created, specific related data is collected in
parallel. This dataset will be a snapshot this new release (including linked
......@@ -155,7 +155,7 @@ milestones and issues) at moment of creation. Such collection of data will
provide a chain of custody and facilitate processes like external audits, for example.
The gathered Evidence data is stored in the database upon creation of a new
release as a JSON object. In GitLab 12.5, a link to
release as a JSON object. In GitLab 12.6, a link to
the Evidence data is provided for [each Release](#releases-list).
Here's what this object can look like:
......
......@@ -660,6 +660,8 @@ module API
expose :subscribed, if: -> (_, options) { options.fetch(:include_subscribed, true) } do |issue, options|
issue.subscribed?(options[:current_user], options[:project] || issue.project)
end
expose :moved_to_id
end
class IssuableTimeStats < Grape::Entity
......
......@@ -153,7 +153,10 @@ module Gitlab
# Fallbacks in case the above patterns miss anything
%r{\.rb\z} => :backend,
%r{\.(md|txt)\z} => :none, # To reinstate roulette for documentation, set to `:docs`.
%r{(
\.(md|txt)\z |
\.markdownlint\.json
)}x => :none, # To reinstate roulette for documentation, set to `:docs`.
%r{\.js\z} => :frontend
}.freeze
......
......@@ -34,7 +34,7 @@ module Gitlab
end
def system_dashboard?(filepath)
SERVICES::SystemDashboardService.system_dashboard?(filepath)
SERVICES::SystemDashboardService.matching_dashboard?(filepath)
end
def custom_metric_embed?(params)
......
......@@ -6500,6 +6500,9 @@ msgstr ""
msgid "Environments allow you to track deployments of your application %{link_to_read_more}."
msgstr ""
msgid "Environments in %{name}"
msgstr ""
msgid "EnvironmentsDashboard|Add a project to the dashboard"
msgstr ""
......@@ -7651,6 +7654,9 @@ msgstr ""
msgid "FogBugz import"
msgstr ""
msgid "Folder/%{name}"
msgstr ""
msgid "Follow the steps below to export your Google Code project data."
msgstr ""
......
......@@ -26,6 +26,8 @@ gitlab:
mailroom:
enabled: false
migrations:
initialRootPassword:
secret: shared-gitlab-initial-root-password
resources:
requests:
cpu: 350m
......
......@@ -197,39 +197,33 @@ function install_external_dns() {
function create_application_secret() {
local namespace="${KUBE_NAMESPACE}"
local release="${CI_ENVIRONMENT_SLUG}"
echoinfo "Creating the ${release}-gitlab-initial-root-password secret in the ${namespace} namespace..." true
kubectl create secret generic --namespace "${namespace}" \
"${release}-gitlab-initial-root-password" \
--from-literal="password=${REVIEW_APPS_ROOT_PASSWORD}" \
--dry-run -o json | kubectl apply -f -
local initial_root_password_shared_secret
local gitlab_license_shared_secret
initial_root_password_shared_secret=$(kubectl get secret --namespace ${namespace} --no-headers -o=custom-columns=NAME:.metadata.name shared-gitlab-initial-root-password | tail -n 1)
if [[ "${initial_root_password_shared_secret}" == "" ]]; then
echoinfo "Creating the 'shared-gitlab-initial-root-password' secret in the ${namespace} namespace..." true
kubectl create secret generic --namespace "${namespace}" \
"shared-gitlab-initial-root-password" \
--from-literal="password=${REVIEW_APPS_ROOT_PASSWORD}" \
--dry-run -o json | kubectl apply -f -
else
echoinfo "The 'shared-gitlab-initial-root-password' secret already exists in the ${namespace} namespace."
fi
if [ -z "${REVIEW_APPS_EE_LICENSE}" ]; then echo "License not found" && return; fi
echoinfo "Creating the ${release}-gitlab-license secret in the ${namespace} namespace..." true
echo "${REVIEW_APPS_EE_LICENSE}" > /tmp/license.gitlab
kubectl create secret generic --namespace "${namespace}" \
"${release}-gitlab-license" \
--from-file=license=/tmp/license.gitlab \
--dry-run -o json | kubectl apply -f -
}
function label_application_secret() {
local namespace="${KUBE_NAMESPACE}"
local release="${CI_ENVIRONMENT_SLUG}"
echoinfo "Labeling the ${release}-gitlab-initial-root-password and ${release}-gitlab-license secrets in the ${namespace} namespace..." true
kubectl label secret --namespace "${namespace}" \
"${release}-gitlab-initial-root-password" \
release="${release}"
kubectl label secret --namespace "${namespace}" \
"${release}-gitlab-license" \
release="${release}"
gitlab_license_shared_secret=$(kubectl get secret --namespace ${namespace} --no-headers -o=custom-columns=NAME:.metadata.name shared-gitlab-license | tail -n 1)
if [[ "${gitlab_license_shared_secret}" == "" ]]; then
echoinfo "Creating the 'shared-gitlab-license' secret in the ${namespace} namespace..." true
echo "${REVIEW_APPS_EE_LICENSE}" > /tmp/license.gitlab
kubectl create secret generic --namespace "${namespace}" \
"shared-gitlab-license" \
--from-file=license=/tmp/license.gitlab \
--dry-run -o json | kubectl apply -f -
else
echoinfo "The 'shared-gitlab-license' secret already exists in the ${namespace} namespace."
fi
}
function download_chart() {
......@@ -272,7 +266,6 @@ function deploy() {
gitlab_workhorse_image_repository="${IMAGE_REPOSITORY}/gitlab-workhorse-${edition}"
create_application_secret
label_application_secret
HELM_CMD=$(cat << EOF
helm upgrade \
......@@ -308,7 +301,7 @@ EOF
if [ -n "${REVIEW_APPS_EE_LICENSE}" ]; then
HELM_CMD=$(cat << EOF
${HELM_CMD} \
--set global.gitlab.license.secret="${release}-gitlab-license"
--set global.gitlab.license.secret="shared-gitlab-license"
EOF
)
fi
......
......@@ -6,17 +6,6 @@ describe 'Pipeline Badge' do
set(:project) { create(:project, :repository, :public) }
let(:ref) { project.default_branch }
# this can't be tested in the controller, as it bypasses the rails router
# and constructs a route based on the controller being tested
# Keep around until 10.0, see gitlab-org/gitlab-ce#35307
context 'when the deprecated badge is requested' do
it 'displays the badge' do
visit build_project_badges_path(project, ref: ref, format: :svg)
expect(page.status_code).to eq(200)
end
end
context 'when the project has a pipeline' do
let!(:pipeline) { create(:ci_empty_pipeline, project: project, ref: ref, sha: project.commit(ref).sha) }
let!(:job) { create(:ci_build, pipeline: pipeline) }
......
......@@ -426,24 +426,38 @@ describe MergeRequestDiff do
end
end
describe '#commits_by_shas' do
let(:commit_shas) { diff_with_commits.commit_shas }
it 'returns empty if no SHAs were provided' do
expect(diff_with_commits.commits_by_shas([])).to be_empty
describe '#includes_any_commits?' do
let(:non_existent_shas) do
Array.new(30) { Digest::SHA1.hexdigest(SecureRandom.hex) }
end
it 'returns one SHA' do
commits = diff_with_commits.commits_by_shas([commit_shas.first, Gitlab::Git::BLANK_SHA])
subject { diff_with_commits }
context 'processes the passed shas in batches' do
context 'number of existing commits is greater than batch size' do
it 'performs a separate request for each batch' do
stub_const('MergeRequestDiff::BATCH_SIZE', 5)
commit_shas = subject.commit_shas
query_count = ActiveRecord::QueryRecorder.new do
subject.includes_any_commits?(non_existent_shas + commit_shas)
end.count
expect(query_count).to eq(7)
end
end
end
expect(commits.count).to eq(1)
it 'returns false if passed commits do not exist' do
expect(subject.includes_any_commits?([])).to eq(false)
expect(subject.includes_any_commits?([Gitlab::Git::BLANK_SHA])).to eq(false)
end
it 'returns all matching SHAs' do
commits = diff_with_commits.commits_by_shas(commit_shas)
it 'returns true if passed commits exists' do
args_with_existing_commits = non_existent_shas << subject.head_commit_sha
expect(commits.count).to eq(commit_shas.count)
expect(commits.map(&:sha)).to match_array(commit_shas)
expect(subject.includes_any_commits?(args_with_existing_commits)).to eq(true)
end
end
......
......@@ -3134,36 +3134,6 @@ describe MergeRequest do
end
end
describe '#includes_any_commits?' do
it 'returns false' do
expect(subject.includes_any_commits?([])).to be_falsey
end
it 'returns false' do
expect(subject.includes_any_commits?([Gitlab::Git::BLANK_SHA])).to be_falsey
end
it 'returns true' do
expect(subject.includes_any_commits?([subject.merge_request_diff.head_commit_sha])).to be_truthy
end
it 'returns true even when there is a non-existent comit' do
expect(subject.includes_any_commits?([Gitlab::Git::BLANK_SHA, subject.merge_request_diff.head_commit_sha])).to be_truthy
end
context 'unpersisted merge request' do
let(:new_mr) { build(:merge_request) }
it 'returns false' do
expect(new_mr.includes_any_commits?([Gitlab::Git::BLANK_SHA])).to be_falsey
end
it 'returns true' do
expect(new_mr.includes_any_commits?([subject.merge_request_diff.head_commit_sha])).to be_truthy
end
end
end
describe '#can_allow_collaboration?' do
let(:target_project) { create(:project, :public) }
let(:source_project) { fork_project(target_project) }
......
......@@ -589,6 +589,24 @@ describe API::Issues do
expect(json_response['subscribed']).to be_truthy
end
context "moved_to_id" do
let(:moved_issue) do
create(:closed_issue, project: project, moved_to: issue)
end
it 'returns null when not moved' do
get api("/projects/#{project.id}/issues/#{issue.iid}", user)
expect(json_response['moved_to_id']).to be_nil
end
it 'returns issue id when moved' do
get api("/projects/#{project.id}/issues/#{moved_issue.iid}", user)
expect(json_response['moved_to_id']).to eq(issue.id)
end
end
it 'exposes the closed_at attribute' do
get api("/projects/#{project.id}/issues/#{closed_issue.iid}", user)
......
......@@ -832,7 +832,7 @@ describe API::Issues do
end
context 'when issue does not exist' do
it 'returns 404 when trying to move an issue' do
it 'returns 404 when trying to delete an issue' do
delete api("/projects/#{project.id}/issues/123", user)
expect(response).to have_gitlab_http_status(404)
......
......@@ -14,24 +14,18 @@ describe Metrics::Dashboard::SystemDashboardService, :use_clean_rails_memory_sto
end
describe 'get_dashboard' do
let(:dashboard_path) { described_class::SYSTEM_DASHBOARD_PATH }
let(:dashboard_path) { described_class::DASHBOARD_PATH }
let(:service_params) { [project, user, { environment: environment, dashboard_path: dashboard_path }] }
let(:service_call) { described_class.new(*service_params).get_dashboard }
it_behaves_like 'valid dashboard service response'
it_behaves_like 'raises error for users with insufficient permissions'
it 'caches the unprocessed dashboard for subsequent calls' do
expect(YAML).to receive(:safe_load).once.and_call_original
described_class.new(*service_params).get_dashboard
described_class.new(*service_params).get_dashboard
end
it_behaves_like 'caches the unprocessed dashboard for subsequent calls'
context 'when called with a non-system dashboard' do
let(:dashboard_path) { 'garbage/dashboard/path' }
# We want to alwaus return the system dashboard.
# We want to always return the system dashboard.
it_behaves_like 'valid dashboard service response'
end
end
......@@ -42,8 +36,8 @@ describe Metrics::Dashboard::SystemDashboardService, :use_clean_rails_memory_sto
expect(all_dashboards).to eq(
[{
path: described_class::SYSTEM_DASHBOARD_PATH,
display_name: described_class::SYSTEM_DASHBOARD_NAME,
path: described_class::DASHBOARD_PATH,
display_name: described_class::DASHBOARD_NAME,
default: true,
system_dashboard: true
}]
......
......@@ -19,7 +19,7 @@ module MetricsDashboardHelpers
end
def system_dashboard_path
Metrics::Dashboard::SystemDashboardService::SYSTEM_DASHBOARD_PATH
Metrics::Dashboard::SystemDashboardService::DASHBOARD_PATH
end
def business_metric_title
......@@ -53,6 +53,15 @@ module MetricsDashboardHelpers
it_behaves_like 'valid dashboard service response for schema'
end
shared_examples_for 'caches the unprocessed dashboard for subsequent calls' do
it do
expect(YAML).to receive(:safe_load).once.and_call_original
described_class.new(*service_params).get_dashboard
described_class.new(*service_params).get_dashboard
end
end
shared_examples_for 'valid embedded dashboard service response' do
let(:dashboard_schema) { JSON.parse(fixture_file('lib/gitlab/metrics/dashboard/schemas/embedded_dashboard.json')) }
......
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