提交 78d8830c 编写于 作者: G GitLab Bot

Add latest changes from gitlab-org/gitlab@master

上级 652bd073
......@@ -2,6 +2,8 @@
cache:
paths:
- vendor/ruby/
- public/assets/webpack/
- assets-hash.txt
- .yarn-cache/
- tmp/cache/assets/sprockets
- tmp/cache/babel-loader
......@@ -28,18 +30,24 @@
DOCKER_DRIVER: overlay2
DOCKER_HOST: tcp://docker:2375
cache:
key: "assets-compile:production:vendor_ruby:.yarn-cache:tmp_cache_assets_sprockets:tmp_cache_webpack:v9"
key: "assets-compile:production:v1"
artifacts:
name: webpack-report
expire_in: 31d
paths:
- webpack-report/
- public/assets/
- assets-compile.log
- public/assets/application-*.css
- public/assets/application-*.css.gz
when: always
script:
- node --version
- retry yarn install --frozen-lockfile --production --cache-folder .yarn-cache --prefer-offline
- free -m
- retry bundle exec rake gitlab:assets:compile
- time bin/rake gitlab:assets:compile > assets-compile.log 2>&1
# TODO: Change the image tag to be the MD5 of assets files and skip image building if the image exists
# We'll also need to pass GITLAB_ASSETS_TAG to the trigerred omnibus-gitlab pipeline similarly to how we do it for trigerred CNG pipelines
# https://gitlab.com/gitlab-org/gitlab/issues/208389
- time scripts/build_assets_image
- scripts/clean-old-cached-assets
- rm -f /etc/apt/sources.list.d/google*.list # We don't need to update Chrome here
......@@ -71,7 +79,7 @@ gitlab:assets:compile pull-cache:
- node --version
- retry yarn install --frozen-lockfile --cache-folder .yarn-cache --prefer-offline
- free -m
- retry bundle exec rake gitlab:assets:compile
- time bin/rake gitlab:assets:compile > assets-compile.log 2>&1
- scripts/clean-old-cached-assets
variables:
SETUP_DB: "false"
......@@ -79,12 +87,13 @@ gitlab:assets:compile pull-cache:
NODE_OPTIONS: --max_old_space_size=3584
WEBPACK_VENDOR_DLL: "true"
cache:
key: "assets-compile:v9"
key: "assets-compile:test:v1"
artifacts:
expire_in: 7d
paths:
- node_modules
- public/assets
- assets-compile.log
compile-assets pull-push-cache:
extends:
......@@ -100,7 +109,7 @@ compile-assets pull-push-cache as-if-foss:
- .as-if-foss
cache:
policy: pull-push
key: "assets-compile:v9:foss"
key: "assets-compile:test:as-if-foss:v1"
compile-assets pull-cache:
extends:
......@@ -116,7 +125,7 @@ compile-assets pull-cache as-if-foss:
- .as-if-foss
cache:
policy: pull
key: "assets-compile:v9:foss"
key: "assets-compile:test:as-if-foss:v1"
.frontend-fixtures-base:
extends:
......
......@@ -55,5 +55,9 @@ package-and-qa:
extends:
- .package-and-qa-base
- .qa:rules:package-and-qa
needs: ["build-qa-image", "gitlab:assets:compile pull-cache"]
needs:
- job: build-qa-image
artifacts: false
- job: gitlab:assets:compile pull-cache
artifacts: false
allow_failure: true
......@@ -327,6 +327,7 @@ export default {
</gl-table>
<gl-pagination
v-if="!isLoading"
ref="pagination"
v-model="currentPage"
:per-page="tagsPagination.perPage"
......
......@@ -48,14 +48,7 @@ class Import::GitlabProjectsController < Import::BaseController
private
def file_is_valid?
# TODO: remove the condition and the private method after the WH version including
# https://gitlab.com/gitlab-org/gitlab-workhorse/-/merge_requests/470
# is released and GITLAB_WORKHORSE_VERSION is updated accordingly.
if with_workhorse_upload_acceleration?
return false unless project_params[:file].is_a?(::UploadedFile)
else
return false unless project_params[:file] && project_params[:file].respond_to?(:read)
end
return false unless project_params[:file].is_a?(::UploadedFile)
filename = project_params[:file].original_filename
......@@ -75,8 +68,4 @@ class Import::GitlabProjectsController < Import::BaseController
def whitelist_query_limiting
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-foss/issues/42437')
end
def with_workhorse_upload_acceleration?
request.headers[Gitlab::Workhorse::INTERNAL_API_REQUEST_HEADER].present?
end
end
......@@ -598,19 +598,15 @@ module Ci
end
def merge_request
return @merge_request if defined?(@merge_request)
strong_memoize(:merge_request) do
merge_requests = MergeRequest.includes(:latest_merge_request_diff)
.where(source_branch: ref, source_project: pipeline.project)
.reorder(iid: :desc)
@merge_request ||=
begin
merge_requests = MergeRequest.includes(:latest_merge_request_diff)
.where(source_branch: ref,
source_project: pipeline.project)
.reorder(iid: :desc)
merge_requests.find do |merge_request|
merge_request.commit_shas.include?(pipeline.sha)
end
merge_requests.find do |merge_request|
merge_request.commit_shas.include?(pipeline.sha)
end
end
end
def repo_url
......
......@@ -16,7 +16,7 @@
%head{ prefix: "og: http://ogp.me/ns#" }
%meta{ charset: "utf-8" }
- if Feature.enabled?('asset_host_prefetch') && ActionController::Base.asset_host
- if ActionController::Base.asset_host
%link{ rel: 'dns-prefetch', href: ActionController::Base.asset_host }
%link{ rel: 'preconnnect', href: ActionController::Base.asset_host, crossorigin: '' }
......
---
title: Adds branch information to the package details title section
merge_request: 27488
author:
type: added
---
title: Enable Workhorse upload acceleration for Project Import uploads via UI
merge_request: 27332
author:
type: performance
---
title: Disable lookup of other ActiveSessions to determine admin mode status
merge_request: 27318
author: Diego Louzán
type: changed
---
title: Prefetch DNS for asset host
merge_request: 26868
author:
type: performance
......@@ -77,7 +77,7 @@ module Gitlab
return false unless user
Gitlab::SafeRequestStore.fetch(admin_mode_rs_key) do
user.admin? && any_session_with_admin_mode?
user.admin? && session_with_admin_mode?
end
end
......@@ -136,19 +136,10 @@ module Gitlab
@current_session ||= Gitlab::NamespacedSessionStore.new(SESSION_STORE_KEY)
end
def any_session_with_admin_mode?
def session_with_admin_mode?
return true if bypass_session?
return true if current_session_data.initiated? && current_session_data[ADMIN_MODE_START_TIME_KEY].to_i > MAX_ADMIN_MODE_TIME.ago.to_i
all_sessions.any? do |session|
session[ADMIN_MODE_START_TIME_KEY].to_i > MAX_ADMIN_MODE_TIME.ago.to_i
end
end
def all_sessions
@all_sessions ||= ActiveSession.list_sessions(user).lazy.map do |session|
Gitlab::NamespacedSessionStore.new(SESSION_STORE_KEY, session.with_indifferent_access )
end
current_session_data.initiated? && current_session_data[ADMIN_MODE_START_TIME_KEY].to_i > MAX_ADMIN_MODE_TIME.ago.to_i
end
def admin_mode_requested_in_grace_period?
......
# frozen_string_literal: true
require 'fileutils'
module Tasks
module Gitlab
module Assets
FOSS_ASSET_FOLDERS = %w[app/assets app/views fixtures/emojis vendor/assets/javascripts].freeze
EE_ASSET_FOLDERS = %w[ee/app/assets ee/app/views].freeze
JS_ASSET_PATTERNS = %w[*.js config/**/*.js].freeze
JS_ASSET_FILES = %w[package.json yarn.lock].freeze
MASTER_MD5_HASH_FILE = 'master-assets-hash.txt'
HEAD_MD5_HASH_FILE = 'assets-hash.txt'
PUBLIC_ASSETS_WEBPACK_DIR = 'public/assets/webpack'
def self.md5_of_assets_impacting_webpack_compilation
start_time = Time.now
asset_files = assets_impacting_webpack_compilation
puts "Generating the MD5 hash for #{assets_impacting_webpack_compilation.size} Webpack-related assets..."
asset_file_md5s = asset_files.map do |asset_file|
Digest::MD5.file(asset_file).hexdigest
end
Digest::MD5.hexdigest(asset_file_md5s.join).tap { |md5| puts "=> MD5 generated in #{Time.now - start_time}: #{md5}" }
end
def self.assets_impacting_webpack_compilation
assets_folders = FOSS_ASSET_FOLDERS
assets_folders += EE_ASSET_FOLDERS if ::Gitlab.ee?
asset_files = Dir.glob(JS_ASSET_PATTERNS)
asset_files += JS_ASSET_FILES
assets_folders.each do |folder|
asset_files.concat(Dir.glob(["#{folder}/**/*.*"]))
end
asset_files
end
private_class_method :assets_impacting_webpack_compilation
end
end
end
namespace :gitlab do
namespace :assets do
desc 'GitLab | Assets | Compile all frontend assets'
......@@ -8,9 +53,35 @@ namespace :gitlab do
yarn:check
gettext:po_to_json
rake:assets:precompile
webpack:compile
gitlab:assets:compile_webpack_if_needed
gitlab:assets:fix_urls
].each(&Gitlab::TaskHelpers.method(:invoke_and_time_task))
].each(&::Gitlab::TaskHelpers.method(:invoke_and_time_task))
end
desc 'GitLab | Assets | Compile all Webpack assets'
task :compile_webpack_if_needed do
FileUtils.mv(Tasks::Gitlab::Assets::HEAD_MD5_HASH_FILE, Tasks::Gitlab::Assets::MASTER_MD5_HASH_FILE, force: true)
master_assets_md5 =
if File.exist?(Tasks::Gitlab::Assets::MASTER_MD5_HASH_FILE)
File.read(Tasks::Gitlab::Assets::MASTER_MD5_HASH_FILE)
else
'missing!'
end
head_assets_md5 = Tasks::Gitlab::Assets.md5_of_assets_impacting_webpack_compilation.tap do |md5|
File.write(Tasks::Gitlab::Assets::HEAD_MD5_HASH_FILE, md5)
end
puts "Webpack assets MD5 for `master`: #{master_assets_md5}"
puts "Webpack assets MD5 for `HEAD`: #{head_assets_md5}"
public_assets_webpack_dir_exists = Dir.exist?(Tasks::Gitlab::Assets::PUBLIC_ASSETS_WEBPACK_DIR)
if head_assets_md5 != master_assets_md5 || !public_assets_webpack_dir_exists
FileUtils.rm_r(Tasks::Gitlab::Assets::PUBLIC_ASSETS_WEBPACK_DIR) if public_assets_webpack_dir_exists
Rake::Task['webpack:compile'].invoke
end
end
desc 'GitLab | Assets | Clean up old compiled frontend assets'
......
......@@ -3,90 +3,21 @@
require 'spec_helper'
describe 'Group navbar' do
let(:user) { create(:user) }
let(:group) { create(:group) }
include NavbarStructureHelper
let(:analytics_nav_item) do
{
nav_item: _('Analytics'),
nav_sub_items: [
_('Contribution')
]
}
end
include_context 'group navbar structure'
let_it_be(:user) { create(:user) }
let_it_be(:group) { create(:group) }
let(:structure) do
[
{
nav_item: _('Group overview'),
nav_sub_items: [
_('Details'),
_('Activity')
]
},
{
nav_item: _('Issues'),
nav_sub_items: [
_('List'),
_('Board'),
_('Labels'),
_('Milestones')
]
},
{
nav_item: _('Merge Requests'),
nav_sub_items: []
},
{
nav_item: _('Kubernetes'),
nav_sub_items: []
},
(analytics_nav_item if Gitlab.ee?),
{
nav_item: _('Members'),
nav_sub_items: []
}
]
before do
group.add_maintainer(user)
sign_in(user)
end
it_behaves_like 'verified navigation bar' do
before do
group.add_maintainer(user)
sign_in(user)
visit group_path(group)
end
end
if Gitlab.ee?
context 'when productivity analytics is available' do
before do
stub_licensed_features(productivity_analytics: true)
analytics_nav_item[:nav_sub_items] << _('Productivity')
group.add_maintainer(user)
sign_in(user)
visit group_path(group)
end
it_behaves_like 'verified navigation bar'
end
context 'when value stream analytics is available' do
before do
stub_licensed_features(cycle_analytics_for_groups: true)
analytics_nav_item[:nav_sub_items] << _('Value Stream')
group.add_maintainer(user)
sign_in(user)
visit group_path(group)
end
it_behaves_like 'verified navigation bar'
end
end
end
......@@ -3,112 +3,14 @@
require 'spec_helper'
describe 'Project navbar' do
let(:user) { create(:user) }
let(:project) { create(:project, :repository) }
include NavbarStructureHelper
let(:analytics_nav_item) do
{
nav_item: _('Analytics'),
nav_sub_items: [
_('CI / CD'),
(_('Code Review') if Gitlab.ee?),
_('Repository'),
_('Value Stream')
]
}
end
include_context 'project navbar structure'
let(:requirements_nav_item) do
{
nav_item: _('Requirements'),
nav_sub_items: [_('List')]
}
end
let(:structure) do
[
{
nav_item: _('Project overview'),
nav_sub_items: [
_('Details'),
_('Activity'),
_('Releases')
]
},
{
nav_item: _('Repository'),
nav_sub_items: [
_('Files'),
_('Commits'),
_('Branches'),
_('Tags'),
_('Contributors'),
_('Graph'),
_('Compare'),
(_('Locked Files') if Gitlab.ee?)
]
},
{
nav_item: _('Issues'),
nav_sub_items: [
_('List'),
_('Boards'),
_('Labels'),
_('Milestones')
]
},
{
nav_item: _('Merge Requests'),
nav_sub_items: []
},
(requirements_nav_item if Gitlab.ee?),
{
nav_item: _('CI / CD'),
nav_sub_items: [
_('Pipelines'),
_('Jobs'),
_('Artifacts'),
_('Schedules')
]
},
{
nav_item: _('Operations'),
nav_sub_items: [
_('Metrics'),
_('Environments'),
_('Error Tracking'),
_('Serverless'),
_('Logs'),
_('Kubernetes')
]
},
analytics_nav_item,
{
nav_item: _('Wiki'),
nav_sub_items: []
},
{
nav_item: _('Snippets'),
nav_sub_items: []
},
{
nav_item: _('Settings'),
nav_sub_items: [
_('General'),
_('Members'),
_('Integrations'),
_('Webhooks'),
_('Repository'),
_('CI / CD'),
_('Operations'),
(_('Audit Events') if Gitlab.ee?)
].compact
}
]
end
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, :repository) }
before do
stub_licensed_features(requirements: false)
project.add_maintainer(user)
sign_in(user)
end
......@@ -119,28 +21,19 @@ describe 'Project navbar' do
end
end
if Gitlab.ee?
context 'when issues analytics is available' do
before do
stub_licensed_features(issues_analytics: true)
analytics_nav_item[:nav_sub_items] << _('Issues')
analytics_nav_item[:nav_sub_items].sort!
context 'when pages are available' do
before do
allow(Gitlab.config.pages).to receive(:enabled).and_return(true)
visit project_path(project)
end
insert_after_sub_nav_item(
_('Operations'),
within: _('Settings'),
new_sub_nav_item_name: _('Pages')
)
it_behaves_like 'verified navigation bar'
visit project_path(project)
end
context 'when requirements is available' do
before do
stub_licensed_features(requirements: true)
visit project_path(project)
end
it_behaves_like 'verified navigation bar'
end
it_behaves_like 'verified navigation bar'
end
end
......@@ -13,6 +13,9 @@ describe 'Projects > Snippets > User comments on a snippet', :js do
sign_in(user)
visit(project_snippet_path(project, snippet))
# Snippet's content is loaded async, we wait for it before we try to click anything
wait_for_requests
end
it 'leaves a comment on a snippet' do
......@@ -34,7 +37,8 @@ describe 'Projects > Snippets > User comments on a snippet', :js do
end
it 'has zen mode' do
find('.js-zen-enter').click
click_button 'Go full screen'
expect(page).to have_selector('.fullscreen')
end
end
......@@ -66,6 +66,10 @@ describe('Details Page', () => {
it('does not have list items', () => {
expect(findFirstRowItem('rowCheckbox').exists()).toBe(false);
});
it('does not show pagination', () => {
expect(findPagination().exists()).toBe(false);
});
});
describe('table', () => {
......
......@@ -151,13 +151,13 @@ describe Gitlab::Auth::CurrentUserMode, :do_not_mock_admin_mode, :request_store
allow(ActiveSession).to receive(:list_sessions).with(user).and_return([session, another_session])
end
it 'can be enabled in one and seen in the other' do
it 'cannot be enabled in one and seen in the other' do
Gitlab::Session.with_session(another_session) do
another_subject.request_admin_mode!
another_subject.enable_admin_mode!(password: user.password)
end
expect(subject.admin_mode?).to be(true)
expect(subject.admin_mode?).to be(false)
end
end
end
......
......@@ -34,8 +34,6 @@ describe BugzillaService do
end
context 'overriding properties' do
let(:default_title) { 'JIRA' }
let(:default_description) { 'JiraService|Jira issue tracker' }
let(:url) { 'http://bugzilla.example.com' }
let(:access_params) do
{ project_url: url, issues_url: url, new_issue_url: url }
......
......@@ -3,62 +3,101 @@
require 'spec_helper'
describe Import::GitlabProjectsController do
include WorkhorseHelpers
let(:workhorse_token) { JWT.encode({ 'iss' => 'gitlab-workhorse' }, Gitlab::Workhorse.secret, 'HS256') }
let(:workhorse_headers) { { 'GitLab-Workhorse' => '1.0', Gitlab::Workhorse::INTERNAL_API_REQUEST_HEADER => workhorse_token } }
let_it_be(:namespace) { create(:namespace) }
let_it_be(:user) { namespace.owner }
let(:file) { fixture_file_upload('spec/fixtures/project_export.tar.gz', 'text/plain') }
before do
sign_in(user)
login_as(user)
end
describe 'POST create' do
context 'with an invalid path' do
it 'redirects with an error' do
post :create, params: { namespace_id: namespace.id, path: '/test', file: file }
subject { upload_archive(file_upload, workhorse_headers, params) }
let(:file) { File.join('spec', 'features', 'projects', 'import_export', 'test_project_export.tar.gz') }
let(:file_upload) { fixture_file_upload(file) }
let(:params) { { namespace_id: namespace.id, path: 'test' } }
before do
allow(ImportExportUploader).to receive(:workhorse_upload_path).and_return('/')
end
expect(flash[:alert]).to start_with('Project could not be imported')
context 'with a valid path' do
it 'schedules an import and redirects to the new project path' do
stub_import(namespace)
subject
expect(flash[:notice]).to include('is being imported')
expect(response).to have_gitlab_http_status(:found)
end
end
context 'with an invalid path' do
['/test', '../test'].each do |invalid_path|
it "redirects with an error when path is `#{invalid_path}`" do
params[:path] = invalid_path
it 'redirects with an error when a relative path is used' do
post :create, params: { namespace_id: namespace.id, path: '../test', file: file }
subject
expect(flash[:alert]).to start_with('Project could not be imported')
expect(response).to have_gitlab_http_status(:found)
expect(flash[:alert]).to start_with('Project could not be imported')
expect(response).to have_gitlab_http_status(:found)
end
end
end
context 'with a valid path' do
it 'redirects to the new project path' do
post :create, params: { namespace_id: namespace.id, path: 'test', file: file }
context 'when request exceeds the rate limit' do
before do
allow(::Gitlab::ApplicationRateLimiter).to receive(:throttled?).and_return(true)
end
expect(flash[:notice]).to include('is being imported')
it 'prevents users from importing projects' do
subject
expect(flash[:alert]).to eq('This endpoint has been requested too many times. Try again later.')
expect(response).to have_gitlab_http_status(:found)
end
end
it_behaves_like 'project import rate limiter'
def upload_archive(file, headers = {}, params = {})
workhorse_finalize(
import_gitlab_project_path,
method: :post,
file_key: :file,
params: params.merge(file: file),
headers: headers,
send_rewritten_field: true
)
end
def stub_import(namespace)
expect_any_instance_of(ProjectImportState).to receive(:schedule)
expect(::Projects::CreateService)
.to receive(:new)
.with(user, instance_of(ActionController::Parameters))
.and_call_original
end
end
describe 'POST authorize' do
let(:workhorse_token) { JWT.encode({ 'iss' => 'gitlab-workhorse' }, Gitlab::Workhorse.secret, 'HS256') }
before do
request.headers['GitLab-Workhorse'] = '1.0'
request.headers[Gitlab::Workhorse::INTERNAL_API_REQUEST_HEADER] = workhorse_token
end
subject { post authorize_import_gitlab_project_path, headers: workhorse_headers }
it 'authorizes importing project with workhorse header' do
post :authorize, format: :json
subject
expect(response).to have_gitlab_http_status(:ok)
expect(response.content_type.to_s).to eq(Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE)
expect(json_response['TempPath']).to eq(ImportExportUploader.workhorse_local_upload_path)
end
it 'rejects requests that bypassed gitlab-workhorse or have invalid header' do
request.headers[Gitlab::Workhorse::INTERNAL_API_REQUEST_HEADER] = 'INVALID_HEADER'
it 'rejects requests that bypassed gitlab-workhorse' do
workhorse_headers.delete(Gitlab::Workhorse::INTERNAL_API_REQUEST_HEADER)
expect { post :authorize, format: :json }.to raise_error(JWT::DecodeError)
expect { subject }.to raise_error(JWT::DecodeError)
end
context 'when using remote storage' do
......@@ -68,7 +107,7 @@ describe Import::GitlabProjectsController do
end
it 'responds with status 200, location of file remote store and object details' do
post :authorize, format: :json
subject
expect(response).to have_gitlab_http_status(:ok)
expect(response.content_type.to_s).to eq(Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE)
......@@ -87,7 +126,7 @@ describe Import::GitlabProjectsController do
end
it 'handles as a local file' do
post :authorize, format: :json
subject
expect(response).to have_gitlab_http_status(:ok)
expect(response.content_type.to_s).to eq(Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE)
......
# frozen_string_literal: true
module NavbarStructureHelper
def insert_after_nav_item(before_nav_item_name, new_nav_item:)
expect(structure).to include(a_hash_including(nav_item: before_nav_item_name))
index = structure.find_index { |h| h[:nav_item] == before_nav_item_name }
structure.insert(index + 1, new_nav_item)
end
def insert_after_sub_nav_item(before_sub_nav_item_name, within:, new_sub_nav_item_name:)
expect(structure).to include(a_hash_including(nav_item: within))
hash = structure.find { |h| h[:nav_item] == within }
expect(hash).to have_key(:nav_sub_items)
expect(hash[:nav_sub_items]).to include(before_sub_nav_item_name)
index = hash[:nav_sub_items].find_index(before_sub_nav_item_name)
hash[:nav_sub_items].insert(index + 1, new_sub_nav_item_name)
end
end
# frozen_string_literal: true
RSpec.shared_context 'project navbar structure' do
let(:requirements_nav_item) do
{
nav_item: _('Requirements'),
nav_sub_items: [_('List')]
}
end
let(:analytics_nav_item) do
{
nav_item: _('Analytics'),
nav_sub_items: [
_('CI / CD'),
(_('Code Review') if Gitlab.ee?),
_('Repository'),
_('Value Stream')
]
}
end
let(:structure) do
[
{
nav_item: _('Project overview'),
nav_sub_items: [
_('Details'),
_('Activity'),
_('Releases')
]
},
{
nav_item: _('Repository'),
nav_sub_items: [
_('Files'),
_('Commits'),
_('Branches'),
_('Tags'),
_('Contributors'),
_('Graph'),
_('Compare'),
(_('Locked Files') if Gitlab.ee?)
]
},
{
nav_item: _('Issues'),
nav_sub_items: [
_('List'),
_('Boards'),
_('Labels'),
_('Milestones')
]
},
{
nav_item: _('Merge Requests'),
nav_sub_items: []
},
(requirements_nav_item if Gitlab.ee?),
{
nav_item: _('CI / CD'),
nav_sub_items: [
_('Pipelines'),
_('Jobs'),
_('Artifacts'),
_('Schedules')
]
},
{
nav_item: _('Operations'),
nav_sub_items: [
_('Metrics'),
_('Environments'),
_('Error Tracking'),
_('Serverless'),
_('Logs'),
_('Kubernetes')
]
},
analytics_nav_item,
{
nav_item: _('Wiki'),
nav_sub_items: []
},
{
nav_item: _('Snippets'),
nav_sub_items: []
},
{
nav_item: _('Settings'),
nav_sub_items: [
_('General'),
_('Members'),
_('Integrations'),
_('Webhooks'),
_('Repository'),
_('CI / CD'),
_('Operations'),
(_('Audit Events') if Gitlab.ee?)
].compact
}
].compact
end
end
RSpec.shared_context 'group navbar structure' do
let(:analytics_nav_item) do
{
nav_item: _('Analytics'),
nav_sub_items: [
_('Contribution')
]
}
end
let(:settings_nav_item) do
{
nav_item: _('Settings'),
nav_sub_items: [
_('General'),
_('Projects'),
_('CI / CD'),
_('Webhooks'),
_('Audit Events'),
_('Usage Quotas')
]
}
end
let(:structure) do
[
{
nav_item: _('Group overview'),
nav_sub_items: [
_('Details'),
_('Activity')
]
},
{
nav_item: _('Issues'),
nav_sub_items: [
_('List'),
_('Board'),
_('Labels'),
_('Milestones')
]
},
{
nav_item: _('Merge Requests'),
nav_sub_items: []
},
{
nav_item: _('Kubernetes'),
nav_sub_items: []
},
(analytics_nav_item if Gitlab.ee?),
{
nav_item: _('Members'),
nav_sub_items: []
}
]
end
end
......@@ -34,36 +34,23 @@ describe 'layouts/_head' do
expect(rendered).to match(%{content="foo&quot; http-equiv=&quot;refresh"})
end
context 'when an asset_host is set and feature is activated in the config it will' do
context 'when an asset_host is set' do
let(:asset_host) { 'http://assets' }
before do
stub_feature_flags(asset_host_prefetch: true)
allow(ActionController::Base).to receive(:asset_host).and_return(asset_host)
end
it 'add a link dns-prefetch tag' do
it 'adds a link dns-prefetch tag' do
render
expect(rendered).to match('<link href="http://assets" rel="dns-prefetch">')
end
it 'add a link preconnect tag' do
render
expect(rendered).to match('<link crossorigin="" href="http://assets" rel="preconnnect">')
end
end
context 'when an asset_host is set and feature is not activated in the config it will' do
let(:asset_host) { 'http://assets' }
before do
stub_feature_flags(asset_host_prefetch: false)
allow(ActionController::Base).to receive(:asset_host).and_return(asset_host)
expect(rendered).to match(%Q(<link href="#{asset_host}" rel="dns-prefetch">))
end
it 'not add a link dns-prefetch tag' do
it 'adds a link preconnect tag' do
render
expect(rendered).not_to match('<link href="http://assets" rel="dns-prefetch">')
expect(rendered).to match(%Q(<link crossorigin="" href="#{asset_host}" rel="preconnnect">))
end
end
......
......@@ -781,15 +781,15 @@
eslint-plugin-vue "^6.2.1"
vue-eslint-parser "^7.0.0"
"@gitlab/svgs@^1.113.0":
version "1.113.0"
resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-1.113.0.tgz#0ea9cb3122a479f3ed4bb22943d68a9a38f69948"
integrity sha512-upT+sKEnnwZDU7vzI5VSyg2l6IOd/0Icm/MLae6po/nOGbf2vftkUVfbalzISAmk9eYTuJQ1sGmRWdKXPGy1cw==
"@gitlab/ui@^9.29.0":
version "9.29.0"
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-9.29.0.tgz#2308aec1d3d837392eaaf9d441aecec4b695ed73"
integrity sha512-zIY/aChWaU4UBlAjZ95PpBxgUd9VrGiXs9ujVU6Gbi+ZsHbpDvPlBHsHEG9isnUVBE2AD4GPqMLO8K9i+B9O4A==
"@gitlab/svgs@^1.114.0":
version "1.114.0"
resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-1.114.0.tgz#ffee243fa540016c8198596686a46e3c459adb32"
integrity sha512-r2tizWDx1fX2QbeXzU0Z5Fi9YS7TLIxt7K+vAnZxOeddgd5KdipCvhT/H7n9Oa9jLU4bMwGSrHZ1usCmCoWOnw==
"@gitlab/ui@^9.31.1":
version "9.31.1"
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-9.31.1.tgz#53206aac643d79f8eddbc5715131bad5ffc1e412"
integrity sha512-MHBVIpVzUYPkr70ti21dTZbzzZttOidWZdN3TeZOdqYbjYg2ONujFBxOGSCNYcaMYr+1/wFtuVRL/JmMVGjJrg==
dependencies:
"@babel/standalone" "^7.0.0"
"@gitlab/vue-toasted" "^1.3.0"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册