Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-09-02 15:12:37 +00:00
parent 2d337eacd9
commit 0a70b104d0
46 changed files with 363 additions and 691 deletions

View File

@ -53,23 +53,6 @@ Layout/HashAlignment:
- 'spec/lib/gitlab/metrics/subscribers/action_view_spec.rb'
- 'spec/lib/gitlab/metrics/subscribers/active_record_spec.rb'
- 'spec/lib/gitlab/metrics/subscribers/load_balancing_spec.rb'
- 'spec/models/ci/build_spec.rb'
- 'spec/models/ci/processable_spec.rb'
- 'spec/models/clusters/platforms/kubernetes_spec.rb'
- 'spec/models/container_registry/event_spec.rb'
- 'spec/models/deployment_spec.rb'
- 'spec/models/design_management/version_spec.rb'
- 'spec/models/group_spec.rb'
- 'spec/models/integrations/chat_message/pipeline_message_spec.rb'
- 'spec/models/integrations/drone_ci_spec.rb'
- 'spec/models/merge_request_spec.rb'
- 'spec/models/namespace_spec.rb'
- 'spec/models/operations/feature_flag_spec.rb'
- 'spec/models/pages_domain_spec.rb'
- 'spec/models/remote_mirror_spec.rb'
- 'spec/models/repository_spec.rb'
- 'spec/models/user_spec.rb'
- 'spec/presenters/project_presenter_spec.rb'
- 'spec/routing/project_routing_spec.rb'
- 'spec/serializers/ci/lint/job_entity_spec.rb'
- 'spec/serializers/container_repository_entity_spec.rb'

View File

@ -5,10 +5,6 @@ import { SEVERITY_CLASSES, SEVERITY_ICONS } from '~/reports/codequality_report/c
export default {
components: { GlButton, GlIcon },
props: {
line: {
type: Number,
required: true,
},
codeQuality: {
type: Array,
required: true,
@ -50,7 +46,7 @@ export default {
size="small"
icon="close"
class="gl-absolute gl-right-2 gl-top-2"
@click="$emit('hideCodeQualityFindings', line)"
@click="$emit('hideCodeQualityFindings')"
/>
</div>
</template>

View File

@ -0,0 +1,35 @@
<script>
import DiffCodeQuality from './diff_code_quality.vue';
export default {
components: {
DiffCodeQuality,
},
props: {
line: {
type: Object,
required: true,
},
},
computed: {
parsedCodeQuality() {
return (this.line.left ?? this.line.right)?.codequality;
},
codeQualityLineNumber() {
return this.parsedCodeQuality[0].line;
},
},
methods: {
hideCodeQualityFindings() {
this.$emit('hideCodeQualityFindings', this.codeQualityLineNumber);
},
},
};
</script>
<template>
<diff-code-quality
:code-quality="parsedCodeQuality"
@hideCodeQualityFindings="hideCodeQualityFindings"
/>
</template>

View File

@ -9,7 +9,7 @@ import { getCommentedLines } from '~/notes/components/multiline_comment_utils';
import { hide } from '~/tooltips';
import { pickDirection } from '../utils/diff_line';
import DiffCommentCell from './diff_comment_cell.vue';
import DiffCodeQuality from './diff_code_quality.vue';
import DiffLine from './diff_line.vue';
import DiffExpansionCell from './diff_expansion_cell.vue';
import DiffRow from './diff_row.vue';
import { isHighlighted } from './diff_row_utils';
@ -18,8 +18,8 @@ export default {
components: {
DiffExpansionCell,
DiffRow,
DiffLine,
DiffCommentCell,
DiffCodeQuality,
DraftNote,
},
directives: {
@ -96,10 +96,6 @@ export default {
}
this.idState.dragStart = line;
},
parseCodeQuality(line) {
return (line.left ?? line.right)?.codequality;
},
hideCodeQualityFindings(line) {
const index = this.codeQualityExpandedLines.indexOf(line);
if (index > -1) {
@ -179,7 +175,7 @@ export default {
);
},
getCodeQualityLine(line) {
return this.parseCodeQuality(line)?.[0]?.line;
return (line.left ?? line.right)?.codequality?.[0]?.line;
},
},
userColorScheme: window.gon.user_color_scheme,
@ -248,15 +244,13 @@ export default {
@startdragging="onStartDragging"
@stopdragging="onStopDragging"
/>
<diff-code-quality
<diff-line
v-if="
glFeatures.refactorCodeQualityInlineFindings &&
codeQualityExpandedLines.includes(getCodeQualityLine(line))
"
:key="line.line_code"
:line="getCodeQualityLine(line)"
:code-quality="parseCodeQuality(line)"
:line="line"
@hideCodeQualityFindings="hideCodeQualityFindings"
/>
<div

View File

@ -1,9 +1,43 @@
<script>
import { __ } from '~/locale';
import createFlash from '~/flash';
import branchRulesQuery from './graphql/queries/branch_rules.query.graphql';
export const i18n = {
heading: __('Branch'),
queryError: __('An error occurred while loading branch rules. Please try again.'),
};
export default {
name: 'BranchRules',
i18n: { heading: __('Branch') },
i18n,
apollo: {
branchRules: {
query: branchRulesQuery,
variables() {
return {
projectPath: this.projectPath,
};
},
update(data) {
return data.project?.branchRules?.nodes || [];
},
error() {
createFlash({ message: this.$options.i18n.queryError });
},
},
},
props: {
projectPath: {
type: String,
required: true,
},
},
data() {
return {
branchRules: [],
};
},
};
</script>

View File

@ -0,0 +1,10 @@
query getBranchRules($projectPath: ID!) {
project(fullPath: $projectPath) {
id
branchRules {
nodes {
name
}
}
}
}

View File

@ -1,13 +1,28 @@
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createDefaultClient from '~/lib/graphql';
import BranchRulesApp from '~/projects/settings/repository/branch_rules/app.vue';
Vue.use(VueApollo);
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient(),
});
export default function mountBranchRules(el) {
if (!el) return null;
const { projectPath } = el.dataset;
return new Vue({
el,
apolloProvider,
render(createElement) {
return createElement(BranchRulesApp);
return createElement(BranchRulesApp, {
props: {
projectPath,
},
});
},
});
}

View File

@ -23,120 +23,4 @@ module StorageHelper
_("Repository: %{counter_repositories} / Wikis: %{counter_wikis} / Build Artifacts: %{counter_build_artifacts} / Pipeline Artifacts: %{counter_pipeline_artifacts} / LFS: %{counter_lfs_objects} / Snippets: %{counter_snippets} / Packages: %{counter_packages} / Uploads: %{counter_uploads}") % counters
end
def storage_enforcement_banner_info(context)
root_ancestor = context.root_ancestor
return unless should_show_storage_enforcement_banner?(context, current_user, root_ancestor)
text_args = storage_enforcement_banner_text_args(root_ancestor, context)
text_paragraph_2 = if root_ancestor.user_namespace?
html_escape_once(s_("UsageQuota|The namespace is currently using %{strong_start}%{used_storage}%{strong_end} of namespace storage. " \
"View and manage your usage from %{strong_start}User settings &gt; Usage quotas%{strong_end}. %{docs_link_start}Learn more%{link_end} " \
"about how to reduce your storage.")).html_safe % text_args[:p2]
else
html_escape_once(s_("UsageQuota|The namespace is currently using %{strong_start}%{used_storage}%{strong_end} of namespace storage. " \
"Group owners can view namespace storage usage and purchase more from %{strong_start}Group settings &gt; Usage quotas%{strong_end}. %{docs_link_start}Learn more.%{link_end}" \
)).html_safe % text_args[:p2]
end
{
text_paragraph_1: html_escape_once(s_("UsageQuota|Effective %{storage_enforcement_date}, namespace storage limits will apply " \
"to the %{strong_start}%{namespace_name}%{strong_end} namespace. %{extra_message}" \
"View the %{rollout_link_start}rollout schedule for this change%{link_end}.")).html_safe % text_args[:p1],
text_paragraph_2: text_paragraph_2,
text_paragraph_3: html_escape_once(s_("UsageQuota|See our %{faq_link_start}FAQ%{link_end} for more information.")).html_safe % text_args[:p3],
variant: 'warning',
namespace_id: root_ancestor.id,
callouts_path: root_ancestor.user_namespace? ? callouts_path : group_callouts_path,
callouts_feature_name: storage_enforcement_banner_user_callouts_feature_name(root_ancestor)
}
end
private
def should_show_storage_enforcement_banner?(context, current_user, root_ancestor)
return false unless user_allowed_storage_enforcement_banner?(context, current_user, root_ancestor)
return false if root_ancestor.paid?
return false unless future_enforcement_date?(root_ancestor)
return false if user_dismissed_storage_enforcement_banner?(root_ancestor)
return false if (root_ancestor.root_storage_statistics&.storage_size || 0) < ::Namespace::MIN_STORAGE_ENFORCEMENT_USAGE
::Feature.enabled?(:namespace_storage_limit_show_preenforcement_banner, root_ancestor)
end
def user_allowed_storage_enforcement_banner?(context, current_user, root_ancestor)
return can?(current_user, :maintainer_access, context) unless context.respond_to?(:user_namespace?) && context.user_namespace?
can?(current_user, :owner_access, context)
end
def storage_enforcement_banner_text_args(root_ancestor, context)
strong_tags = {
strong_start: "<strong>".html_safe,
strong_end: "</strong>".html_safe
}
extra_message = if context.is_a?(Project)
html_escape_once(s_("UsageQuota|The %{strong_start}%{context_name}%{strong_end} project will be affected by this. "))
.html_safe % strong_tags.merge(context_name: context.name)
elsif !context.root?
html_escape_once(s_("UsageQuota|The %{strong_start}%{context_name}%{strong_end} group will be affected by this. "))
.html_safe % strong_tags.merge(context_name: context.name)
else
''
end
{
p1: {
storage_enforcement_date: root_ancestor.storage_enforcement_date,
namespace_name: root_ancestor.name,
extra_message: extra_message,
rollout_link_start: '<a href="%{url}" >'.html_safe % { url: help_page_path('user/usage_quotas', anchor: 'namespace-storage-limit-enforcement-schedule') },
link_end: "</a>".html_safe
}.merge(strong_tags),
p2: {
used_storage: storage_counter(root_ancestor.root_storage_statistics&.storage_size || 0),
docs_link_start: '<a href="%{url}" >'.html_safe % { url: help_page_path('user/usage_quotas', anchor: 'manage-your-storage-usage') },
link_end: "</a>".html_safe
}.merge(strong_tags),
p3: {
faq_link_start: '<a href="%{url}" >'.html_safe % { url: "#{Gitlab::Saas.about_pricing_url}faq-efficient-free-tier/#storage-limits-on-gitlab-saas-free-tier" },
link_end: "</a>".html_safe
}
}
end
def storage_enforcement_banner_user_callouts_feature_name(namespace)
"storage_enforcement_banner_#{storage_enforcement_banner_threshold(namespace)}_enforcement_threshold"
end
def storage_enforcement_banner_threshold(namespace)
days_to_enforcement_date = (namespace.storage_enforcement_date - Date.today)
return :first if days_to_enforcement_date > 30
return :second if days_to_enforcement_date > 15 && days_to_enforcement_date <= 30
return :third if days_to_enforcement_date > 7 && days_to_enforcement_date <= 15
return :fourth if days_to_enforcement_date >= 0 && days_to_enforcement_date <= 7
end
def user_dismissed_storage_enforcement_banner?(namespace)
return false unless current_user
if namespace.user_namespace?
current_user.dismissed_callout?(feature_name: storage_enforcement_banner_user_callouts_feature_name(namespace))
else
current_user.dismissed_callout_for_group?(
feature_name: storage_enforcement_banner_user_callouts_feature_name(namespace),
group: namespace
)
end
end
def future_enforcement_date?(namespace)
return true if ::Feature.enabled?(:namespace_storage_limit_bypass_date_check, namespace)
namespace.storage_enforcement_date.present? && namespace.storage_enforcement_date >= Date.today
end
end

View File

@ -43,10 +43,10 @@ module Users
verification_reminder: 40, # EE-only
ci_deprecation_warning_for_types_keyword: 41,
security_training_feature_promotion: 42, # EE-only
storage_enforcement_banner_first_enforcement_threshold: 43,
storage_enforcement_banner_second_enforcement_threshold: 44,
storage_enforcement_banner_third_enforcement_threshold: 45,
storage_enforcement_banner_fourth_enforcement_threshold: 46,
storage_enforcement_banner_first_enforcement_threshold: 43, # EE-only
storage_enforcement_banner_second_enforcement_threshold: 44, # EE-only
storage_enforcement_banner_third_enforcement_threshold: 45, # EE-only
storage_enforcement_banner_fourth_enforcement_threshold: 46, # EE-only
# 47 and 48 were removed with https://gitlab.com/gitlab-org/gitlab/-/merge_requests/95446
# 49 was removed with https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91533
# because the banner was no longer relevant.

View File

@ -11,10 +11,10 @@ module Users
enum feature_name: {
invite_members_banner: 1,
approaching_seat_count_threshold: 2, # EE-only
storage_enforcement_banner_first_enforcement_threshold: 3,
storage_enforcement_banner_second_enforcement_threshold: 4,
storage_enforcement_banner_third_enforcement_threshold: 5,
storage_enforcement_banner_fourth_enforcement_threshold: 6,
storage_enforcement_banner_first_enforcement_threshold: 3, # EE-only
storage_enforcement_banner_second_enforcement_threshold: 4, # EE-only
storage_enforcement_banner_third_enforcement_threshold: 5, # EE-only
storage_enforcement_banner_fourth_enforcement_threshold: 6, # EE-only
preview_user_over_limit_free_plan_alert: 7, # EE-only
user_reached_limit_free_plan_alert: 8, # EE-only
free_group_limited_alert: 9, # EE-only

View File

@ -11,10 +11,10 @@ module Users
enum feature_name: {
invite_members_banner: 1,
approaching_seat_count_threshold: 2, # EE-only
storage_enforcement_banner_first_enforcement_threshold: 3,
storage_enforcement_banner_second_enforcement_threshold: 4,
storage_enforcement_banner_third_enforcement_threshold: 5,
storage_enforcement_banner_fourth_enforcement_threshold: 6,
storage_enforcement_banner_first_enforcement_threshold: 3, # EE-only
storage_enforcement_banner_second_enforcement_threshold: 4, # EE-only
storage_enforcement_banner_third_enforcement_threshold: 5, # EE-only
storage_enforcement_banner_fourth_enforcement_threshold: 6, # EE-only
preview_user_over_limit_free_plan_alert: 7, # EE-only
user_reached_limit_free_plan_alert: 8, # EE-only
web_hook_disabled: 9

View File

@ -6,7 +6,7 @@
- @left_sidebar = true
- content_for :flash_message do
= render "layouts/header/storage_enforcement_banner", context: @group
= dispensable_render_if_exists "groups/storage_enforcement_alert", context: @group
= dispensable_render_if_exists "shared/namespace_storage_limit_alert", context: @group
- content_for :page_specific_javascripts do

View File

@ -1,15 +0,0 @@
- return unless current_user
- context = local_assigns.fetch(:context)
- banner_info = storage_enforcement_banner_info(context)
- return unless banner_info.present?
= render Pajamas::AlertComponent.new(variant: :warning,
alert_options: { class: 'js-storage-enforcement-banner',
data: { feature_id: banner_info[:callouts_feature_name],
dismiss_endpoint: banner_info[:callouts_path],
group_id: banner_info[:namespace_id],
defer_links: "true" }}) do |c|
= c.body do
%p= banner_info[:text_paragraph_1]
%p= banner_info[:text_paragraph_2]
%p= banner_info[:text_paragraph_3]

View File

@ -7,7 +7,7 @@
- enable_search_settings locals: { container_class: 'gl-my-5' }
- content_for :flash_message do
= render "layouts/header/storage_enforcement_banner", context: current_user.namespace
= dispensable_render_if_exists "profiles/storage_enforcement_alert", context: current_user.namespace
= dispensable_render_if_exists "shared/namespace_storage_limit_alert", context: current_user.namespace
= render template: "layouts/application"

View File

@ -8,7 +8,7 @@
- @content_class = [@content_class, project_classes(@project)].compact.join(" ")
- content_for :flash_message do
= render "layouts/header/storage_enforcement_banner", context: @project
= dispensable_render_if_exists "projects/storage_enforcement_alert", context: @project
= dispensable_render_if_exists "shared/namespace_storage_limit_alert", context: @project
- content_for :project_javascripts do

View File

@ -9,4 +9,4 @@
= _('Define rules for who can push, merge, and the required approvals for each branch.')
.settings-content.gl-pr-0
#js-branch-rules
#js-branch-rules{ data: { project_path: @project.full_path } }

View File

@ -736,7 +736,7 @@ You can change these limits in the [GitLab Rails console](operations/rails_conso
- To update the maximum YAML size, update `max_yaml_size_bytes` with the new value in megabytes:
```ruby
ApplicationSetting.update!(max_yaml_size_bytes: 2.megabytes)
ApplicationSetting.update(max_yaml_size_bytes: 2.megabytes)
```
The `max_yaml_size_bytes` value is not directly tied to the size of the YAML file,
@ -745,7 +745,7 @@ You can change these limits in the [GitLab Rails console](operations/rails_conso
- To update the maximum YAML depth, update `max_yaml_depth` with the new value in megabytes:
```ruby
ApplicationSetting.update!(max_yaml_depth: 125)
ApplicationSetting.update(max_yaml_depth: 125)
```
### Limit dotenv variables

View File

@ -4197,6 +4197,9 @@ msgstr ""
msgid "An error occurred while loading all the files."
msgstr ""
msgid "An error occurred while loading branch rules. Please try again."
msgstr ""
msgid "An error occurred while loading chart data"
msgstr ""
@ -42179,6 +42182,9 @@ msgstr ""
msgid "UsageQuota|Gitlab-integrated Docker Container Registry for storing Docker Images. %{linkStart}More information%{linkEnd}"
msgstr ""
msgid "UsageQuota|Group settings &gt; Usage quotas"
msgstr ""
msgid "UsageQuota|Includes artifacts, repositories, wiki, uploads, and other items."
msgstr ""
@ -42275,10 +42281,10 @@ msgstr ""
msgid "UsageQuota|The %{strong_start}%{context_name}%{strong_end} project will be affected by this. "
msgstr ""
msgid "UsageQuota|The namespace is currently using %{strong_start}%{used_storage}%{strong_end} of namespace storage. Group owners can view namespace storage usage and purchase more from %{strong_start}Group settings &gt; Usage quotas%{strong_end}. %{docs_link_start}Learn more.%{link_end}"
msgid "UsageQuota|The namespace is currently using %{strong_start}%{used_storage}%{strong_end} of namespace storage. Group owners can view namespace storage usage and purchase more from %{strong_start}%{usage_quotas_nav_instruction}%{strong_end}. %{docs_link_start}Learn more%{link_end}."
msgstr ""
msgid "UsageQuota|The namespace is currently using %{strong_start}%{used_storage}%{strong_end} of namespace storage. View and manage your usage from %{strong_start}User settings &gt; Usage quotas%{strong_end}. %{docs_link_start}Learn more%{link_end} about how to reduce your storage."
msgid "UsageQuota|The namespace is currently using %{strong_start}%{used_storage}%{strong_end} of namespace storage. View and manage your usage from %{strong_start}%{usage_quotas_nav_instruction}%{strong_end}. %{docs_link_start}Learn more%{link_end} about how to reduce your storage."
msgstr ""
msgid "UsageQuota|The table below shows current period usage"
@ -42344,6 +42350,9 @@ msgstr ""
msgid "UsageQuota|Usage quotas help link"
msgstr ""
msgid "UsageQuota|User settings &gt; Usage quotas"
msgstr ""
msgid "UsageQuota|When you purchase additional storage, we automatically unlock projects that were locked when you reached the %{actualRepositorySizeLimit} limit."
msgstr ""

View File

@ -36,7 +36,11 @@ module QA
group.add_member(developer_user, Resource::Members::AccessLevel::DEVELOPER)
end
it 'allows enforcing 2FA via UI and logging in with 2FA', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347931' do
it(
'allows enforcing 2FA via UI and logging in with 2FA',
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347931',
quarantine: { type: :flaky, issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/369516' }
) do
enforce_two_factor_authentication_on_group(group)
enable_two_factor_authentication_for_user(developer_user)

View File

@ -517,76 +517,4 @@ RSpec.describe 'Group' do
fill_in 'confirm_name_input', with: confirm_with
click_button 'Confirm'
end
describe 'storage_enforcement_banner', :js do
let_it_be_with_refind(:group) { create(:group, :with_root_storage_statistics) }
let_it_be_with_refind(:user) { create(:user) }
before do
group.root_storage_statistics.update!(storage_size: ::Namespace::MIN_STORAGE_ENFORCEMENT_USAGE)
group.add_owner(user)
sign_in(user)
end
context 'with storage_enforcement_date set' do
let_it_be(:storage_enforcement_date) { Date.today + 30 }
before do
allow_next_found_instance_of(Group) do |group|
allow(group).to receive(:storage_enforcement_date).and_return(storage_enforcement_date)
end
end
it 'displays the banner in the group page' do
visit group_path(group)
expect_page_to_have_storage_enforcement_banner(storage_enforcement_date)
end
it 'does not display the banner in a paid group page' do
allow_next_found_instance_of(Group) do |group|
allow(group).to receive(:paid?).and_return(true)
end
visit group_path(group)
expect_page_not_to_have_storage_enforcement_banner
end
it 'does not display the banner if user has previously closed unless threshold has changed' do
visit group_path(group)
expect_page_to_have_storage_enforcement_banner(storage_enforcement_date)
find('.js-storage-enforcement-banner [data-testid="close-icon"]').click
wait_for_requests
page.refresh
expect_page_not_to_have_storage_enforcement_banner
storage_enforcement_date = Date.today + 13
allow_next_found_instance_of(Group) do |group|
allow(group).to receive(:storage_enforcement_date).and_return(storage_enforcement_date)
end
page.refresh
expect_page_to_have_storage_enforcement_banner(storage_enforcement_date)
end
end
context 'with storage_enforcement_date not set' do
before do
allow_next_found_instance_of(Group) do |group|
allow(group).to receive(:storage_enforcement_date).and_return(nil)
end
end
it 'does not display the banner in the group page' do
stub_feature_flags(namespace_storage_limit_bypass_date_check: false)
visit group_path(group)
expect_page_not_to_have_storage_enforcement_banner
end
end
end
def expect_page_to_have_storage_enforcement_banner(storage_enforcement_date)
expect(page).to have_text "Effective #{storage_enforcement_date}, namespace storage limits will apply"
end
def expect_page_not_to_have_storage_enforcement_banner
expect(page).not_to have_text "namespace storage limits will apply"
end
end

View File

@ -87,69 +87,4 @@ RSpec.describe 'User visits their profile' do
end
end
end
describe 'storage_enforcement_banner', :js do
let_it_be(:root_storage_statistics) do
create(
:namespace_root_storage_statistics,
namespace: user.namespace,
storage_size: ::Namespace::MIN_STORAGE_ENFORCEMENT_USAGE
)
end
before do
stub_feature_flags(namespace_storage_limit_bypass_date_check: false)
end
context 'with storage_enforcement_date set' do
let_it_be(:storage_enforcement_date) { Date.today + 30 }
before do
allow_next_found_instance_of(Namespaces::UserNamespace) do |user_namespace|
allow(user_namespace).to receive(:storage_enforcement_date).and_return(storage_enforcement_date)
end
end
it 'displays the banner in the profile page' do
visit(profile_path)
expect_page_to_have_storage_enforcement_banner(storage_enforcement_date)
end
it 'does not display the banner if user has previously closed unless threshold has changed' do
visit(profile_path)
expect_page_to_have_storage_enforcement_banner(storage_enforcement_date)
find('.js-storage-enforcement-banner [data-testid="close-icon"]').click
page.refresh
expect_page_not_to_have_storage_enforcement_banner
storage_enforcement_date = Date.today + 13
allow_next_found_instance_of(Namespaces::UserNamespace) do |user_namespace|
allow(user_namespace).to receive(:storage_enforcement_date).and_return(storage_enforcement_date)
end
page.refresh
expect_page_to_have_storage_enforcement_banner(storage_enforcement_date)
end
end
context 'with storage_enforcement_date not set' do
before do
allow_next_found_instance_of(Namespaces::UserNamespace) do |user_namespace|
allow(user_namespace).to receive(:storage_enforcement_date).and_return(nil)
end
end
it 'does not display the banner in the group page' do
visit(profile_path)
expect_page_not_to_have_storage_enforcement_banner
end
end
end
def expect_page_to_have_storage_enforcement_banner(storage_enforcement_date)
expect(page).to have_text "Effective #{storage_enforcement_date}, namespace storage limits will apply"
end
def expect_page_not_to_have_storage_enforcement_banner
expect(page).not_to have_text "namespace storage limits will apply"
end
end

View File

@ -47,7 +47,7 @@ RSpec.describe 'User creates release', :js do
fill_out_form_and_submit
end
it 'creates a new release when "Create release" is clicked and redirects to the release\'s dedicated page', :aggregate_failures do
it 'creates a new release when "Create release" is clicked and redirects to the release\'s dedicated page', :aggregate_failures, :sidekiq_inline do
release = project.releases.last
expect(release.tag).to eq(tag_name)
@ -66,6 +66,11 @@ RSpec.describe 'User creates release', :js do
expect(link.url).to eq(link_2[:url])
expect(link.name).to eq(link_2[:title])
expect(release).not_to be_historical_release
expect(release).not_to be_upcoming_release
expect(release.evidences.length).to eq(1)
expect(page).to have_current_path(project_release_path(project, release))
end
end

View File

@ -440,110 +440,6 @@ RSpec.describe 'Project' do
end
end
describe 'storage_enforcement_banner', :js do
let_it_be_with_refind(:group) { create(:group, :with_root_storage_statistics) }
let_it_be_with_refind(:user) { create(:user) }
let_it_be(:project) { create(:project, group: group) }
before do
group.root_storage_statistics.update!(storage_size: ::Namespace::MIN_STORAGE_ENFORCEMENT_USAGE)
group.add_maintainer(user)
sign_in(user)
end
context 'with storage_enforcement_date set' do
let_it_be(:storage_enforcement_date) { Date.today + 30 }
before do
allow_next_found_instance_of(Group) do |group|
allow(group).to receive(:storage_enforcement_date).and_return(storage_enforcement_date)
end
end
it 'displays the banner in the project page' do
visit project_path(project)
expect_page_to_have_storage_enforcement_banner(storage_enforcement_date)
end
context 'when in a subgroup project page' do
let_it_be(:subgroup) { create(:group, parent: group) }
let_it_be(:project) { create(:project, namespace: subgroup) }
it 'displays the banner' do
visit project_path(project)
expect_page_to_have_storage_enforcement_banner(storage_enforcement_date)
end
end
context 'when in a user namespace project page' do
let_it_be_with_refind(:project) { create(:project, namespace: user.namespace) }
before do
create(
:namespace_root_storage_statistics,
namespace: user.namespace,
storage_size: ::Namespace::MIN_STORAGE_ENFORCEMENT_USAGE
)
allow_next_found_instance_of(Namespaces::UserNamespace) do |user_namespace|
allow(user_namespace).to receive(:storage_enforcement_date).and_return(storage_enforcement_date)
end
end
it 'displays the banner' do
visit project_path(project)
expect_page_to_have_storage_enforcement_banner(storage_enforcement_date)
end
end
it 'does not display the banner in a paid group project page' do
allow_next_found_instance_of(Group) do |group|
allow(group).to receive(:paid?).and_return(true)
end
visit project_path(project)
expect_page_not_to_have_storage_enforcement_banner
end
it 'does not display the banner if user has previously closed unless threshold has changed' do
visit project_path(project)
expect_page_to_have_storage_enforcement_banner(storage_enforcement_date)
find('.js-storage-enforcement-banner [data-testid="close-icon"]').click
wait_for_requests
page.refresh
expect_page_not_to_have_storage_enforcement_banner
storage_enforcement_date = Date.today + 13
allow_next_found_instance_of(Group) do |group|
allow(group).to receive(:storage_enforcement_date).and_return(storage_enforcement_date)
end
page.refresh
expect_page_to_have_storage_enforcement_banner(storage_enforcement_date)
end
end
context 'with storage_enforcement_date not set' do
before do
allow_next_found_instance_of(Group) do |group|
allow(group).to receive(:storage_enforcement_date).and_return(nil)
end
end
it 'does not display the banner in the group page' do
stub_feature_flags(namespace_storage_limit_bypass_date_check: false)
visit project_path(project)
expect_page_not_to_have_storage_enforcement_banner
end
end
end
def expect_page_to_have_storage_enforcement_banner(storage_enforcement_date)
expect(page).to have_text "Effective #{storage_enforcement_date}, namespace storage limits will apply"
end
def expect_page_not_to_have_storage_enforcement_banner
expect(page).not_to have_text "namespace storage limits will apply"
end
def remove_with_confirm(button_text, confirm_with, confirm_button_text = 'Confirm')
click_button button_text
fill_in 'confirm_name_input', with: confirm_with

View File

@ -17,7 +17,6 @@ describe('DiffCodeQuality', () => {
return mountFunction(DiffCodeQuality, {
propsData: {
expandedLines: [],
line: 1,
codeQuality,
},
});
@ -28,9 +27,7 @@ describe('DiffCodeQuality', () => {
expect(wrapper.findByTestId('diff-codequality').exists()).toBe(true);
await wrapper.findByTestId('diff-codequality-close').trigger('click');
expect(wrapper.emitted('hideCodeQualityFindings').length).toBe(1);
expect(wrapper.emitted().hideCodeQualityFindings[0][0]).toBe(wrapper.props('line'));
});
it('renders correct amount of list items for codequality array and their description', async () => {

View File

@ -0,0 +1,65 @@
import { shallowMount } from '@vue/test-utils';
import DiffLine from '~/diffs/components/diff_line.vue';
import DiffCodeQuality from '~/diffs/components/diff_code_quality.vue';
const EXAMPLE_LINE_NUMBER = 3;
const EXAMPLE_DESCRIPTION = 'example description';
const EXAMPLE_SEVERITY = 'example severity';
const left = {
line: {
left: {
codequality: [
{
line: EXAMPLE_LINE_NUMBER,
description: EXAMPLE_DESCRIPTION,
severity: EXAMPLE_SEVERITY,
},
],
},
},
};
const right = {
line: {
right: {
codequality: [
{
line: EXAMPLE_LINE_NUMBER,
description: EXAMPLE_DESCRIPTION,
severity: EXAMPLE_SEVERITY,
},
],
},
},
};
const mockData = [right, left];
describe('DiffLine', () => {
const createWrapper = (propsData) => {
return shallowMount(DiffLine, { propsData });
};
it('should emit event when hideCodeQualityFindings is called', () => {
const wrapper = createWrapper(right);
wrapper.findComponent(DiffCodeQuality).vm.$emit('hideCodeQualityFindings');
expect(wrapper.emitted()).toEqual({
hideCodeQualityFindings: [[EXAMPLE_LINE_NUMBER]],
});
});
mockData.forEach((element) => {
it('should set correct props for DiffCodeQuality', () => {
const wrapper = createWrapper(element);
expect(wrapper.findComponent(DiffCodeQuality).props('codeQuality')).toEqual([
{
line: EXAMPLE_LINE_NUMBER,
description: EXAMPLE_DESCRIPTION,
severity: EXAMPLE_SEVERITY,
},
]);
});
});
});

View File

@ -2,7 +2,7 @@ import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import DiffView from '~/diffs/components/diff_view.vue';
import DiffCodeQuality from '~/diffs/components/diff_code_quality.vue';
import DiffLine from '~/diffs/components/diff_line.vue';
import { diffCodeQuality } from '../mock_data/diff_code_quality';
describe('DiffView', () => {
@ -51,28 +51,27 @@ describe('DiffView', () => {
return shallowMount(DiffView, { propsData, store, stubs, provide });
};
it('does not render a codeQuality diff view when there is no finding', () => {
it('does not render a diff-line component when there is no finding', () => {
const wrapper = createWrapper();
expect(wrapper.findComponent(DiffCodeQuality).exists()).toBe(false);
expect(wrapper.findComponent(DiffLine).exists()).toBe(false);
});
it('does render a codeQuality diff view with the correct props when there is a finding & refactorCodeQualityInlineFindings flag is true ', async () => {
it('does render a diff-line component with the correct props when there is a finding & refactorCodeQualityInlineFindings flag is true ', async () => {
const wrapper = createWrapper(diffCodeQuality, {
glFeatures: { refactorCodeQualityInlineFindings: true },
});
wrapper.findComponent(DiffRow).vm.$emit('toggleCodeQualityFindings', 2);
await nextTick();
expect(wrapper.findComponent(DiffCodeQuality).exists()).toBe(true);
expect(wrapper.findComponent(DiffCodeQuality).props().codeQuality.length).not.toBe(0);
expect(wrapper.findComponent(DiffLine).props('line')).toBe(diffCodeQuality.diffLines[2]);
});
it('does not render a codeQuality diff view when there is a finding & refactorCodeQualityInlineFindings flag is false ', async () => {
it('does not render a diff-line component when there is a finding & refactorCodeQualityInlineFindings flag is false ', async () => {
const wrapper = createWrapper(diffCodeQuality, {
glFeatures: { refactorCodeQualityInlineFindings: false },
});
wrapper.findComponent(DiffRow).vm.$emit('toggleCodeQualityFindings', 2);
await nextTick();
expect(wrapper.findComponent(DiffCodeQuality).exists()).toBe(false);
expect(wrapper.findComponent(DiffLine).exists()).toBe(false);
});
it.each`

View File

@ -1,18 +1,46 @@
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
import { mountExtended } from 'helpers/vue_test_utils_helper';
import BranchRules from '~/projects/settings/repository/branch_rules/app.vue';
import BranchRules, { i18n } from '~/projects/settings/repository/branch_rules/app.vue';
import branchRulesQuery from '~/projects/settings/repository/branch_rules/graphql/queries/branch_rules.query.graphql';
import createFlash from '~/flash';
import { branchRulesMockResponse, propsDataMock } from './mock_data';
jest.mock('~/flash');
Vue.use(VueApollo);
describe('Branch rules app', () => {
let wrapper;
let fakeApollo;
const createComponent = () => {
wrapper = mountExtended(BranchRules);
const branchRulesQuerySuccessHandler = jest.fn().mockResolvedValue(branchRulesMockResponse);
const createComponent = async (branchRulesQueryHandler = branchRulesQuerySuccessHandler) => {
fakeApollo = createMockApollo([[branchRulesQuery, branchRulesQueryHandler]]);
wrapper = mountExtended(BranchRules, {
apolloProvider: fakeApollo,
propsData: {
...propsDataMock,
},
});
await waitForPromises();
};
const findTitle = () => wrapper.find('strong');
beforeEach(() => createComponent());
it('displays an error if branch rules query fails', async () => {
await createComponent(jest.fn().mockRejectedValue());
expect(createFlash).toHaveBeenCalledWith({ message: i18n.queryError });
});
it('renders a title', () => {
expect(findTitle().text()).toBe('Branch');
expect(findTitle().text()).toBe(i18n.heading);
});
});

View File

@ -0,0 +1,20 @@
export const branchRulesMockResponse = {
data: {
project: {
__typename: 'Project',
branchRules: {
__typename: 'BranchRuleConnection',
nodes: [
{
name: 'master',
__typename: 'BranchRule',
},
],
},
},
},
};
export const propsDataMock = {
projectPath: 'some/project/path',
};

View File

@ -50,149 +50,4 @@ RSpec.describe StorageHelper do
expect(helper.storage_counters_details(namespace_stats)).to eq(message)
end
end
describe "storage_enforcement_banner" do
let_it_be_with_refind(:current_user) { create(:user) }
let_it_be(:free_group) { create(:group, :with_root_storage_statistics) }
let_it_be(:paid_group) { create(:group, :with_root_storage_statistics) }
before do
allow(helper).to receive(:can?).with(current_user, :maintainer_access, free_group).and_return(true)
allow(helper).to receive(:can?).with(current_user, :maintainer_access, paid_group).and_return(true)
allow(helper).to receive(:current_user) { current_user }
allow(paid_group).to receive(:paid?).and_return(true)
free_group.root_storage_statistics.update!(storage_size: ::Namespace::MIN_STORAGE_ENFORCEMENT_USAGE)
paid_group.root_storage_statistics.update!(storage_size: ::Namespace::MIN_STORAGE_ENFORCEMENT_USAGE)
stub_feature_flags(namespace_storage_limit_bypass_date_check: false)
end
describe "#storage_enforcement_banner_info" do
it 'returns nil when namespace is not free' do
expect(helper.storage_enforcement_banner_info(paid_group)).to be(nil)
end
it 'returns nil when storage_enforcement_date is not set' do
allow(free_group).to receive(:storage_enforcement_date).and_return(nil)
expect(helper.storage_enforcement_banner_info(free_group)).to be(nil)
end
describe 'when storage_enforcement_date is set' do
let_it_be(:storage_enforcement_date) { Date.today + 30 }
before do
allow(free_group).to receive(:storage_enforcement_date).and_return(storage_enforcement_date)
end
it 'returns nil when current_user do not have access usage quotas page' do
allow(helper).to receive(:can?).with(current_user, :maintainer_access, free_group).and_return(false)
expect(helper.storage_enforcement_banner_info(free_group)).to be(nil)
end
it 'returns nil when namespace_storage_limit_show_preenforcement_banner FF is disabled' do
stub_feature_flags(namespace_storage_limit_show_preenforcement_banner: false)
expect(helper.storage_enforcement_banner_info(free_group)).to be(nil)
end
context 'when current_user can access the usage quotas page' do
it 'returns a hash' do
used_storage = helper.storage_counter(free_group.root_storage_statistics&.storage_size || 0)
expect(helper.storage_enforcement_banner_info(free_group)).to eql({
text_paragraph_1: "Effective #{storage_enforcement_date}, namespace storage limits will apply to the <strong>#{free_group.name}</strong> namespace. View the <a href=\"/help/user/usage_quotas#namespace-storage-limit-enforcement-schedule\" >rollout schedule for this change</a>.",
text_paragraph_2: "The namespace is currently using <strong>#{used_storage}</strong> of namespace storage. Group owners can view namespace storage usage and purchase more from <strong>Group settings &gt; Usage quotas</strong>. <a href=\"/help/user/usage_quotas#manage-your-storage-usage\" >Learn more.</a>",
text_paragraph_3: "See our <a href=\"https://about.gitlab.com/pricing/faq-efficient-free-tier/#storage-limits-on-gitlab-saas-free-tier\" >FAQ</a> for more information.",
variant: 'warning',
namespace_id: free_group.id,
callouts_feature_name: 'storage_enforcement_banner_second_enforcement_threshold',
callouts_path: '/-/users/group_callouts'
})
end
context 'when namespace is under MIN_STORAGE_ENFORCEMENT_USAGE limit' do
before do
free_group.root_storage_statistics.update!(storage_size: ::Namespace::MIN_STORAGE_ENFORCEMENT_USAGE - 1)
end
it 'returns nil' do
expect(helper.storage_enforcement_banner_info(free_group)).to be(nil)
end
end
context 'when the given group is a sub-group' do
let_it_be(:sub_group) { build(:group) }
before do
allow(helper).to receive(:can?).with(current_user, :maintainer_access, sub_group).and_return(true)
allow(sub_group).to receive(:root_ancestor).and_return(free_group)
end
it 'returns the banner hash' do
expect(helper.storage_enforcement_banner_info(sub_group).keys).to match_array(%i(text_paragraph_1 text_paragraph_2 text_paragraph_3 variant namespace_id callouts_feature_name callouts_path))
end
end
end
end
context 'when the :storage_banner_bypass_date_check is enabled', :freeze_time do
before do
stub_feature_flags(namespace_storage_limit_bypass_date_check: true)
end
it 'returns the enforcement info' do
expect(helper.storage_enforcement_banner_info(free_group)[:text_paragraph_1]).to include("Effective #{Date.current}, namespace storage limits will apply")
end
end
context 'when storage_enforcement_date is set and dismissed callout exists' do
before do
create(:group_callout,
user: current_user,
group_id: free_group.id,
feature_name: 'storage_enforcement_banner_second_enforcement_threshold')
storage_enforcement_date = Date.today + 30
allow(free_group).to receive(:storage_enforcement_date).and_return(storage_enforcement_date)
end
it { expect(helper.storage_enforcement_banner_info(free_group)).to be(nil) }
end
context 'callouts_feature_name' do
let(:days_from_now) { 45 }
subject do
storage_enforcement_date = Date.today + days_from_now
allow(free_group).to receive(:storage_enforcement_date).and_return(storage_enforcement_date)
helper.storage_enforcement_banner_info(free_group)[:callouts_feature_name]
end
it 'returns first callouts_feature_name' do
is_expected.to eq('storage_enforcement_banner_first_enforcement_threshold')
end
context 'returns second callouts_feature_name' do
let(:days_from_now) { 20 }
it { is_expected.to eq('storage_enforcement_banner_second_enforcement_threshold') }
end
context 'returns third callouts_feature_name' do
let(:days_from_now) { 13 }
it { is_expected.to eq('storage_enforcement_banner_third_enforcement_threshold') }
end
context 'returns fourth callouts_feature_name' do
let(:days_from_now) { 3 }
it { is_expected.to eq('storage_enforcement_banner_fourth_enforcement_threshold') }
end
end
end
end
end

View File

@ -2662,17 +2662,17 @@ RSpec.describe Ci::Build do
describe '#ref_slug' do
{
'master' => 'master',
'1-foo' => '1-foo',
'fix/1-foo' => 'fix-1-foo',
'fix-1-foo' => 'fix-1-foo',
'a' * 63 => 'a' * 63,
'a' * 64 => 'a' * 63,
'FOO' => 'foo',
'-' + 'a' * 61 + '-' => 'a' * 61,
'-' + 'a' * 62 + '-' => 'a' * 62,
'-' + 'a' * 63 + '-' => 'a' * 62,
'a' * 62 + ' ' => 'a' * 62
'master' => 'master',
'1-foo' => '1-foo',
'fix/1-foo' => 'fix-1-foo',
'fix-1-foo' => 'fix-1-foo',
'a' * 63 => 'a' * 63,
'a' * 64 => 'a' * 63,
'FOO' => 'foo',
'-' + 'a' * 61 + '-' => 'a' * 61,
'-' + 'a' * 62 + '-' => 'a' * 62,
'-' + 'a' * 63 + '-' => 'a' * 62,
'a' * 62 + ' ' => 'a' * 62
}.each do |ref, slug|
it "transforms #{ref} to #{slug}" do
build.ref = ref

View File

@ -30,10 +30,8 @@ RSpec.describe Ci::Processable do
let_it_be(:downstream_project) { create(:project, :repository) }
let_it_be_with_refind(:processable) do
create(
:ci_bridge, :success, pipeline: pipeline, downstream: downstream_project,
description: 'a trigger job', stage_id: stage.id
)
create(:ci_bridge, :success,
pipeline: pipeline, downstream: downstream_project, description: 'a trigger job', stage_id: stage.id)
end
let(:clone_accessors) { ::Ci::Bridge.clone_accessors }
@ -208,10 +206,11 @@ RSpec.describe Ci::Processable do
let(:environment_name) { 'review/$CI_COMMIT_REF_SLUG-$GITLAB_USER_ID' }
let!(:processable) do
create(:ci_build, :with_deployment, environment: environment_name,
options: { environment: { name: environment_name } },
pipeline: pipeline, stage_id: stage.id, project: project,
user: other_developer)
create(:ci_build, :with_deployment,
environment: environment_name,
options: { environment: { name: environment_name } },
pipeline: pipeline, stage_id: stage.id, project: project,
user: other_developer)
end
it 're-uses the previous persisted environment' do

View File

@ -605,15 +605,15 @@ RSpec.describe Clusters::Platforms::Kubernetes do
{ 'app.gitlab.com/app' => project.full_path_slug, 'app.gitlab.com/env' => 'env-000000' }
])
expect(rollout_status.instances).to eq([{ pod_name: "kube-pod",
stable: true,
status: "pending",
tooltip: "kube-pod (Pending)",
track: "stable" },
stable: true,
status: "pending",
tooltip: "kube-pod (Pending)",
track: "stable" },
{ pod_name: "Not provided",
stable: true,
status: "pending",
tooltip: "Not provided (Pending)",
track: "stable" }])
stable: true,
status: "pending",
tooltip: "Not provided (Pending)",
track: "stable" }])
end
context 'with canary ingress' do

View File

@ -144,7 +144,7 @@ RSpec.describe ContainerRegistry::Event do
let(:target) do
{
'mediaType' => ContainerRegistry::Client::DOCKER_DISTRIBUTION_MANIFEST_V2_TYPE,
'repository' => repository_path,
'repository' => repository_path,
'tag' => 'latest'
}
end

View File

@ -163,8 +163,8 @@ RSpec.describe Deployment do
it 'executes Deployments::HooksWorker asynchronously' do
freeze_time do
expect(Deployments::HooksWorker)
.to receive(:perform_async).with(deployment_id: deployment.id, status: 'running',
status_changed_at: Time.current)
.to receive(:perform_async)
.with(deployment_id: deployment.id, status: 'running', status_changed_at: Time.current)
deployment.run!
end
@ -200,8 +200,8 @@ RSpec.describe Deployment do
it 'executes Deployments::HooksWorker asynchronously' do
freeze_time do
expect(Deployments::HooksWorker)
.to receive(:perform_async).with(deployment_id: deployment.id, status: 'success',
status_changed_at: Time.current)
.to receive(:perform_async)
.with(deployment_id: deployment.id, status: 'success', status_changed_at: Time.current)
deployment.succeed!
end
@ -230,8 +230,8 @@ RSpec.describe Deployment do
it 'executes Deployments::HooksWorker asynchronously' do
freeze_time do
expect(Deployments::HooksWorker)
.to receive(:perform_async).with(deployment_id: deployment.id, status: 'failed',
status_changed_at: Time.current)
.to receive(:perform_async)
.with(deployment_id: deployment.id, status: 'failed', status_changed_at: Time.current)
deployment.drop!
end
@ -260,8 +260,8 @@ RSpec.describe Deployment do
it 'executes Deployments::HooksWorker asynchronously' do
freeze_time do
expect(Deployments::HooksWorker)
.to receive(:perform_async).with(deployment_id: deployment.id, status: 'canceled',
status_changed_at: Time.current)
.to receive(:perform_async)
.with(deployment_id: deployment.id, status: 'canceled', status_changed_at: Time.current)
deployment.cancel!
end

View File

@ -256,7 +256,7 @@ RSpec.describe DesignManagement::Version do
it 'puts them in the right buckets' do
expect(version.designs_by_event).to match(
a_hash_including(
'creation' => have_attributes(size: 3),
'creation' => have_attributes(size: 3),
'modification' => have_attributes(size: 4),
'deletion' => have_attributes(size: 5)
)

View File

@ -2139,8 +2139,7 @@ RSpec.describe Group do
let(:another_shared_with_group) { create(:group, parent: group) }
before do
create(:group_group_link, shared_group: nested_group,
shared_with_group: another_shared_with_group)
create(:group_group_link, shared_group: nested_group, shared_with_group: another_shared_with_group)
end
it 'returns all shared with group ids' do

View File

@ -49,8 +49,8 @@ RSpec.describe Integrations::ChatMessage::PipelineMessage do
allow(test_project).to receive(:avatar_url).with(only_path: false).and_return(args[:project][:avatar_url])
allow(Project).to receive(:find) { test_project }
test_pipeline = double("A test pipeline", has_yaml_errors?: has_yaml_errors,
yaml_errors: "yaml error description here")
test_pipeline = double("A test pipeline",
has_yaml_errors?: has_yaml_errors, yaml_errors: "yaml error description here")
allow(Ci::Pipeline).to receive(:find) { test_pipeline }
allow(Gitlab::UrlBuilder).to receive(:build).with(test_commit).and_return("http://example.com/commit")

View File

@ -175,9 +175,9 @@ RSpec.describe Integrations::DroneCi, :use_clean_rails_memory_store_caching do
end
{
"killed" => :canceled,
"killed" => :canceled,
"failure" => :failed,
"error" => :failed,
"error" => :failed,
"success" => "success"
}.each do |drone_status, our_status|
it "sets commit status to #{our_status.inspect} when returned status is #{drone_status.inspect}" do

View File

@ -3729,9 +3729,9 @@ RSpec.describe MergeRequest, factory_default: :keep do
let(:expected_diff_refs) do
Gitlab::Diff::DiffRefs.new(
base_sha: subject.merge_request_diff.base_commit_sha,
base_sha: subject.merge_request_diff.base_commit_sha,
start_sha: subject.merge_request_diff.start_commit_sha,
head_sha: subject.merge_request_diff.head_commit_sha
head_sha: subject.merge_request_diff.head_commit_sha
)
end

View File

@ -744,30 +744,30 @@ RSpec.describe Namespace do
create(:project,
namespace: namespace,
statistics: build(:project_statistics,
namespace: namespace,
repository_size: 101,
wiki_size: 505,
lfs_objects_size: 202,
build_artifacts_size: 303,
namespace: namespace,
repository_size: 101,
wiki_size: 505,
lfs_objects_size: 202,
build_artifacts_size: 303,
pipeline_artifacts_size: 707,
packages_size: 404,
snippets_size: 605,
uploads_size: 808))
packages_size: 404,
snippets_size: 605,
uploads_size: 808))
end
let(:project2) do
create(:project,
namespace: namespace,
statistics: build(:project_statistics,
namespace: namespace,
repository_size: 10,
wiki_size: 50,
lfs_objects_size: 20,
build_artifacts_size: 30,
namespace: namespace,
repository_size: 10,
wiki_size: 50,
lfs_objects_size: 20,
build_artifacts_size: 30,
pipeline_artifacts_size: 70,
packages_size: 40,
snippets_size: 60,
uploads_size: 80))
packages_size: 40,
snippets_size: 60,
uploads_size: 80))
end
it "sums all project storage counters in the namespace" do

View File

@ -55,7 +55,7 @@ RSpec.describe Operations::FeatureFlag do
it 'is valid if associated with Operations::FeatureFlags::Strategy models' do
project = create(:project)
feature_flag = described_class.create!({ name: 'test', project: project, version: 2,
strategies_attributes: [{ name: 'default', parameters: {} }] })
strategies_attributes: [{ name: 'default', parameters: {} }] })
expect(feature_flag).to be_valid
end
@ -114,13 +114,11 @@ RSpec.describe Operations::FeatureFlag do
let_it_be(:project) { create(:project) }
let!(:feature_flag) do
create(:operations_feature_flag, project: project,
name: 'feature1', active: true, version: 2)
create(:operations_feature_flag, project: project, name: 'feature1', active: true, version: 2)
end
let!(:strategy) do
create(:operations_strategy, feature_flag: feature_flag,
name: 'default', parameters: {})
create(:operations_strategy, feature_flag: feature_flag, name: 'default', parameters: {})
end
it 'matches wild cards in the scope' do
@ -141,10 +139,8 @@ RSpec.describe Operations::FeatureFlag do
it 'returns feature flags ordered by id' do
create(:operations_scope, strategy: strategy, environment_scope: 'production')
feature_flag_b = create(:operations_feature_flag, project: project,
name: 'feature2', active: true, version: 2)
strategy_b = create(:operations_strategy, feature_flag: feature_flag_b,
name: 'default', parameters: {})
feature_flag_b = create(:operations_feature_flag, project: project, name: 'feature2', active: true, version: 2)
strategy_b = create(:operations_strategy, feature_flag: feature_flag_b, name: 'default', parameters: {})
create(:operations_scope, strategy: strategy_b, environment_scope: '*')
flags = described_class.for_unleash_client(project, 'production')

View File

@ -32,17 +32,17 @@ RSpec.describe PagesDomain do
describe "hostname" do
{
'my.domain.com' => true,
'123.456.789' => true,
'0x12345.com' => true,
'0123123' => true,
'a-reserved.com' => true,
'my.domain.com' => true,
'123.456.789' => true,
'0x12345.com' => true,
'0123123' => true,
'a-reserved.com' => true,
'a.b-reserved.com' => true,
'reserved.com' => true,
'_foo.com' => false,
'a.reserved.com' => false,
'reserved.com' => true,
'_foo.com' => false,
'a.reserved.com' => false,
'a.b.reserved.com' => false,
nil => false
nil => false
}.each do |value, validity|
context "domain #{value.inspect} validity" do
before do
@ -66,8 +66,7 @@ RSpec.describe PagesDomain do
end
let(:pages_domain) do
build(:pages_domain, certificate: certificate, key: key,
auto_ssl_enabled: auto_ssl_enabled).tap do |pd|
build(:pages_domain, certificate: certificate, key: key, auto_ssl_enabled: auto_ssl_enabled).tap do |pd|
allow(pd).to receive(:project).and_return(project)
pd.valid?
end

View File

@ -359,10 +359,10 @@ RSpec.describe RemoteMirror, :mailer do
it 'resets all the columns when URL changes' do
remote_mirror.update!(last_error: Time.current,
last_update_at: Time.current,
last_successful_update_at: Time.current,
update_status: 'started',
error_notification_sent: true)
last_update_at: Time.current,
last_successful_update_at: Time.current,
update_status: 'started',
error_notification_sent: true)
expect { remote_mirror.update_attribute(:url, 'http://new.example.com') }
.to change { remote_mirror.last_error }.to(nil)

View File

@ -3306,7 +3306,7 @@ RSpec.describe Repository do
before do
storages = {
'default' => Gitlab::GitalyClient::StorageSettings.new('path' => 'tmp/tests/repositories'),
'picked' => Gitlab::GitalyClient::StorageSettings.new('path' => 'tmp/tests/repositories')
'picked' => Gitlab::GitalyClient::StorageSettings.new('path' => 'tmp/tests/repositories')
}
allow(Gitlab.config.repositories).to receive(:storages).and_return(storages)

View File

@ -2071,11 +2071,12 @@ RSpec.describe User do
context 'user has existing U2F registration' do
it 'returns false' do
device = U2F::FakeU2F.new(FFaker::BaconIpsum.characters(5))
create(:u2f_registration, name: 'my u2f device',
user: user,
certificate: Base64.strict_encode64(device.cert_raw),
key_handle: U2F.urlsafe_encode64(device.key_handle_raw),
public_key: Base64.strict_encode64(device.origin_public_key_raw))
create(:u2f_registration,
name: 'my u2f device',
user: user,
certificate: Base64.strict_encode64(device.cert_raw),
key_handle: U2F.urlsafe_encode64(device.key_handle_raw),
public_key: Base64.strict_encode64(device.origin_public_key_raw))
expect(user.two_factor_u2f_enabled?).to eq(false)
end
@ -2094,11 +2095,12 @@ RSpec.describe User do
context 'user has existing U2F registration' do
it 'returns true' do
device = U2F::FakeU2F.new(FFaker::BaconIpsum.characters(5))
create(:u2f_registration, name: 'my u2f device',
user: user,
certificate: Base64.strict_encode64(device.cert_raw),
key_handle: U2F.urlsafe_encode64(device.key_handle_raw),
public_key: Base64.strict_encode64(device.origin_public_key_raw))
create(:u2f_registration,
name: 'my u2f device',
user: user,
certificate: Base64.strict_encode64(device.cert_raw),
key_handle: U2F.urlsafe_encode64(device.key_handle_raw),
public_key: Base64.strict_encode64(device.origin_public_key_raw))
expect(user.two_factor_u2f_enabled?).to eq(true)
end

View File

@ -102,7 +102,7 @@ RSpec.describe ProjectPresenter do
expect(release).to be_truthy
expect(presenter.releases_anchor_data).to have_attributes(
is_link: true,
label: a_string_including("#{project.releases.count}"),
label: a_string_including("#{project.releases.count}"),
link: presenter.project_releases_path(project)
)
end
@ -216,7 +216,7 @@ RSpec.describe ProjectPresenter do
it 'returns storage data' do
expect(presenter.storage_anchor_data).to have_attributes(
is_link: true,
label: a_string_including('0 Bytes'),
label: a_string_including('0 Bytes'),
link: nil
)
end
@ -270,7 +270,7 @@ RSpec.describe ProjectPresenter do
it 'returns storage data without usage quotas link for non-admin users' do
expect(presenter.storage_anchor_data).to have_attributes(
is_link: true,
label: a_string_including('0 Bytes'),
label: a_string_including('0 Bytes'),
link: nil
)
end
@ -280,7 +280,7 @@ RSpec.describe ProjectPresenter do
expect(presenter.storage_anchor_data).to have_attributes(
is_link: true,
label: a_string_including('0 Bytes'),
label: a_string_including('0 Bytes'),
link: presenter.project_usage_quotas_path(project)
)
end
@ -293,7 +293,7 @@ RSpec.describe ProjectPresenter do
expect(release).to be_truthy
expect(presenter.releases_anchor_data).to have_attributes(
is_link: true,
label: a_string_including("#{project.releases.count}"),
label: a_string_including("#{project.releases.count}"),
link: presenter.project_releases_path(project)
)
end
@ -566,7 +566,7 @@ RSpec.describe ProjectPresenter do
it 'returns upload_anchor_data' do
expect(presenter.upload_anchor_data).to have_attributes(
is_link: false,
label: a_string_including('Upload file'),
label: a_string_including('Upload file'),
data: {
"can_push_code" => "true",
"original_branch" => "master",