Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-03-11 15:07:48 +00:00
parent e105f6b881
commit e46506bcc3
31 changed files with 372 additions and 88 deletions

View File

@ -479,7 +479,7 @@ gem 'ssh_data', '~> 1.2'
gem 'spamcheck', '~> 0.1.0'
# Gitaly GRPC protocol definitions
gem 'gitaly', '~> 14.9.0.pre.rc2'
gem 'gitaly', '~> 14.9.0.pre.rc3'
# KAS GRPC protocol definitions
gem 'kas-grpc', '~> 0.0.2'

View File

@ -455,7 +455,7 @@ GEM
rails (>= 3.2.0)
git (1.7.0)
rchardet (~> 1.8)
gitaly (14.9.0.pre.rc2)
gitaly (14.9.0.pre.rc3)
grpc (~> 1.0)
github-markup (1.7.0)
gitlab (4.16.1)
@ -1486,7 +1486,7 @@ DEPENDENCIES
gettext (~> 3.3)
gettext_i18n_rails (~> 1.8.0)
gettext_i18n_rails_js (~> 1.3)
gitaly (~> 14.9.0.pre.rc2)
gitaly (~> 14.9.0.pre.rc3)
github-markup (~> 1.7.0)
gitlab-chronic (~> 0.10.5)
gitlab-dangerfiles (~> 2.10.2)

View File

@ -0,0 +1,84 @@
<script>
import { GlModal, GlSprintf } from '@gitlab/ui';
import { __ } from '~/locale';
import csrf from '~/lib/utils/csrf';
export default {
components: {
GlModal,
GlSprintf,
},
data() {
return {
name: '',
path: '',
buttons: [],
};
},
mounted() {
this.buttons = document.querySelectorAll('.js-application-delete-button');
this.buttons.forEach((button) => button.addEventListener('click', this.buttonEvent));
},
destroy() {
this.buttons.forEach((button) => button.removeEventListener('click', this.buttonEvent));
},
methods: {
buttonEvent(e) {
e.preventDefault();
this.show(e.target.dataset);
},
show(dataset) {
const { name, path } = dataset;
this.name = name;
this.path = path;
this.$refs.deleteModal.show();
},
deleteApplication() {
this.$refs.deleteForm.submit();
},
},
i18n: {
destroy: __('Destroy'),
title: __('Confirm destroy application'),
body: __('Are you sure that you want to destroy %{application}'),
},
modal: {
actionPrimary: {
text: __('Destroy'),
attributes: {
variant: 'danger',
},
},
actionSecondary: {
text: __('Cancel'),
attributes: {
variant: 'default',
},
},
},
csrf,
};
</script>
<template>
<gl-modal
ref="deleteModal"
:title="$options.i18n.title"
:action-primary="$options.modal.actionPrimary"
:action-secondary="$options.modal.actionSecondary"
modal-id="delete-application-modal"
size="sm"
@primary="deleteApplication"
><gl-sprintf :message="$options.i18n.body">
<template #application>
<strong>{{ name }}</strong>
</template></gl-sprintf
>
<form ref="deleteForm" method="post" :action="path">
<input type="hidden" name="_method" value="delete" />
<input type="hidden" name="authenticity_token" :value="$options.csrf.token" />
</form>
</gl-modal>
</template>

View File

@ -0,0 +1,15 @@
import Vue from 'vue';
import DeleteApplication from './components/delete_application.vue';
export default () => {
const el = document.querySelector('.js-application-delete-modal');
if (!el) return false;
return new Vue({
el,
render(h) {
return h(DeleteApplication);
},
});
};

View File

@ -0,0 +1,3 @@
import initApplicationDeleteButtons from '~/admin/applications';
initApplicationDeleteButtons();

View File

@ -222,14 +222,12 @@ export const securityFeatures = [
helpPath: COVERAGE_FUZZING_HELP_PATH,
configurationHelpPath: COVERAGE_FUZZING_CONFIG_HELP_PATH,
type: REPORT_TYPE_COVERAGE_FUZZING,
secondary: gon?.features?.corpusManagementUi
? {
type: REPORT_TYPE_CORPUS_MANAGEMENT,
name: CORPUS_MANAGEMENT_NAME,
description: CORPUS_MANAGEMENT_DESCRIPTION,
configurationText: CORPUS_MANAGEMENT_CONFIG_TEXT,
}
: {},
secondary: {
type: REPORT_TYPE_CORPUS_MANAGEMENT,
name: CORPUS_MANAGEMENT_NAME,
description: CORPUS_MANAGEMENT_DESCRIPTION,
configurationText: CORPUS_MANAGEMENT_CONFIG_TEXT,
},
},
];

View File

@ -114,7 +114,7 @@ export default {
class="gl-display-inline-block"
>
<attention-requested-toggle
v-if="showVerticalList && user.can_update_merge_request"
v-if="showVerticalList"
:user="user"
type="assignee"
@toggle-attention-requested="toggleAttentionRequested"

View File

@ -8,6 +8,8 @@ export default {
attentionRequestedReviewer: __('Request attention to review'),
attentionRequestedAssignee: __('Request attention'),
removeAttentionRequested: __('Remove attention request'),
attentionRequestedNoPermission: __('Attention requested'),
noAttentionRequestedNoPermission: __('No attention request'),
},
components: {
GlButton,
@ -33,17 +35,25 @@ export default {
computed: {
tooltipTitle() {
if (this.user.attention_requested) {
return this.$options.i18n.removeAttentionRequested;
if (this.user.can_update_merge_request) {
return this.$options.i18n.removeAttentionRequested;
}
return this.$options.i18n.attentionRequestedNoPermission;
}
return this.type === 'reviewer'
? this.$options.i18n.attentionRequestedReviewer
: this.$options.i18n.attentionRequestedAssignee;
if (this.user.can_update_merge_request) {
return this.type === 'reviewer'
? this.$options.i18n.attentionRequestedReviewer
: this.$options.i18n.attentionRequestedAssignee;
}
return this.$options.i18n.noAttentionRequestedNoPermission;
},
},
methods: {
toggleAttentionRequired() {
if (this.loading) return;
if (this.loading || !this.user.can_update_merge_request) return;
this.$root.$emit(BV_HIDE_TOOLTIP);
this.loading = true;
@ -60,12 +70,13 @@ export default {
</script>
<template>
<span v-gl-tooltip.left.viewport="tooltipTitle">
<span v-gl-tooltip.left.viewport="tooltipTitle" class="gl-display-inline-block">
<gl-button
:loading="loading"
:variant="user.attention_requested ? 'warning' : 'default'"
:icon="user.attention_requested ? 'attention-solid' : 'attention'"
:aria-label="tooltipTitle"
:class="{ 'gl-pointer-events-none': !user.can_update_merge_request }"
size="small"
category="tertiary"
@click="toggleAttentionRequired"

View File

@ -98,7 +98,7 @@ export default {
data-testid="reviewer"
>
<attention-requested-toggle
v-if="glFeatures.mrAttentionRequests && user.can_update_merge_request"
v-if="glFeatures.mrAttentionRequests"
:user="user"
type="reviewer"
@toggle-attention-requested="toggleAttentionRequested"

View File

@ -1085,10 +1085,10 @@ class Repository
blob.data
end
def create_if_not_exists
def create_if_not_exists(default_branch = nil)
return if exists?
raw.create_repository
raw.create_repository(default_branch)
after_create
true

View File

@ -367,7 +367,7 @@ class Snippet < ApplicationRecord
def create_repository
return if repository_exists? && snippet_repository
repository.create_if_not_exists
repository.create_if_not_exists(default_branch)
track_snippet_repository(repository.storage)
end

View File

@ -1,4 +1,5 @@
- submit_btn_css ||= 'gl-button btn btn-danger btn-sm'
= form_tag admin_application_path(application) do
%input{ :name => "_method", :type => "hidden", :value => "delete" }/
= submit_tag 'Destroy', class: submit_btn_css, data: { confirm: _('Are you sure?') }
- submit_btn_css ||= 'gl-button btn btn-danger btn-sm js-application-delete-button'
%button{ class: submit_btn_css, data: { path: admin_application_path(application), name: application.name } }
= _('Destroy')

View File

@ -33,3 +33,5 @@
%td= render 'delete_form', application: application
= paginate @applications, theme: 'gitlab'
.js-application-delete-modal

View File

@ -1161,8 +1161,6 @@ Input type: `ConfigureSecretDetectionInput`
### `Mutation.corpusCreate`
Available only when feature flag `corpus_management` is enabled. This flag is enabled by default.
Input type: `CorpusCreateInput`
#### Arguments
@ -13789,7 +13787,7 @@ Represents vulnerability finding of a security report on the pipeline.
| <a id="projectcontainerexpirationpolicy"></a>`containerExpirationPolicy` | [`ContainerExpirationPolicy`](#containerexpirationpolicy) | Container expiration policy of the project. |
| <a id="projectcontainerregistryenabled"></a>`containerRegistryEnabled` | [`Boolean`](#boolean) | Indicates if Container Registry is enabled for the current user. |
| <a id="projectcontainerrepositoriescount"></a>`containerRepositoriesCount` | [`Int!`](#int) | Number of container repositories in the project. |
| <a id="projectcorpuses"></a>`corpuses` | [`CoverageFuzzingCorpusConnection`](#coveragefuzzingcorpusconnection) | Find corpuses of the project. Available only when feature flag `corpus_management` is enabled. This flag is enabled by default. (see [Connections](#connections)) |
| <a id="projectcorpuses"></a>`corpuses` | [`CoverageFuzzingCorpusConnection`](#coveragefuzzingcorpusconnection) | Find corpuses of the project. (see [Connections](#connections)) |
| <a id="projectcreatedat"></a>`createdAt` | [`Time`](#time) | Timestamp of the project creation. |
| <a id="projectdastscannerprofiles"></a>`dastScannerProfiles` | [`DastScannerProfileConnection`](#dastscannerprofileconnection) | DAST scanner profiles associated with the project. (see [Connections](#connections)) |
| <a id="projectdastsiteprofiles"></a>`dastSiteProfiles` | [`DastSiteProfileConnection`](#dastsiteprofileconnection) | DAST Site Profiles associated with the project. (see [Connections](#connections)) |

View File

@ -26,18 +26,12 @@ For more information on the database review process, check the [database review
## How to apply for becoming a database reviewer
Team members are encouraged to self-identify as database domain experts and add it to their [team profile](https://gitlab.com/gitlab-com/www-gitlab-com/-/blob/master/data/team.yml)
Team members are encouraged to self-identify as database domain experts, and add it to their profile YAML file:
```yaml
projects:
gitlab:
- reviewer database
```
Assign the MR which adds your expertise to the `team.yml` file to a database maintainer
or the [Database Team's Engineering Manager](https://about.gitlab.com/handbook/engineering/development/enablement/database/).
Once the `team.yml` update is merged, the [Reviewer roulette](../code_review.md#reviewer-roulette)
may recommend you as a database reviewer.
## Resources for database reviewers

View File

@ -64,3 +64,15 @@ We recommend the following workflow:
1. **If the experiment is a success**, designers add the new icon or illustration to the Pajamas UI kit as part of the cleanup process.
Engineers can then add it to the [SVG library](https://gitlab-org.gitlab.io/gitlab-svgs/) and modify the implementation based on the
[Frontend Development Guidelines](../fe_guide/icons.md#usage-in-hamlrails-2).
## Turn off all experiments
When there is a case on GitLab.com (SaaS) that necessitates turning off all experiments, we have this control.
You can toggle experiments on SaaS on and off using the `gitlab_experiment` [feature flag](../feature_flags).
This can be done via chatops:
- [disable](../feature_flags/controls.md#disabling-feature-flags): `/chatops run feature set gitlab_experiment false`
- [enable](../feature_flags/controls.md#process): `/chatops run feature delete gitlab_experiment`
- This allows the `default_enabled` [value of true in the yml](https://gitlab.com/gitlab-org/gitlab/-/blob/016430f6751b0c34abb24f74608c80a1a8268f20/config/feature_flags/ops/gitlab_experiment.yml#L8) to be honored.

View File

@ -144,12 +144,8 @@ You can download the JSON report file from the CI/CD pipelines page. For more in
## Corpus registry
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/5017) in GitLab 14.8.
FLAG:
On self-managed GitLab, by default this feature is available. To hide the feature, ask an
administrator to [disable the feature flags](../../../administration/feature_flags.md) named
`corpus_management` and `corpus_management_ui`. On GitLab.com, this feature is available.
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/5017) in GitLab 14.8.
> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/347187) in GitLab 14.9. [Feature flags `corpus_management` and `corpus_management_ui`](https://gitlab.com/gitlab-org/gitlab/-/issues/328418) removed.
The corpus registry is a library of corpuses. Corpuses in a project's registry are available to
all jobs in that project. A project-wide registry is a more efficient way to manage corpuses than

View File

@ -99,9 +99,9 @@ module Gitlab
gitaly_repository_client.exists?
end
def create_repository
def create_repository(default_branch = nil)
wrapped_gitaly_errors do
gitaly_repository_client.create_repository
gitaly_repository_client.create_repository(default_branch)
rescue GRPC::AlreadyExists => e
raise RepositoryExists, e.message
end

View File

@ -107,8 +107,8 @@ module Gitlab
end
# rubocop: enable Metrics/ParameterLists
def create_repository
request = Gitaly::CreateRepositoryRequest.new(repository: @gitaly_repo)
def create_repository(default_branch = nil)
request = Gitaly::CreateRepositoryRequest.new(repository: @gitaly_repo, default_branch: default_branch)
GitalyClient.call(@storage, :repository_service, :create_repository, request, timeout: GitalyClient.fast_timeout)
end

View File

@ -4696,6 +4696,9 @@ msgstr ""
msgid "Are you sure that you want to archive this project?"
msgstr ""
msgid "Are you sure that you want to destroy %{application}"
msgstr ""
msgid "Are you sure that you want to unarchive this project?"
msgstr ""
@ -5032,6 +5035,9 @@ msgstr ""
msgid "Attention"
msgstr ""
msgid "Attention requested"
msgstr ""
msgid "Audit Events"
msgstr ""
@ -9281,6 +9287,9 @@ msgstr ""
msgid "Confirm approval"
msgstr ""
msgid "Confirm destroy application"
msgstr ""
msgid "Confirm new password"
msgstr ""
@ -24672,6 +24681,9 @@ msgstr ""
msgid "No assignee"
msgstr ""
msgid "No attention request"
msgstr ""
msgid "No authentication methods configured."
msgstr ""

View File

@ -155,6 +155,7 @@
"pikaday": "^1.8.0",
"popper.js": "^1.16.1",
"portal-vue": "^2.1.7",
"postcss": "8.4.5",
"prismjs": "^1.21.0",
"prosemirror-markdown": "1.7.1",
"prosemirror-model": "^1.16.1",
@ -239,7 +240,6 @@
"miragejs": "^0.1.40",
"mock-apollo-client": "1.2.0",
"nodemon": "^2.0.4",
"postcss": "^8.4.5",
"prettier": "2.2.1",
"prosemirror-schema-basic": "^1.1.2",
"prosemirror-schema-list": "^1.1.6",

View File

@ -0,0 +1,20 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`DeleteApplication the modal component form matches the snapshot 1`] = `
<form
action="application/path/1"
method="post"
>
<input
name="_method"
type="hidden"
value="delete"
/>
<input
name="authenticity_token"
type="hidden"
value="mock-csrf-token"
/>
</form>
`;

View File

@ -0,0 +1,69 @@
import { GlModal, GlSprintf } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import DeleteApplication from '~/admin/applications/components/delete_application.vue';
const path = 'application/path/1';
const name = 'Application name';
jest.mock('~/lib/utils/csrf', () => ({ token: 'mock-csrf-token' }));
describe('DeleteApplication', () => {
let wrapper;
const createComponent = () => {
wrapper = shallowMount(DeleteApplication, {
stubs: {
GlSprintf,
},
});
};
const findModal = () => wrapper.findComponent(GlModal);
const findForm = () => wrapper.find('form');
beforeEach(() => {
setFixtures(`
<button class="js-application-delete-button" data-path="${path}" data-name="${name}">Destroy</button>
`);
createComponent();
});
afterEach(() => {
wrapper.destroy();
});
describe('the modal component', () => {
beforeEach(() => {
wrapper.vm.$refs.deleteModal.show = jest.fn();
document.querySelector('.js-application-delete-button').click();
});
it('displays the modal component', () => {
const modal = findModal();
expect(modal.exists()).toBe(true);
expect(modal.props('title')).toBe('Confirm destroy application');
expect(modal.text()).toBe(`Are you sure that you want to destroy ${name}`);
});
describe('form', () => {
it('matches the snapshot', () => {
expect(findForm().element).toMatchSnapshot();
});
describe('form submission', () => {
let formSubmitSpy;
beforeEach(() => {
formSubmitSpy = jest.spyOn(wrapper.vm.$refs.deleteForm, 'submit');
findModal().vm.$emit('primary');
});
it('submits the form on the modal primary action', () => {
expect(formSubmitSpy).toHaveBeenCalled();
});
});
});
});
});

View File

@ -16,7 +16,10 @@ describe('Attention require toggle', () => {
});
it('renders button', () => {
factory({ type: 'reviewer', user: { attention_requested: false } });
factory({
type: 'reviewer',
user: { attention_requested: false, can_update_merge_request: true },
});
expect(findToggle().exists()).toBe(true);
});
@ -28,7 +31,10 @@ describe('Attention require toggle', () => {
`(
'renders $icon icon when attention_requested is $attentionRequested',
({ attentionRequested, icon }) => {
factory({ type: 'reviewer', user: { attention_requested: attentionRequested } });
factory({
type: 'reviewer',
user: { attention_requested: attentionRequested, can_update_merge_request: true },
});
expect(findToggle().props('icon')).toBe(icon);
},
@ -41,27 +47,47 @@ describe('Attention require toggle', () => {
`(
'renders button with variant $variant when attention_requested is $attentionRequested',
({ attentionRequested, variant }) => {
factory({ type: 'reviewer', user: { attention_requested: attentionRequested } });
factory({
type: 'reviewer',
user: { attention_requested: attentionRequested, can_update_merge_request: true },
});
expect(findToggle().props('variant')).toBe(variant);
},
);
it('emits toggle-attention-requested on click', async () => {
factory({ type: 'reviewer', user: { attention_requested: true } });
factory({
type: 'reviewer',
user: { attention_requested: true, can_update_merge_request: true },
});
await findToggle().trigger('click');
expect(wrapper.emitted('toggle-attention-requested')[0]).toEqual([
{
user: { attention_requested: true },
user: { attention_requested: true, can_update_merge_request: true },
callback: expect.anything(),
},
]);
});
it('does not emit toggle-attention-requested on click if can_update_merge_request is false', async () => {
factory({
type: 'reviewer',
user: { attention_requested: true, can_update_merge_request: false },
});
await findToggle().trigger('click');
expect(wrapper.emitted('toggle-attention-requested')).toBe(undefined);
});
it('sets loading on click', async () => {
factory({ type: 'reviewer', user: { attention_requested: true } });
factory({
type: 'reviewer',
user: { attention_requested: true, can_update_merge_request: true },
});
await findToggle().trigger('click');
@ -69,14 +95,24 @@ describe('Attention require toggle', () => {
});
it.each`
type | attentionRequested | tooltip
${'reviewer'} | ${true} | ${AttentionRequestedToggle.i18n.removeAttentionRequested}
${'reviewer'} | ${false} | ${AttentionRequestedToggle.i18n.attentionRequestedReviewer}
${'assignee'} | ${false} | ${AttentionRequestedToggle.i18n.attentionRequestedAssignee}
type | attentionRequested | tooltip | canUpdateMergeRequest
${'reviewer'} | ${true} | ${AttentionRequestedToggle.i18n.removeAttentionRequested} | ${true}
${'reviewer'} | ${false} | ${AttentionRequestedToggle.i18n.attentionRequestedReviewer} | ${true}
${'assignee'} | ${false} | ${AttentionRequestedToggle.i18n.attentionRequestedAssignee} | ${true}
${'reviewer'} | ${true} | ${AttentionRequestedToggle.i18n.attentionRequestedNoPermission} | ${false}
${'reviewer'} | ${false} | ${AttentionRequestedToggle.i18n.noAttentionRequestedNoPermission} | ${false}
${'assignee'} | ${true} | ${AttentionRequestedToggle.i18n.attentionRequestedNoPermission} | ${false}
${'assignee'} | ${false} | ${AttentionRequestedToggle.i18n.noAttentionRequestedNoPermission} | ${false}
`(
'sets tooltip as $tooltip when attention_requested is $attentionRequested and type is $type',
({ type, attentionRequested, tooltip }) => {
factory({ type, user: { attention_requested: attentionRequested } });
'sets tooltip as $tooltip when attention_requested is $attentionRequested, type is $type and, can_update_merge_request is $canUpdateMergeRequest',
({ type, attentionRequested, tooltip, canUpdateMergeRequest }) => {
factory({
type,
user: {
attention_requested: attentionRequested,
can_update_merge_request: canUpdateMergeRequest,
},
});
expect(findToggle().attributes('aria-label')).toBe(tooltip);
},

View File

@ -78,6 +78,10 @@ RSpec.describe Gitlab::BackgroundMigration::BackfillSnippetRepositories, :migrat
end
shared_examples 'migration_bot user commits files' do
before do
allow(Gitlab::CurrentSettings).to receive(:default_branch_name).and_return('main')
end
it do
subject
@ -89,6 +93,10 @@ RSpec.describe Gitlab::BackgroundMigration::BackfillSnippetRepositories, :migrat
end
shared_examples 'commits the file to the repository' do
before do
allow(Gitlab::CurrentSettings).to receive(:default_branch_name).and_return('main')
end
context 'when author can update snippet and use git' do
it 'creates the repository and commit the file' do
subject
@ -269,6 +277,10 @@ RSpec.describe Gitlab::BackgroundMigration::BackfillSnippetRepositories, :migrat
let!(:snippet) { snippets.create!(id: 5, type: 'PersonalSnippet', author_id: other_user.id, file_name: file_name, content: content) }
let(:ids) { [4, 5] }
before do
allow(Gitlab::CurrentSettings).to receive(:default_branch_name).and_return('main')
end
after do
raw_repository(snippet).remove
raw_repository(invalid_snippet).remove

View File

@ -218,6 +218,26 @@ RSpec.describe Gitlab::GitalyClient::RepositoryService do
end
end
describe '#create_repository' do
it 'sends a create_repository message without arguments' do
expect_any_instance_of(Gitaly::RepositoryService::Stub)
.to receive(:create_repository)
.with(gitaly_request_with_path(storage_name, relative_path).and(gitaly_request_with_params(default_branch: '')), kind_of(Hash))
.and_return(double)
client.create_repository
end
it 'sends a create_repository message with default branch' do
expect_any_instance_of(Gitaly::RepositoryService::Stub)
.to receive(:create_repository)
.with(gitaly_request_with_path(storage_name, relative_path).and(gitaly_request_with_params(default_branch: 'default-branch-name')), kind_of(Hash))
.and_return(double)
client.create_repository('default-branch-name')
end
end
describe '#create_from_snapshot' do
it 'sends a create_repository_from_snapshot message' do
expect_any_instance_of(Gitaly::RepositoryService::Stub)

View File

@ -3062,6 +3062,14 @@ RSpec.describe Repository do
repository.create_if_not_exists
end
it 'creates a repository with a default branch name' do
default_branch_name = 'branch-a'
repository.create_if_not_exists(default_branch_name)
repository.create_file(user, 'file', 'content', message: 'initial commit', branch_name: default_branch_name)
expect(repository.root_ref).to eq(default_branch_name)
end
context 'it does nothing if the repository already existed' do
let(:project) { create(:project, :repository) }

View File

@ -667,6 +667,16 @@ RSpec.describe Snippet do
expect(snippet.repository.exists?).to be_truthy
end
it 'sets the default branch' do
expect(snippet).to receive(:default_branch).and_return('default-branch-1')
expect(subject).to be_truthy
snippet.repository.create_file(snippet.author, 'file', 'content', message: 'initial commit', branch_name: 'default-branch-1')
expect(snippet.repository.exists?).to be_truthy
expect(snippet.repository.root_ref).to eq('default-branch-1')
end
it 'tracks snippet repository' do
expect do
subject
@ -677,6 +687,7 @@ RSpec.describe Snippet do
expect(snippet).to receive(:repository_storage).and_return('picked')
expect(snippet).to receive(:repository_exists?).and_return(false)
expect(snippet.repository).to receive(:create_if_not_exists)
allow(snippet).to receive(:default_branch).and_return('picked')
subject
@ -899,22 +910,6 @@ RSpec.describe Snippet do
end
end
context 'when repository is empty' do
let(:snippet) { create(:snippet, :empty_repo) }
before do
allow(Gitlab::CurrentSettings).to receive(:default_branch_name).and_return(default_branch)
end
context 'when default branch in settings is different from "master"' do
let(:default_branch) { 'custom-branch' }
it 'changes the HEAD reference to the default branch' do
expect { subject }.to change { File.read(head_path).squish }.to("ref: refs/heads/#{default_branch}")
end
end
end
context 'when repository is not empty' do
let(:snippet) { create(:snippet, :empty_repo) }

View File

@ -13,8 +13,6 @@ RSpec.describe Projects::Security::ConfigurationPresenter do
before do
stub_licensed_features(licensed_scan_types.to_h { |type| [type, true] })
stub_feature_flags(corpus_management_ui: false)
end
describe '#to_html_data_attribute' do

View File

@ -5,7 +5,7 @@ RSpec.shared_examples 'manage applications' do
let_it_be(:application_name_changed) { "#{application_name} changed" }
let_it_be(:application_redirect_uri) { 'https://foo.bar' }
it 'allows user to manage applications' do
it 'allows user to manage applications', :js do
visit new_application_path
expect(page).to have_content 'Add new application'

View File

@ -9447,15 +9447,7 @@ postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0:
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514"
integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==
postcss@^7.0.14, postcss@^7.0.5, postcss@^7.0.6:
version "7.0.39"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.39.tgz#9624375d965630e2e1f2c02a935c82a59cb48309"
integrity sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==
dependencies:
picocolors "^0.2.1"
source-map "^0.6.1"
postcss@^8.2.1, postcss@^8.4.5:
postcss@8.4.5, postcss@^8.2.1, postcss@^8.4.5:
version "8.4.5"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.5.tgz#bae665764dfd4c6fcc24dc0fdf7e7aa00cc77f95"
integrity sha512-jBDboWM8qpaqwkMwItqTQTiFikhs/67OYVvblFFTM7MrZjt6yMKd6r2kgXizEbTTljacm4NldIlZnhbjr84QYg==
@ -9464,6 +9456,14 @@ postcss@^8.2.1, postcss@^8.4.5:
picocolors "^1.0.0"
source-map-js "^1.0.1"
postcss@^7.0.14, postcss@^7.0.5, postcss@^7.0.6:
version "7.0.39"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.39.tgz#9624375d965630e2e1f2c02a935c82a59cb48309"
integrity sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==
dependencies:
picocolors "^0.2.1"
source-map "^0.6.1"
prelude-ls@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"