From 0a70b104d06b27e1d391a7035fa0500e84daaef4 Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Fri, 2 Sep 2022 15:12:37 +0000 Subject: [PATCH] Add latest changes from gitlab-org/gitlab@master --- .rubocop_todo/layout/hash_alignment.yml | 17 -- .../diffs/components/diff_code_quality.vue | 6 +- .../diffs/components/diff_line.vue | 35 +++++ .../diffs/components/diff_view.vue | 16 +- .../settings/repository/branch_rules/app.vue | 36 ++++- .../queries/branch_rules.query.graphql | 10 ++ .../branch_rules/mount_branch_rules.js | 17 +- app/helpers/storage_helper.rb | 116 -------------- app/models/users/callout.rb | 8 +- app/models/users/group_callout.rb | 8 +- app/models/users/namespace_callout.rb | 8 +- app/views/layouts/group.html.haml | 2 +- .../_storage_enforcement_banner.html.haml | 15 -- app/views/layouts/profile.html.haml | 2 +- app/views/layouts/project.html.haml | 2 +- .../projects/branch_rules/_show.html.haml | 2 +- doc/administration/instance_limits.md | 4 +- locale/gitlab.pot | 13 +- .../1_manage/login/log_in_with_2fa_spec.rb | 6 +- spec/features/groups_spec.rb | 72 --------- .../profiles/user_visits_profile_spec.rb | 65 -------- .../releases/user_creates_release_spec.rb | 7 +- spec/features/projects_spec.rb | 104 ------------- .../components/diff_code_quality_spec.js | 3 - .../diffs/components/diff_line_spec.js | 65 ++++++++ .../diffs/components/diff_view_spec.js | 15 +- .../repository/branch_rules/app_spec.js | 36 ++++- .../repository/branch_rules/mock_data.js | 20 +++ spec/helpers/storage_helper_spec.rb | 145 ------------------ spec/models/ci/build_spec.rb | 22 +-- spec/models/ci/processable_spec.rb | 15 +- .../clusters/platforms/kubernetes_spec.rb | 16 +- spec/models/container_registry/event_spec.rb | 2 +- spec/models/deployment_spec.rb | 16 +- spec/models/design_management/version_spec.rb | 2 +- spec/models/group_spec.rb | 3 +- .../chat_message/pipeline_message_spec.rb | 4 +- spec/models/integrations/drone_ci_spec.rb | 4 +- spec/models/merge_request_spec.rb | 4 +- spec/models/namespace_spec.rb | 32 ++-- spec/models/operations/feature_flag_spec.rb | 14 +- spec/models/pages_domain_spec.rb | 21 ++- spec/models/remote_mirror_spec.rb | 8 +- spec/models/repository_spec.rb | 2 +- spec/models/user_spec.rb | 22 +-- spec/presenters/project_presenter_spec.rb | 12 +- 46 files changed, 363 insertions(+), 691 deletions(-) create mode 100644 app/assets/javascripts/diffs/components/diff_line.vue create mode 100644 app/assets/javascripts/projects/settings/repository/branch_rules/graphql/queries/branch_rules.query.graphql delete mode 100644 app/views/layouts/header/_storage_enforcement_banner.html.haml create mode 100644 spec/frontend/diffs/components/diff_line_spec.js create mode 100644 spec/frontend/projects/settings/repository/branch_rules/mock_data.js diff --git a/.rubocop_todo/layout/hash_alignment.yml b/.rubocop_todo/layout/hash_alignment.yml index eafd3d58c65..a1d2c3813c6 100644 --- a/.rubocop_todo/layout/hash_alignment.yml +++ b/.rubocop_todo/layout/hash_alignment.yml @@ -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' diff --git a/app/assets/javascripts/diffs/components/diff_code_quality.vue b/app/assets/javascripts/diffs/components/diff_code_quality.vue index f339b108a11..b91696526f5 100644 --- a/app/assets/javascripts/diffs/components/diff_code_quality.vue +++ b/app/assets/javascripts/diffs/components/diff_code_quality.vue @@ -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')" /> diff --git a/app/assets/javascripts/diffs/components/diff_line.vue b/app/assets/javascripts/diffs/components/diff_line.vue new file mode 100644 index 00000000000..448272549d3 --- /dev/null +++ b/app/assets/javascripts/diffs/components/diff_line.vue @@ -0,0 +1,35 @@ + + + diff --git a/app/assets/javascripts/diffs/components/diff_view.vue b/app/assets/javascripts/diffs/components/diff_view.vue index ea94df1ad5b..03a5f5bebe3 100644 --- a/app/assets/javascripts/diffs/components/diff_view.vue +++ b/app/assets/javascripts/diffs/components/diff_view.vue @@ -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" /> - -
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: [], + }; + }, }; diff --git a/app/assets/javascripts/projects/settings/repository/branch_rules/graphql/queries/branch_rules.query.graphql b/app/assets/javascripts/projects/settings/repository/branch_rules/graphql/queries/branch_rules.query.graphql new file mode 100644 index 00000000000..104a0c25a80 --- /dev/null +++ b/app/assets/javascripts/projects/settings/repository/branch_rules/graphql/queries/branch_rules.query.graphql @@ -0,0 +1,10 @@ +query getBranchRules($projectPath: ID!) { + project(fullPath: $projectPath) { + id + branchRules { + nodes { + name + } + } + } +} diff --git a/app/assets/javascripts/projects/settings/repository/branch_rules/mount_branch_rules.js b/app/assets/javascripts/projects/settings/repository/branch_rules/mount_branch_rules.js index abe0b93081e..35322e2e466 100644 --- a/app/assets/javascripts/projects/settings/repository/branch_rules/mount_branch_rules.js +++ b/app/assets/javascripts/projects/settings/repository/branch_rules/mount_branch_rules.js @@ -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, + }, + }); }, }); } diff --git a/app/helpers/storage_helper.rb b/app/helpers/storage_helper.rb index f42f0de6e1e..a60143db739 100644 --- a/app/helpers/storage_helper.rb +++ b/app/helpers/storage_helper.rb @@ -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 > 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 > 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: "".html_safe, - strong_end: "".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: ''.html_safe % { url: help_page_path('user/usage_quotas', anchor: 'namespace-storage-limit-enforcement-schedule') }, - link_end: "".html_safe - }.merge(strong_tags), - p2: { - used_storage: storage_counter(root_ancestor.root_storage_statistics&.storage_size || 0), - docs_link_start: ''.html_safe % { url: help_page_path('user/usage_quotas', anchor: 'manage-your-storage-usage') }, - link_end: "".html_safe - }.merge(strong_tags), - p3: { - faq_link_start: ''.html_safe % { url: "#{Gitlab::Saas.about_pricing_url}faq-efficient-free-tier/#storage-limits-on-gitlab-saas-free-tier" }, - link_end: "".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 diff --git a/app/models/users/callout.rb b/app/models/users/callout.rb index a84335c0908..c9b6b859d45 100644 --- a/app/models/users/callout.rb +++ b/app/models/users/callout.rb @@ -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. diff --git a/app/models/users/group_callout.rb b/app/models/users/group_callout.rb index 70498ae83e0..3e3e424e9c9 100644 --- a/app/models/users/group_callout.rb +++ b/app/models/users/group_callout.rb @@ -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 diff --git a/app/models/users/namespace_callout.rb b/app/models/users/namespace_callout.rb index a20a196a4ef..4e655a96b57 100644 --- a/app/models/users/namespace_callout.rb +++ b/app/models/users/namespace_callout.rb @@ -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 diff --git a/app/views/layouts/group.html.haml b/app/views/layouts/group.html.haml index 67809cbc608..5a043704b76 100644 --- a/app/views/layouts/group.html.haml +++ b/app/views/layouts/group.html.haml @@ -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 diff --git a/app/views/layouts/header/_storage_enforcement_banner.html.haml b/app/views/layouts/header/_storage_enforcement_banner.html.haml deleted file mode 100644 index 1f7060f8235..00000000000 --- a/app/views/layouts/header/_storage_enforcement_banner.html.haml +++ /dev/null @@ -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] diff --git a/app/views/layouts/profile.html.haml b/app/views/layouts/profile.html.haml index 1ec839ef642..1b6e78b7b3d 100644 --- a/app/views/layouts/profile.html.haml +++ b/app/views/layouts/profile.html.haml @@ -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" diff --git a/app/views/layouts/project.html.haml b/app/views/layouts/project.html.haml index 9e5819c5189..75d5e40011c 100644 --- a/app/views/layouts/project.html.haml +++ b/app/views/layouts/project.html.haml @@ -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 diff --git a/app/views/projects/branch_rules/_show.html.haml b/app/views/projects/branch_rules/_show.html.haml index af0e656d301..46665fdb450 100644 --- a/app/views/projects/branch_rules/_show.html.haml +++ b/app/views/projects/branch_rules/_show.html.haml @@ -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 } } diff --git a/doc/administration/instance_limits.md b/doc/administration/instance_limits.md index 8d3091cc831..ab2fc814f6b 100644 --- a/doc/administration/instance_limits.md +++ b/doc/administration/instance_limits.md @@ -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 diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 985c1ecdbb1..01a583dadb5 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -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 > 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 > 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 > 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 > Usage quotas" +msgstr "" + msgid "UsageQuota|When you purchase additional storage, we automatically unlock projects that were locked when you reached the %{actualRepositorySizeLimit} limit." msgstr "" diff --git a/qa/qa/specs/features/browser_ui/1_manage/login/log_in_with_2fa_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/login/log_in_with_2fa_spec.rb index c5efa833f04..ad90df4b90d 100644 --- a/qa/qa/specs/features/browser_ui/1_manage/login/log_in_with_2fa_spec.rb +++ b/qa/qa/specs/features/browser_ui/1_manage/login/log_in_with_2fa_spec.rb @@ -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) diff --git a/spec/features/groups_spec.rb b/spec/features/groups_spec.rb index 65cb8770662..4e02f6f7ca2 100644 --- a/spec/features/groups_spec.rb +++ b/spec/features/groups_spec.rb @@ -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 diff --git a/spec/features/profiles/user_visits_profile_spec.rb b/spec/features/profiles/user_visits_profile_spec.rb index 4859e796954..df096c2f151 100644 --- a/spec/features/profiles/user_visits_profile_spec.rb +++ b/spec/features/profiles/user_visits_profile_spec.rb @@ -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 diff --git a/spec/features/projects/releases/user_creates_release_spec.rb b/spec/features/projects/releases/user_creates_release_spec.rb index 10c4395da81..d82c4229b71 100644 --- a/spec/features/projects/releases/user_creates_release_spec.rb +++ b/spec/features/projects/releases/user_creates_release_spec.rb @@ -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 diff --git a/spec/features/projects_spec.rb b/spec/features/projects_spec.rb index d9030b9ec89..9dcf3c5ab99 100644 --- a/spec/features/projects_spec.rb +++ b/spec/features/projects_spec.rb @@ -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 diff --git a/spec/frontend/diffs/components/diff_code_quality_spec.js b/spec/frontend/diffs/components/diff_code_quality_spec.js index 81a817c47dc..b5dce4fc924 100644 --- a/spec/frontend/diffs/components/diff_code_quality_spec.js +++ b/spec/frontend/diffs/components/diff_code_quality_spec.js @@ -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 () => { diff --git a/spec/frontend/diffs/components/diff_line_spec.js b/spec/frontend/diffs/components/diff_line_spec.js new file mode 100644 index 00000000000..37368eb1461 --- /dev/null +++ b/spec/frontend/diffs/components/diff_line_spec.js @@ -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, + }, + ]); + }); + }); +}); diff --git a/spec/frontend/diffs/components/diff_view_spec.js b/spec/frontend/diffs/components/diff_view_spec.js index 15923a1c6de..c681d0cf7f9 100644 --- a/spec/frontend/diffs/components/diff_view_spec.js +++ b/spec/frontend/diffs/components/diff_view_spec.js @@ -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` diff --git a/spec/frontend/projects/settings/repository/branch_rules/app_spec.js b/spec/frontend/projects/settings/repository/branch_rules/app_spec.js index e12c3aeedd6..618944329fb 100644 --- a/spec/frontend/projects/settings/repository/branch_rules/app_spec.js +++ b/spec/frontend/projects/settings/repository/branch_rules/app_spec.js @@ -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); }); }); diff --git a/spec/frontend/projects/settings/repository/branch_rules/mock_data.js b/spec/frontend/projects/settings/repository/branch_rules/mock_data.js new file mode 100644 index 00000000000..2b8468ead0e --- /dev/null +++ b/spec/frontend/projects/settings/repository/branch_rules/mock_data.js @@ -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', +}; diff --git a/spec/helpers/storage_helper_spec.rb b/spec/helpers/storage_helper_spec.rb index d42dd51b2a1..6c0f1034d65 100644 --- a/spec/helpers/storage_helper_spec.rb +++ b/spec/helpers/storage_helper_spec.rb @@ -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 #{free_group.name} namespace. View the rollout schedule for this change.", - text_paragraph_2: "The namespace is currently using #{used_storage} of namespace storage. Group owners can view namespace storage usage and purchase more from Group settings > Usage quotas. Learn more.", - text_paragraph_3: "See our FAQ 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 diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb index e5b6e88f399..eac8115742d 100644 --- a/spec/models/ci/build_spec.rb +++ b/spec/models/ci/build_spec.rb @@ -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 diff --git a/spec/models/ci/processable_spec.rb b/spec/models/ci/processable_spec.rb index 360b7de961b..594f9b679ec 100644 --- a/spec/models/ci/processable_spec.rb +++ b/spec/models/ci/processable_spec.rb @@ -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 diff --git a/spec/models/clusters/platforms/kubernetes_spec.rb b/spec/models/clusters/platforms/kubernetes_spec.rb index a0ede9fb0d9..7b9ff409edd 100644 --- a/spec/models/clusters/platforms/kubernetes_spec.rb +++ b/spec/models/clusters/platforms/kubernetes_spec.rb @@ -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 diff --git a/spec/models/container_registry/event_spec.rb b/spec/models/container_registry/event_spec.rb index 799d9d4fd1c..c2c494c49fb 100644 --- a/spec/models/container_registry/event_spec.rb +++ b/spec/models/container_registry/event_spec.rb @@ -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 diff --git a/spec/models/deployment_spec.rb b/spec/models/deployment_spec.rb index 2fdca7114eb..d9a1ade4400 100644 --- a/spec/models/deployment_spec.rb +++ b/spec/models/deployment_spec.rb @@ -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 diff --git a/spec/models/design_management/version_spec.rb b/spec/models/design_management/version_spec.rb index 519ba3c67b4..44ecae82174 100644 --- a/spec/models/design_management/version_spec.rb +++ b/spec/models/design_management/version_spec.rb @@ -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) ) diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb index 2a994ce9ff7..170ac657b84 100644 --- a/spec/models/group_spec.rb +++ b/spec/models/group_spec.rb @@ -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 diff --git a/spec/models/integrations/chat_message/pipeline_message_spec.rb b/spec/models/integrations/chat_message/pipeline_message_spec.rb index 68ef0ccb2e4..a63cc0b6d83 100644 --- a/spec/models/integrations/chat_message/pipeline_message_spec.rb +++ b/spec/models/integrations/chat_message/pipeline_message_spec.rb @@ -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") diff --git a/spec/models/integrations/drone_ci_spec.rb b/spec/models/integrations/drone_ci_spec.rb index 8a51f8a0705..905fee075ad 100644 --- a/spec/models/integrations/drone_ci_spec.rb +++ b/spec/models/integrations/drone_ci_spec.rb @@ -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 diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb index 24014c6c5f3..1f02849cdb9 100644 --- a/spec/models/merge_request_spec.rb +++ b/spec/models/merge_request_spec.rb @@ -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 diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb index 71ce3afda44..ea63e27a5fe 100644 --- a/spec/models/namespace_spec.rb +++ b/spec/models/namespace_spec.rb @@ -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 diff --git a/spec/models/operations/feature_flag_spec.rb b/spec/models/operations/feature_flag_spec.rb index e709470b312..85a475f5c53 100644 --- a/spec/models/operations/feature_flag_spec.rb +++ b/spec/models/operations/feature_flag_spec.rb @@ -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') diff --git a/spec/models/pages_domain_spec.rb b/spec/models/pages_domain_spec.rb index 4e463b1194c..4691d38184a 100644 --- a/spec/models/pages_domain_spec.rb +++ b/spec/models/pages_domain_spec.rb @@ -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 diff --git a/spec/models/remote_mirror_spec.rb b/spec/models/remote_mirror_spec.rb index 429ad550626..adb4777ae90 100644 --- a/spec/models/remote_mirror_spec.rb +++ b/spec/models/remote_mirror_spec.rb @@ -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) diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb index 47532ed1216..04c263223b2 100644 --- a/spec/models/repository_spec.rb +++ b/spec/models/repository_spec.rb @@ -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) diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 8921b6d208a..3487bf7b70e 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -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 diff --git a/spec/presenters/project_presenter_spec.rb b/spec/presenters/project_presenter_spec.rb index 5eeaea8de06..f6bc3048092 100644 --- a/spec/presenters/project_presenter_spec.rb +++ b/spec/presenters/project_presenter_spec.rb @@ -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",