Commit 78d8830c authored by GitLab Bot's avatar GitLab Bot

Add latest changes from gitlab-org/gitlab@master

parent 652bd073
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
cache: cache:
paths: paths:
- vendor/ruby/ - vendor/ruby/
- public/assets/webpack/
- assets-hash.txt
- .yarn-cache/ - .yarn-cache/
- tmp/cache/assets/sprockets - tmp/cache/assets/sprockets
- tmp/cache/babel-loader - tmp/cache/babel-loader
...@@ -28,18 +30,24 @@ ...@@ -28,18 +30,24 @@
DOCKER_DRIVER: overlay2 DOCKER_DRIVER: overlay2
DOCKER_HOST: tcp://docker:2375 DOCKER_HOST: tcp://docker:2375
cache: cache:
key: "assets-compile:production:vendor_ruby:.yarn-cache:tmp_cache_assets_sprockets:tmp_cache_webpack:v9" key: "assets-compile:production:v1"
artifacts: artifacts:
name: webpack-report name: webpack-report
expire_in: 31d expire_in: 31d
paths: paths:
- webpack-report/ - webpack-report/
- public/assets/ - assets-compile.log
- public/assets/application-*.css
- public/assets/application-*.css.gz
when: always
script: script:
- node --version - node --version
- retry yarn install --frozen-lockfile --production --cache-folder .yarn-cache --prefer-offline - retry yarn install --frozen-lockfile --production --cache-folder .yarn-cache --prefer-offline
- free -m - 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 - time scripts/build_assets_image
- scripts/clean-old-cached-assets - scripts/clean-old-cached-assets
- rm -f /etc/apt/sources.list.d/google*.list # We don't need to update Chrome here - 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: ...@@ -71,7 +79,7 @@ gitlab:assets:compile pull-cache:
- node --version - node --version
- retry yarn install --frozen-lockfile --cache-folder .yarn-cache --prefer-offline - retry yarn install --frozen-lockfile --cache-folder .yarn-cache --prefer-offline
- free -m - 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 - scripts/clean-old-cached-assets
variables: variables:
SETUP_DB: "false" SETUP_DB: "false"
...@@ -79,12 +87,13 @@ gitlab:assets:compile pull-cache: ...@@ -79,12 +87,13 @@ gitlab:assets:compile pull-cache:
NODE_OPTIONS: --max_old_space_size=3584 NODE_OPTIONS: --max_old_space_size=3584
WEBPACK_VENDOR_DLL: "true" WEBPACK_VENDOR_DLL: "true"
cache: cache:
key: "assets-compile:v9" key: "assets-compile:test:v1"
artifacts: artifacts:
expire_in: 7d expire_in: 7d
paths: paths:
- node_modules - node_modules
- public/assets - public/assets
- assets-compile.log
compile-assets pull-push-cache: compile-assets pull-push-cache:
extends: extends:
...@@ -100,7 +109,7 @@ compile-assets pull-push-cache as-if-foss: ...@@ -100,7 +109,7 @@ compile-assets pull-push-cache as-if-foss:
- .as-if-foss - .as-if-foss
cache: cache:
policy: pull-push policy: pull-push
key: "assets-compile:v9:foss" key: "assets-compile:test:as-if-foss:v1"
compile-assets pull-cache: compile-assets pull-cache:
extends: extends:
...@@ -116,7 +125,7 @@ compile-assets pull-cache as-if-foss: ...@@ -116,7 +125,7 @@ compile-assets pull-cache as-if-foss:
- .as-if-foss - .as-if-foss
cache: cache:
policy: pull policy: pull
key: "assets-compile:v9:foss" key: "assets-compile:test:as-if-foss:v1"
.frontend-fixtures-base: .frontend-fixtures-base:
extends: extends:
......
...@@ -55,5 +55,9 @@ package-and-qa: ...@@ -55,5 +55,9 @@ package-and-qa:
extends: extends:
- .package-and-qa-base - .package-and-qa-base
- .qa:rules:package-and-qa - .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 allow_failure: true
...@@ -327,6 +327,7 @@ export default { ...@@ -327,6 +327,7 @@ export default {
</gl-table> </gl-table>
<gl-pagination <gl-pagination
v-if="!isLoading"
ref="pagination" ref="pagination"
v-model="currentPage" v-model="currentPage"
:per-page="tagsPagination.perPage" :per-page="tagsPagination.perPage"
......
...@@ -48,14 +48,7 @@ class Import::GitlabProjectsController < Import::BaseController ...@@ -48,14 +48,7 @@ class Import::GitlabProjectsController < Import::BaseController
private private
def file_is_valid? 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) return false unless project_params[:file].is_a?(::UploadedFile)
else
return false unless project_params[:file] && project_params[:file].respond_to?(:read)
end
filename = project_params[:file].original_filename filename = project_params[:file].original_filename
...@@ -75,8 +68,4 @@ class Import::GitlabProjectsController < Import::BaseController ...@@ -75,8 +68,4 @@ class Import::GitlabProjectsController < Import::BaseController
def whitelist_query_limiting def whitelist_query_limiting
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-foss/issues/42437') Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-foss/issues/42437')
end end
def with_workhorse_upload_acceleration?
request.headers[Gitlab::Workhorse::INTERNAL_API_REQUEST_HEADER].present?
end
end end
...@@ -598,13 +598,9 @@ module Ci ...@@ -598,13 +598,9 @@ module Ci
end end
def merge_request def merge_request
return @merge_request if defined?(@merge_request) strong_memoize(:merge_request) do
@merge_request ||=
begin
merge_requests = MergeRequest.includes(:latest_merge_request_diff) merge_requests = MergeRequest.includes(:latest_merge_request_diff)
.where(source_branch: ref, .where(source_branch: ref, source_project: pipeline.project)
source_project: pipeline.project)
.reorder(iid: :desc) .reorder(iid: :desc)
merge_requests.find do |merge_request| merge_requests.find do |merge_request|
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
%head{ prefix: "og: http://ogp.me/ns#" } %head{ prefix: "og: http://ogp.me/ns#" }
%meta{ charset: "utf-8" } %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: 'dns-prefetch', href: ActionController::Base.asset_host }
%link{ rel: 'preconnnect', href: ActionController::Base.asset_host, crossorigin: '' } %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 ...@@ -77,7 +77,7 @@ module Gitlab
return false unless user return false unless user
Gitlab::SafeRequestStore.fetch(admin_mode_rs_key) do Gitlab::SafeRequestStore.fetch(admin_mode_rs_key) do
user.admin? && any_session_with_admin_mode? user.admin? && session_with_admin_mode?
end end
end end
...@@ -136,19 +136,10 @@ module Gitlab ...@@ -136,19 +136,10 @@ module Gitlab
@current_session ||= Gitlab::NamespacedSessionStore.new(SESSION_STORE_KEY) @current_session ||= Gitlab::NamespacedSessionStore.new(SESSION_STORE_KEY)
end end
def any_session_with_admin_mode? def session_with_admin_mode?
return true if bypass_session? 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| current_session_data.initiated? && current_session_data[ADMIN_MODE_START_TIME_KEY].to_i > MAX_ADMIN_MODE_TIME.ago.to_i
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
end end
def admin_mode_requested_in_grace_period? 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 :gitlab do
namespace :assets do namespace :assets do
desc 'GitLab | Assets | Compile all frontend assets' desc 'GitLab | Assets | Compile all frontend assets'
...@@ -8,9 +53,35 @@ namespace :gitlab do ...@@ -8,9 +53,35 @@ namespace :gitlab do
yarn:check yarn:check
gettext:po_to_json gettext:po_to_json
rake:assets:precompile rake:assets:precompile
webpack:compile gitlab:assets:compile_webpack_if_needed
gitlab:assets:fix_urls 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 end
desc 'GitLab | Assets | Clean up old compiled frontend assets' desc 'GitLab | Assets | Clean up old compiled frontend assets'
......
...@@ -3,90 +3,21 @@ ...@@ -3,90 +3,21 @@
require 'spec_helper' require 'spec_helper'
describe 'Group navbar' do describe 'Group navbar' do
let(:user) { create(:user) } include NavbarStructureHelper
let(:group) { create(:group) }
let(:analytics_nav_item) do include_context 'group navbar structure'
{
nav_item: _('Analytics'),
nav_sub_items: [
_('Contribution')
]
}
end
let(:structure) do let_it_be(:user) { create(:user) }
[ let_it_be(:group) { create(:group) }
{
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
it_behaves_like 'verified navigation bar' do
before do before do
group.add_maintainer(user) group.add_maintainer(user)
sign_in(user) sign_in(user)
visit group_path(group)
end
end end
if Gitlab.ee? it_behaves_like 'verified navigation bar' do
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 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) visit group_path(group)
end end
it_behaves_like 'verified navigation bar'
end
end end
end end
...@@ -3,112 +3,14 @@ ...@@ -3,112 +3,14 @@
require 'spec_helper' require 'spec_helper'
describe 'Project navbar' do describe 'Project navbar' do
let(:user) { create(:user) } include NavbarStructureHelper
let(:project) { create(:project, :repository) }
let(:analytics_nav_item) do include_context 'project navbar structure'
{
nav_item: _('Analytics'),
nav_sub_items: [
_('CI / CD'),
(_('Code Review') if Gitlab.ee?),
_('Repository'),
_('Value Stream')
]
}
end
let(:requirements_nav_item) do
{
nav_item: _('Requirements'),
nav_sub_items: [_('List')]
}
end
let(:structure) do let_it_be(:user) { create(:user) }
[ let_it_be(:project) { create(:project, :repository) }
{
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
before do before do
stub_licensed_features(requirements: false)
project.add_maintainer(user) project.add_maintainer(user)
sign_in(user) sign_in(user)
end end
...@@ -119,28 +21,19 @@ describe 'Project navbar' do ...@@ -119,28 +21,19 @@ describe 'Project navbar' do
end end
end end
if Gitlab.ee? context 'when pages are available' do
context 'when issues analytics is available' do
before do before do
stub_licensed_features(issues_analytics: true) allow(Gitlab.config.pages).to receive(:enabled).and_return(true)
analytics_nav_item[:nav_sub_items] << _('Issues')
analytics_nav_item[:nav_sub_items].sort!
visit project_path(project) insert_after_sub_nav_item(
end _('Operations'),
within: _('Settings'),
it_behaves_like 'verified navigation bar' new_sub_nav_item_name: _('Pages')
end )
context 'when requirements is available' do
before do
stub_licensed_features(requirements: true)
visit project_path(project) visit project_path(project)
end end
it_behaves_like 'verified navigation bar' it_behaves_like 'verified navigation bar'
end end
end
end end
...@@ -13,6 +13,9 @@ describe 'Projects > Snippets > User comments on a snippet', :js do ...@@ -13,6 +13,9 @@ describe 'Projects > Snippets > User comments on a snippet', :js do
sign_in(user) sign_in(user)
visit(project_snippet_path(project, snippet)) 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 end
it 'leaves a comment on a snippet' do it 'leaves a comment on a snippet' do
...@@ -34,7 +37,8 @@ describe 'Projects > Snippets > User comments on a snippet', :js do ...@@ -34,7 +37,8 @@ describe 'Projects > Snippets > User comments on a snippet', :js do
end end
it 'has zen mode' do it 'has zen mode' do
find('.js-zen-enter').click click_button 'Go full screen'
expect(page).to have_selector('.fullscreen') expect(page).to have_selector('.fullscreen')
end end
end end
...@@ -66,6 +66,10 @@ describe('Details Page', () => { ...@@ -66,6 +66,10 @@ describe('Details Page', () => {
it('does not have list items', () => { it('does not have list items', () => {
expect(findFirstRowItem('rowCheckbox').exists()).toBe(false); expect(findFirstRowItem('rowCheckbox').exists()).toBe(false);
}); });
it('does not show pagination', () => {
expect(findPagination().exists()).toBe(false);
});
}); });
describe('table', () => { describe('table', () => {
......
...@@ -151,13 +151,13 @@ describe Gitlab::Auth::CurrentUserMode, :do_not_mock_admin_mode, :request_store ...@@ -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]) allow(ActiveSession).to receive(:list_sessions).with(user).and_return([session, another_session])
end 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 Gitlab::Session.with_session(another_session) do
another_subject.request_admin_mode! another_subject.request_admin_mode!
another_subject.enable_admin_mode!(password: user.password) another_subject.enable_admin_mode!(password: user.password)
end end
expect(subject.admin_mode?).to be(true) expect(subject.admin_mode?).to be(false)
end end
end end
end end
......
...@@ -34,8 +34,6 @@ describe BugzillaService do ...@@ -34,8 +34,6 @@ describe BugzillaService do
end end
context 'overriding properties' do context 'overriding properties' do
let(:default_title) { 'JIRA' }
let(:default_description) { 'JiraService|Jira issue tracker' }
let(:url) { 'http://bugzilla.example.com' } let(:url) { 'http://bugzilla.example.com' }
let(:access_params) do let(:access_params) do
{ project_url: url, issues_url: url, new_issue_url: url } { project_url: url, issues_url: url, new_issue_url: url }
......
...@@ -3,62 +3,101 @@ ...@@ -3,62 +3,101 @@
require 'spec_helper' require 'spec_helper'
describe Import::GitlabProjectsController do 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(:namespace) { create(:namespace) }
let_it_be(:user) { namespace.owner } let_it_be(:user) { namespace.owner }
let(:file) { fixture_file_upload('spec/fixtures/project_export.tar.gz', 'text/plain') }
before do before do
sign_in(user) login_as(user)
end end
describe 'POST create' do describe 'POST create' do
context 'with an invalid path' do subject { upload_archive(file_upload, workhorse_headers, params) }
it 'redirects with an error' do
post :create, params: { namespace_id: namespace.id, path: '/test', file: file }
expect(flash[:alert]).to start_with('Project could not be imported') 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
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) expect(response).to have_gitlab_http_status(:found)
end 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 subject
post :create, params: { namespace_id: namespace.id, path: '../test', file: file }
expect(flash[:alert]).to start_with('Project could not be imported') expect(flash[:alert]).to start_with('Project could not be imported')
expect(response).to have_gitlab_http_status(:found) expect(response).to have_gitlab_http_status(:found)
end end
end end
end
context 'with a valid path' do context 'when request exceeds the rate limit' do
it 'redirects to the new project path' do before do
post :create, params: { namespace_id: namespace.id, path: 'test', file: file } 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) expect(response).to have_gitlab_http_status(:found)
end end
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 end
describe 'POST authorize' do def stub_import(namespace)
let(:workhorse_token) { JWT.encode({ 'iss' => 'gitlab-workhorse' }, Gitlab::Workhorse.secret, 'HS256') } expect_any_instance_of(ProjectImportState).to receive(:schedule)
expect(::Projects::CreateService)
before do .to receive(:new)
request.headers['GitLab-Workhorse'] = '1.0' .with(user, instance_of(ActionController::Parameters))
request.headers[Gitlab::Workhorse::INTERNAL_API_REQUEST_HEADER] = workhorse_token .and_call_original
end
end end
describe 'POST authorize' do
subject { post authorize_import_gitlab_project_path, headers: workhorse_headers }
it 'authorizes importing project with workhorse header' do it 'authorizes importing project with workhorse header' do
post :authorize, format: :json subject
expect(response).to have_gitlab_http_status(:ok) expect(response).to have_gitlab_http_status(:ok)
expect(response.content_type.to_s).to eq(Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE) 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 end
it 'rejects requests that bypassed gitlab-workhorse or have invalid header' do it 'rejects requests that bypassed gitlab-workhorse' do
request.headers[Gitlab::Workhorse::INTERNAL_API_REQUEST_HEADER] = 'INVALID_HEADER' 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 end
context 'when using remote storage' do context 'when using remote storage' do
...@@ -68,7 +107,7 @@ describe Import::GitlabProjectsController do ...@@ -68,7 +107,7 @@ describe Import::GitlabProjectsController do
end end
it 'responds with status 200, location of file remote store and object details' do 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).to have_gitlab_http_status(:ok)
expect(response.content_type.to_s).to eq(Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE) expect(response.content_type.to_s).to eq(Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE)
...@@ -87,7 +126,7 @@ describe Import::GitlabProjectsController do ...@@ -87,7 +126,7 @@ describe Import::GitlabProjectsController do
end end
it 'handles as a local file' do it 'handles as a local file' do
post :authorize, format: :json subject
expect(response).to have_gitlab_http_status(:ok) expect(response).to have_gitlab_http_status(:ok)
expect(response.content_type.to_s).to eq(Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE) 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 ...@@ -34,36 +34,23 @@ describe 'layouts/_head' do
expect(rendered).to match(%{content="foo&quot; http-equiv=&quot;refresh"}) expect(rendered).to match(%{content="foo&quot; http-equiv=&quot;refresh"})
end 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' } let(:asset_host) { 'http://assets' }
before do before do
stub_feature_flags(asset_host_prefetch: true)
allow(ActionController::Base).to receive(:asset_host).and_return(asset_host) allow(ActionController::Base).to receive(:asset_host).and_return(asset_host)
end end
it 'add a link dns-prefetch tag' do it 'adds a link dns-prefetch tag' do
render 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 expect(rendered).to match(%Q(<link href="#{asset_host}" rel="dns-prefetch">))
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)
end end
it 'not add a link dns-prefetch tag' do it 'adds a link preconnect tag' do
render 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
end end
......
...@@ -781,15 +781,15 @@ ...@@ -781,15 +781,15 @@
eslint-plugin-vue "^6.2.1" eslint-plugin-vue "^6.2.1"
vue-eslint-parser "^7.0.0" vue-eslint-parser "^7.0.0"
"@gitlab/svgs@^1.113.0": "@gitlab/svgs@^1.114.0":
version "1.113.0" version "1.114.0"
resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-1.113.0.tgz#0ea9cb3122a479f3ed4bb22943d68a9a38f69948" resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-1.114.0.tgz#ffee243fa540016c8198596686a46e3c459adb32"
integrity sha512-upT+sKEnnwZDU7vzI5VSyg2l6IOd/0Icm/MLae6po/nOGbf2vftkUVfbalzISAmk9eYTuJQ1sGmRWdKXPGy1cw== integrity sha512-r2tizWDx1fX2QbeXzU0Z5Fi9YS7TLIxt7K+vAnZxOeddgd5KdipCvhT/H7n9Oa9jLU4bMwGSrHZ1usCmCoWOnw==
"@gitlab/ui@^9.29.0": "@gitlab/ui@^9.31.1":
version "9.29.0" version "9.31.1"
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-9.29.0.tgz#2308aec1d3d837392eaaf9d441aecec4b695ed73" resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-9.31.1.tgz#53206aac643d79f8eddbc5715131bad5ffc1e412"
integrity sha512-zIY/aChWaU4UBlAjZ95PpBxgUd9VrGiXs9ujVU6Gbi+ZsHbpDvPlBHsHEG9isnUVBE2AD4GPqMLO8K9i+B9O4A== integrity sha512-MHBVIpVzUYPkr70ti21dTZbzzZttOidWZdN3TeZOdqYbjYg2ONujFBxOGSCNYcaMYr+1/wFtuVRL/JmMVGjJrg==
dependencies: dependencies:
"@babel/standalone" "^7.0.0" "@babel/standalone" "^7.0.0"
"@gitlab/vue-toasted" "^1.3.0" "@gitlab/vue-toasted" "^1.3.0"
......
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