Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
19325d74c2
commit
3748ae5cbb
|
@ -330,3 +330,6 @@ Dangerfile @gl-quality/eng-prod
|
|||
|
||||
[Workhorse]
|
||||
/workhorse/ @jacobvosmaer-gitlab @nick.thomas @nolith @patrickbajao
|
||||
|
||||
[Application Security]
|
||||
/lib/gitlab/content_security_policy/ @gitlab-com/gl-security/appsec
|
||||
|
|
|
@ -140,6 +140,7 @@ export default {
|
|||
</div>
|
||||
<div class="gl-p-2">
|
||||
<gl-button
|
||||
is-unsafe-link
|
||||
:href="codeDownloadUrl"
|
||||
:title="$options.i18n.downloadButton"
|
||||
icon="download"
|
||||
|
|
|
@ -68,7 +68,7 @@ export default {
|
|||
<local-storage-sync v-model="isExpanded" :storage-key="$options.localDrawerKey" as-json>
|
||||
<aside
|
||||
aria-live="polite"
|
||||
class="gl-fixed gl-right-0 gl-bg-gray-10 gl-shadow-drawer gl-transition-medium gl-border-l-solid gl-border-1 gl-border-gray-100 gl-h-full gl-z-index-9999 gl-overflow-y-auto"
|
||||
class="gl-fixed gl-right-0 gl-bg-gray-10 gl-shadow-drawer gl-transition-medium gl-border-l-solid gl-border-1 gl-border-gray-100 gl-h-full gl-z-index-3 gl-overflow-y-auto"
|
||||
:style="rootStyle"
|
||||
>
|
||||
<gl-button
|
||||
|
|
|
@ -15,7 +15,7 @@ export default {
|
|||
mixins: [timeagoMixin],
|
||||
props: {
|
||||
time: {
|
||||
type: String,
|
||||
type: [String, Number],
|
||||
required: true,
|
||||
},
|
||||
tooltipPlacement: {
|
||||
|
|
|
@ -372,7 +372,7 @@ $system-note-svg-size: 16px;
|
|||
top: $mr-tabs-height + $header-height;
|
||||
|
||||
.with-performance-bar & {
|
||||
top: 126px;
|
||||
top: 123px;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2539,7 +2539,7 @@ class Project < ApplicationRecord
|
|||
def default_branch_or_main
|
||||
return default_branch if default_branch
|
||||
|
||||
Feature.enabled?(:main_branch_over_master, self, default_enabled: :yaml) ? 'main' : 'master'
|
||||
Gitlab::DefaultBranch.value(project: self)
|
||||
end
|
||||
|
||||
def ci_config_path_or_default
|
||||
|
|
|
@ -20,7 +20,6 @@ class Snippet < ApplicationRecord
|
|||
extend ::Gitlab::Utils::Override
|
||||
|
||||
MAX_FILE_COUNT = 10
|
||||
MASTER_BRANCH = 'master'
|
||||
|
||||
cache_markdown_field :title, pipeline: :single_line
|
||||
cache_markdown_field :description
|
||||
|
@ -316,19 +315,19 @@ class Snippet < ApplicationRecord
|
|||
|
||||
override :default_branch
|
||||
def default_branch
|
||||
super || MASTER_BRANCH
|
||||
super || Gitlab::DefaultBranch.value(project: project)
|
||||
end
|
||||
|
||||
def repository_storage
|
||||
snippet_repository&.shard_name || Repository.pick_storage_shard
|
||||
end
|
||||
|
||||
# Repositories are created by default with the `master` branch.
|
||||
# Repositories are created with a default branch. This branch
|
||||
# can be different from the default branch set in the platform.
|
||||
# This method changes the `HEAD` file to point to the existing
|
||||
# default branch in case it's not master.
|
||||
# default branch in case it's different.
|
||||
def change_head_to_default_branch
|
||||
return unless repository.exists?
|
||||
return if default_branch == MASTER_BRANCH
|
||||
# All snippets must have at least 1 file. Therefore, if
|
||||
# `HEAD` is empty is because it's pointing to the wrong
|
||||
# default branch
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Reschedule DropInvalidVulnerabilities and track jobs
|
||||
merge_request: 61491
|
||||
author:
|
||||
type: other
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Lowers the z-indexing of the pipeline drawer
|
||||
merge_request: 61683
|
||||
author:
|
||||
type: other
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Omit trailing slash when proxying pre-authorized routes with no suffix
|
||||
merge_request: 61638
|
||||
author:
|
||||
type: fixed
|
|
@ -0,0 +1,25 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ScheduleDropInvalidVulnerabilities2 < ActiveRecord::Migration[6.0]
|
||||
include Gitlab::Database::MigrationHelpers
|
||||
|
||||
MIGRATION = 'DropInvalidVulnerabilities'
|
||||
DELAY_INTERVAL = 2.minutes.to_i
|
||||
BATCH_SIZE = 10_000
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
queue_background_migration_jobs_by_range_at_intervals(
|
||||
define_batchable_model('vulnerabilities'),
|
||||
MIGRATION,
|
||||
DELAY_INTERVAL,
|
||||
batch_size: BATCH_SIZE,
|
||||
track_jobs: true
|
||||
)
|
||||
end
|
||||
|
||||
def down
|
||||
# no-op
|
||||
end
|
||||
end
|
|
@ -0,0 +1 @@
|
|||
def18f68ad71a1581452d52d331d2fd99ec9a3eb9b8e2fd111277eda498169fa
|
|
@ -21,6 +21,17 @@ class Gitlab::BackgroundMigration::DropInvalidVulnerabilities
|
|||
.left_joins(:findings)
|
||||
.where(vulnerability_occurrences: { vulnerability_id: nil })
|
||||
.delete_all
|
||||
|
||||
mark_job_as_succeeded(start_id, end_id)
|
||||
end
|
||||
# rubocop: enable CodeReuse/ActiveRecord
|
||||
|
||||
private
|
||||
|
||||
def mark_job_as_succeeded(*arguments)
|
||||
Gitlab::Database::BackgroundMigrationJob.mark_all_as_succeeded(
|
||||
'DropInvalidVulnerabilities',
|
||||
arguments
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Class is used while we're migrating from master to main
|
||||
module Gitlab
|
||||
module DefaultBranch
|
||||
def self.value(project: nil)
|
||||
Feature.enabled?(:main_branch_over_master, project, default_enabled: :yaml) ? 'main' : 'master'
|
||||
end
|
||||
end
|
||||
end
|
|
@ -5054,25 +5054,22 @@ msgstr ""
|
|||
msgid "BillingPlan|Upgrade for free"
|
||||
msgstr ""
|
||||
|
||||
msgid "Billings|As a user on a free or trial namespace, you'll need to verify your account with a credit card to run pipelines. This is required to help prevent cryptomining attacks on GitLab infrastructure. %{strongStart}GitLab will not charge or store your credit card, it will only be used for validation.%{strongEnd}"
|
||||
msgid "Billings|To use free pipeline minutes, you'll need to validate your account with a credit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge or store your credit card, it will only be used for validation.%{strongEnd}"
|
||||
msgstr ""
|
||||
|
||||
msgid "Billings|To discourage and reduce abuse GitLab will require some users to provide a valid credit card to use free pipeline minutes on GitLab.com. To use free pipeline minutes, you will need to validate your account with a credit card. %{strongStart}GitLab will not add permanent charges to your credit card as we will only use it for validation.%{strongEnd}"
|
||||
msgid "Billings|User successfully validated"
|
||||
msgstr ""
|
||||
|
||||
msgid "Billings|User Verification Required"
|
||||
msgid "Billings|User validation required"
|
||||
msgstr ""
|
||||
|
||||
msgid "Billings|User successfully verified"
|
||||
msgid "Billings|Validate account"
|
||||
msgstr ""
|
||||
|
||||
msgid "Billings|Verify User Account"
|
||||
msgid "Billings|Validate user account"
|
||||
msgstr ""
|
||||
|
||||
msgid "Billings|Verify account"
|
||||
msgstr ""
|
||||
|
||||
msgid "Billings|Your user account has been successfully verified. You will now be able to run pipelines on any free or trial namespace."
|
||||
msgid "Billings|Your user account has been successfully validated. You can now use free pipeline minutes."
|
||||
msgstr ""
|
||||
|
||||
msgid "Billing|An email address is only visible for users with public emails."
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
"@gitlab/favicon-overlay": "2.0.0",
|
||||
"@gitlab/svgs": "1.195.0",
|
||||
"@gitlab/tributejs": "1.0.0",
|
||||
"@gitlab/ui": "29.21.0",
|
||||
"@gitlab/ui": "29.23.0",
|
||||
"@gitlab/visual-review-tools": "1.6.1",
|
||||
"@rails/actioncable": "^6.0.3-4",
|
||||
"@rails/ujs": "^6.0.3-4",
|
||||
|
|
|
@ -94,7 +94,10 @@ describe('Pipelines', () => {
|
|||
beforeAll(() => {
|
||||
origWindowLocation = window.location;
|
||||
delete window.location;
|
||||
window.location = { search: '' };
|
||||
window.location = {
|
||||
search: '',
|
||||
protocol: 'https:',
|
||||
};
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
|
|
|
@ -1,28 +1,36 @@
|
|||
import { shallowMount } from '@vue/test-utils';
|
||||
|
||||
import timezoneMock from 'timezone-mock';
|
||||
import { formatDate, getTimeago } from '~/lib/utils/datetime_utility';
|
||||
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
|
||||
|
||||
describe('Time ago with tooltip component', () => {
|
||||
let vm;
|
||||
|
||||
const buildVm = (propsData = {}, scopedSlots = {}) => {
|
||||
vm = shallowMount(TimeAgoTooltip, {
|
||||
propsData,
|
||||
scopedSlots,
|
||||
});
|
||||
};
|
||||
const timestamp = '2017-05-08T14:57:39.781Z';
|
||||
const timeAgoTimestamp = getTimeago().format(timestamp);
|
||||
|
||||
const defaultProps = {
|
||||
time: timestamp,
|
||||
};
|
||||
|
||||
const buildVm = (props = {}, scopedSlots = {}) => {
|
||||
vm = shallowMount(TimeAgoTooltip, {
|
||||
propsData: {
|
||||
...defaultProps,
|
||||
...props,
|
||||
},
|
||||
scopedSlots,
|
||||
});
|
||||
};
|
||||
|
||||
afterEach(() => {
|
||||
vm.destroy();
|
||||
timezoneMock.unregister();
|
||||
});
|
||||
|
||||
it('should render timeago with a bootstrap tooltip', () => {
|
||||
buildVm({
|
||||
time: timestamp,
|
||||
});
|
||||
buildVm();
|
||||
|
||||
expect(vm.attributes('title')).toEqual(formatDate(timestamp));
|
||||
expect(vm.text()).toEqual(timeAgoTimestamp);
|
||||
|
@ -30,7 +38,6 @@ describe('Time ago with tooltip component', () => {
|
|||
|
||||
it('should render provided html class', () => {
|
||||
buildVm({
|
||||
time: timestamp,
|
||||
cssClass: 'foo',
|
||||
});
|
||||
|
||||
|
@ -38,14 +45,58 @@ describe('Time ago with tooltip component', () => {
|
|||
});
|
||||
|
||||
it('should render with the datetime attribute', () => {
|
||||
buildVm({ time: timestamp });
|
||||
buildVm();
|
||||
|
||||
expect(vm.attributes('datetime')).toEqual(timestamp);
|
||||
});
|
||||
|
||||
it('should render provided scope content with the correct timeAgo string', () => {
|
||||
buildVm({ time: timestamp }, { default: `<span>The time is {{ props.timeAgo }}</span>` });
|
||||
buildVm(null, { default: `<span>The time is {{ props.timeAgo }}</span>` });
|
||||
|
||||
expect(vm.text()).toEqual(`The time is ${timeAgoTimestamp}`);
|
||||
});
|
||||
|
||||
describe('number based timestamps', () => {
|
||||
// Store a date object before we mock the TZ
|
||||
const date = new Date();
|
||||
|
||||
describe('with default TZ', () => {
|
||||
beforeEach(() => {
|
||||
buildVm({ time: date.getTime() });
|
||||
});
|
||||
|
||||
it('handled correctly', () => {
|
||||
expect(vm.text()).toEqual(getTimeago().format(date.getTime()));
|
||||
});
|
||||
});
|
||||
|
||||
describe.each`
|
||||
timezone | offset
|
||||
${'US/Pacific'} | ${420}
|
||||
${'US/Eastern'} | ${240}
|
||||
${'Brazil/East'} | ${180}
|
||||
${'UTC'} | ${-0}
|
||||
${'Europe/London'} | ${-60}
|
||||
`('with different client vs server TZ', ({ timezone, offset }) => {
|
||||
let tzDate;
|
||||
|
||||
beforeEach(() => {
|
||||
timezoneMock.register(timezone);
|
||||
// Date object with mocked TZ
|
||||
tzDate = new Date();
|
||||
buildVm({ time: date.getTime() });
|
||||
});
|
||||
|
||||
it('the date object should have correct timezones', () => {
|
||||
expect(tzDate.getTimezoneOffset()).toBe(offset);
|
||||
});
|
||||
|
||||
it('timeago should handled the date correctly', () => {
|
||||
// getTime() should always handle the TZ, which allows for us to validate the date objects represent
|
||||
// the same date and time regardless of the TZ.
|
||||
expect(vm.text()).toEqual(getTimeago().format(date.getTime()));
|
||||
expect(vm.text()).toEqual(getTimeago().format(tzDate.getTime()));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -201,4 +201,25 @@ RSpec.describe Banzai::Filter::References::UserReferenceFilter do
|
|||
expect(filter.send(:usernames)).to eq([user.username])
|
||||
end
|
||||
end
|
||||
|
||||
context 'checking N+1' do
|
||||
let(:user2) { create(:user) }
|
||||
let(:group) { create(:group) }
|
||||
let(:reference2) { user2.to_reference }
|
||||
let(:reference3) { group.to_reference }
|
||||
|
||||
it 'does not have N+1 per multiple user references', :use_sql_query_cache do
|
||||
markdown = "#{reference}"
|
||||
|
||||
control_count = ActiveRecord::QueryRecorder.new(skip_cached: false) do
|
||||
reference_filter(markdown)
|
||||
end.count
|
||||
|
||||
markdown = "#{reference} @qwertyuiopzx @wertyuio @ertyu @rtyui #{reference2} #{reference3}"
|
||||
|
||||
expect do
|
||||
reference_filter(markdown)
|
||||
end.not_to exceed_all_query_limit(control_count)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::BackgroundMigration::DropInvalidVulnerabilities, schema: 20201110110454 do
|
||||
let_it_be(:background_migration_jobs) { table(:background_migration_jobs) }
|
||||
let_it_be(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') }
|
||||
let_it_be(:users) { table(:users) }
|
||||
let_it_be(:user) { create_user! }
|
||||
|
@ -47,16 +48,34 @@ RSpec.describe Gitlab::BackgroundMigration::DropInvalidVulnerabilities, schema:
|
|||
)
|
||||
end
|
||||
|
||||
subject { described_class.new.perform(vulnerability_with_finding.id, vulnerability_without_finding.id) }
|
||||
let(:succeeded_status) { 1 }
|
||||
let(:pending_status) { 0 }
|
||||
|
||||
it 'drops Vulnerabilities without any Findings' do
|
||||
expect(vulnerabilities.pluck(:id)).to eq([vulnerability_with_finding.id, vulnerability_without_finding.id])
|
||||
|
||||
expect { subject }.to change(vulnerabilities, :count).by(-1)
|
||||
expect { subject.perform(vulnerability_with_finding.id, vulnerability_without_finding.id) }.to change(vulnerabilities, :count).by(-1)
|
||||
|
||||
expect(vulnerabilities.pluck(:id)).to eq([vulnerability_with_finding.id])
|
||||
end
|
||||
|
||||
it 'marks jobs as done' do
|
||||
background_migration_jobs.create!(
|
||||
class_name: 'DropInvalidVulnerabilities',
|
||||
arguments: [vulnerability_with_finding.id, vulnerability_with_finding.id]
|
||||
)
|
||||
|
||||
background_migration_jobs.create!(
|
||||
class_name: 'DropInvalidVulnerabilities',
|
||||
arguments: [vulnerability_without_finding.id, vulnerability_without_finding.id]
|
||||
)
|
||||
|
||||
subject.perform(vulnerability_with_finding.id, vulnerability_with_finding.id)
|
||||
|
||||
expect(background_migration_jobs.first.status).to eq(succeeded_status)
|
||||
expect(background_migration_jobs.second.status).to eq(pending_status)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def create_vulnerability!(project_id:, author_id:, title: 'test', severity: 7, confidence: 7, report_type: 0)
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
# We disabled main_branch_over_master feature for tests
|
||||
# In order to have consistent branch usages
|
||||
# When we migrate the branch name to main, we can enable it
|
||||
RSpec.describe Gitlab::DefaultBranch do
|
||||
context 'main_branch_over_master is enabled' do
|
||||
before do
|
||||
stub_feature_flags(main_branch_over_master: true)
|
||||
end
|
||||
|
||||
it 'returns main' do
|
||||
expect(described_class.value).to eq('main')
|
||||
end
|
||||
end
|
||||
|
||||
context 'main_branch_over_master is disabled' do
|
||||
it 'returns master' do
|
||||
expect(described_class.value).to eq('master')
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,120 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
require Rails.root.join('db', 'post_migrate', '20210511142748_schedule_drop_invalid_vulnerabilities2.rb')
|
||||
|
||||
RSpec.describe ScheduleDropInvalidVulnerabilities2, :migration do
|
||||
let_it_be(:background_migration_jobs) { table(:background_migration_jobs) }
|
||||
|
||||
let_it_be(:namespace) { table(:namespaces).create!(name: 'user', path: 'user') }
|
||||
let_it_be(:users) { table(:users) }
|
||||
let_it_be(:user) { create_user! }
|
||||
let_it_be(:project) { table(:projects).create!(id: 123, namespace_id: namespace.id) }
|
||||
|
||||
let_it_be(:scanners) { table(:vulnerability_scanners) }
|
||||
let_it_be(:scanner) { scanners.create!(project_id: project.id, external_id: 'test 1', name: 'test scanner 1') }
|
||||
let_it_be(:different_scanner) { scanners.create!(project_id: project.id, external_id: 'test 2', name: 'test scanner 2') }
|
||||
|
||||
let_it_be(:vulnerabilities) { table(:vulnerabilities) }
|
||||
let_it_be(:vulnerability_with_finding) do
|
||||
create_vulnerability!(
|
||||
project_id: project.id,
|
||||
author_id: user.id
|
||||
)
|
||||
end
|
||||
|
||||
let_it_be(:vulnerability_without_finding) do
|
||||
create_vulnerability!(
|
||||
project_id: project.id,
|
||||
author_id: user.id
|
||||
)
|
||||
end
|
||||
|
||||
let_it_be(:vulnerability_identifiers) { table(:vulnerability_identifiers) }
|
||||
let_it_be(:primary_identifier) do
|
||||
vulnerability_identifiers.create!(
|
||||
project_id: project.id,
|
||||
external_type: 'uuid-v5',
|
||||
external_id: 'uuid-v5',
|
||||
fingerprint: '7e394d1b1eb461a7406d7b1e08f057a1cf11287a',
|
||||
name: 'Identifier for UUIDv5')
|
||||
end
|
||||
|
||||
let_it_be(:vulnerabilities_findings) { table(:vulnerability_occurrences) }
|
||||
let_it_be(:finding) do
|
||||
create_finding!(
|
||||
vulnerability_id: vulnerability_with_finding.id,
|
||||
project_id: project.id,
|
||||
scanner_id: scanner.id,
|
||||
primary_identifier_id: primary_identifier.id
|
||||
)
|
||||
end
|
||||
|
||||
before do
|
||||
stub_const("#{described_class}::BATCH_SIZE", 1)
|
||||
end
|
||||
|
||||
around do |example|
|
||||
freeze_time { Sidekiq::Testing.fake! { example.run } }
|
||||
end
|
||||
|
||||
it 'schedules background migrations' do
|
||||
migrate!
|
||||
|
||||
expect(background_migration_jobs.count).to eq(2)
|
||||
expect(background_migration_jobs.first.arguments).to eq([vulnerability_with_finding.id, vulnerability_with_finding.id])
|
||||
expect(background_migration_jobs.second.arguments).to eq([vulnerability_without_finding.id, vulnerability_without_finding.id])
|
||||
|
||||
expect(BackgroundMigrationWorker.jobs.size).to eq(2)
|
||||
expect(described_class::MIGRATION).to be_scheduled_delayed_migration(2.minutes, vulnerability_with_finding.id, vulnerability_with_finding.id)
|
||||
expect(described_class::MIGRATION).to be_scheduled_delayed_migration(4.minutes, vulnerability_without_finding.id, vulnerability_without_finding.id)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def create_vulnerability!(project_id:, author_id:, title: 'test', severity: 7, confidence: 7, report_type: 0)
|
||||
vulnerabilities.create!(
|
||||
project_id: project_id,
|
||||
author_id: author_id,
|
||||
title: title,
|
||||
severity: severity,
|
||||
confidence: confidence,
|
||||
report_type: report_type
|
||||
)
|
||||
end
|
||||
|
||||
# rubocop:disable Metrics/ParameterLists
|
||||
def create_finding!(
|
||||
vulnerability_id:, project_id:, scanner_id:, primary_identifier_id:,
|
||||
name: "test", severity: 7, confidence: 7, report_type: 0,
|
||||
project_fingerprint: '123qweasdzxc', location_fingerprint: 'test',
|
||||
metadata_version: 'test', raw_metadata: 'test', uuid: 'test')
|
||||
vulnerabilities_findings.create!(
|
||||
vulnerability_id: vulnerability_id,
|
||||
project_id: project_id,
|
||||
name: name,
|
||||
severity: severity,
|
||||
confidence: confidence,
|
||||
report_type: report_type,
|
||||
project_fingerprint: project_fingerprint,
|
||||
scanner_id: scanner_id,
|
||||
primary_identifier_id: primary_identifier_id,
|
||||
location_fingerprint: location_fingerprint,
|
||||
metadata_version: metadata_version,
|
||||
raw_metadata: raw_metadata,
|
||||
uuid: uuid
|
||||
)
|
||||
end
|
||||
# rubocop:enable Metrics/ParameterLists
|
||||
|
||||
def create_user!(name: "Example User", email: "user@example.com", user_type: nil)
|
||||
users.create!(
|
||||
name: name,
|
||||
email: email,
|
||||
username: name,
|
||||
projects_limit: 0,
|
||||
user_type: user_type,
|
||||
confirmed_at: Time.current
|
||||
)
|
||||
end
|
||||
end
|
|
@ -6923,11 +6923,6 @@ RSpec.describe Project, factory_default: :keep do
|
|||
describe '#default_branch_or_main' do
|
||||
let(:project) { create(:project, :repository) }
|
||||
|
||||
before do
|
||||
# Stubbing it as true since the FF disabled for tests globally
|
||||
stub_feature_flags(main_branch_over_master: true)
|
||||
end
|
||||
|
||||
it 'returns default branch' do
|
||||
expect(project.default_branch_or_main).to eq(project.default_branch)
|
||||
end
|
||||
|
@ -6935,18 +6930,8 @@ RSpec.describe Project, factory_default: :keep do
|
|||
context 'when default branch is nil' do
|
||||
let(:project) { create(:project, :empty_repo) }
|
||||
|
||||
it 'returns main' do
|
||||
expect(project.default_branch_or_main).to eq('main')
|
||||
end
|
||||
|
||||
context 'main_branch_over_master is disabled' do
|
||||
before do
|
||||
stub_feature_flags(main_branch_over_master: false)
|
||||
end
|
||||
|
||||
it 'returns master' do
|
||||
expect(project.default_branch_or_main).to eq('master')
|
||||
end
|
||||
it 'returns Gitlab::DefaultBranch.value' do
|
||||
expect(project.default_branch_or_main).to eq(Gitlab::DefaultBranch.value)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -826,18 +826,6 @@ RSpec.describe Snippet do
|
|||
allow(Gitlab::CurrentSettings).to receive(:default_branch_name).and_return(default_branch)
|
||||
end
|
||||
|
||||
context 'when default branch in settings is "master"' do
|
||||
let(:default_branch) { 'master' }
|
||||
|
||||
it 'does nothing' do
|
||||
expect(File.read(head_path).squish).to eq 'ref: refs/heads/master'
|
||||
|
||||
expect(snippet.repository.raw_repository).not_to receive(:write_ref)
|
||||
|
||||
subject
|
||||
end
|
||||
end
|
||||
|
||||
context 'when default branch in settings is different from "master"' do
|
||||
let(:default_branch) { 'main' }
|
||||
|
||||
|
|
|
@ -168,7 +168,10 @@ func singleJoiningSlash(a, b string) string {
|
|||
|
||||
// joinURLPath is taken from reverseproxy.go:joinURLPath
|
||||
func joinURLPath(a *url.URL, b string) (path string, rawpath string) {
|
||||
if a.RawPath == "" && b == "" {
|
||||
// Avoid adding a trailing slash if the suffix is empty
|
||||
if b == "" {
|
||||
return a.Path, a.RawPath
|
||||
} else if a.RawPath == "" {
|
||||
return singleJoiningSlash(a.Path, b), ""
|
||||
}
|
||||
|
||||
|
|
|
@ -536,7 +536,11 @@ func TestApiContentTypeBlock(t *testing.T) {
|
|||
func TestAPIFalsePositivesAreProxied(t *testing.T) {
|
||||
goodResponse := []byte(`<html></html>`)
|
||||
ts := testhelper.TestServerWithHandler(regexp.MustCompile(`.`), func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Header.Get(secret.RequestHeader) != "" && r.Method != "GET" {
|
||||
url := r.URL.String()
|
||||
if url[len(url)-1] == '/' {
|
||||
w.WriteHeader(500)
|
||||
w.Write([]byte("PreAuthorize request included a trailing slash"))
|
||||
} else if r.Header.Get(secret.RequestHeader) != "" && r.Method != "GET" {
|
||||
w.WriteHeader(500)
|
||||
w.Write([]byte("non-GET request went through PreAuthorize handler"))
|
||||
} else {
|
||||
|
|
|
@ -907,10 +907,10 @@
|
|||
resolved "https://registry.yarnpkg.com/@gitlab/tributejs/-/tributejs-1.0.0.tgz#672befa222aeffc83e7d799b0500a7a4418e59b8"
|
||||
integrity sha512-nmKw1+hB6MHvlmPz63yPwVs1qQkycHwsKgxpEbzmky16Y6mL4EJMk3w1b8QlOAF/AIAzjCERPhe/R4MJiohbZw==
|
||||
|
||||
"@gitlab/ui@29.21.0":
|
||||
version "29.21.0"
|
||||
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-29.21.0.tgz#f91169d693bc92109deadc412cf6ed76a8ae07ad"
|
||||
integrity sha512-fAqhQjLXsl6JRM56NewFqtYowzjvne7IsM6F+aD4C/9OF9u81bXfa5do1o5usl030Hz9e8+PTwkXWwLTe0Nz8w==
|
||||
"@gitlab/ui@29.23.0":
|
||||
version "29.23.0"
|
||||
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-29.23.0.tgz#cf0bf2ed85c679a618f0f78d7f5d4e4346663b55"
|
||||
integrity sha512-ELMHentJ9v5WXlAAuSr5s5kYu8KW710N4qCnzdt09g+McSsvXUhOx2ltM0d4rZe+TZwgwAUndwCUDP+dHqDtrA==
|
||||
dependencies:
|
||||
"@babel/standalone" "^7.0.0"
|
||||
"@gitlab/vue-toasted" "^1.3.0"
|
||||
|
|
Loading…
Reference in New Issue