diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-03-07 03:07:43 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-03-07 03:07:43 +0000 |
commit | d0db90848503511d758f29c16a93a1e2b1c3da47 (patch) | |
tree | 58240f1bc91479c60d78114ecccaa97516e9245a | |
parent | defeeba1a8d6fa8784db1c50ca4ff9e8b56f539c (diff) | |
download | gitlab-ce-d0db90848503511d758f29c16a93a1e2b1c3da47.tar.gz |
Add latest changes from gitlab-org/gitlab@master
53 files changed, 500 insertions, 296 deletions
diff --git a/.rubocop_todo/layout/argument_alignment.yml b/.rubocop_todo/layout/argument_alignment.yml index 63c0b722055..e442a2a8856 100644 --- a/.rubocop_todo/layout/argument_alignment.yml +++ b/.rubocop_todo/layout/argument_alignment.yml @@ -108,7 +108,6 @@ Layout/ArgumentAlignment: - 'app/graphql/mutations/jira_import/import_users.rb' - 'app/graphql/mutations/jira_import/start.rb' - 'app/graphql/mutations/labels/create.rb' - - 'app/graphql/mutations/members/groups/bulk_update.rb' - 'app/graphql/mutations/merge_requests/accept.rb' - 'app/graphql/mutations/merge_requests/base.rb' - 'app/graphql/mutations/merge_requests/create.rb' diff --git a/.rubocop_todo/lint/unused_method_argument.yml b/.rubocop_todo/lint/unused_method_argument.yml index 8c23a6ae84b..a4e48b35248 100644 --- a/.rubocop_todo/lint/unused_method_argument.yml +++ b/.rubocop_todo/lint/unused_method_argument.yml @@ -19,7 +19,6 @@ Lint/UnusedMethodArgument: - 'app/graphql/mutations/base_mutation.rb' - 'app/graphql/mutations/ci/runner/delete.rb' - 'app/graphql/mutations/concerns/mutations/assignable.rb' - - 'app/graphql/mutations/members/groups/bulk_update.rb' - 'app/graphql/mutations/notes/create/base.rb' - 'app/graphql/mutations/notes/create/diff_note.rb' - 'app/graphql/mutations/notes/create/image_diff_note.rb' diff --git a/.rubocop_todo/style/mutable_constant.yml b/.rubocop_todo/style/mutable_constant.yml index 2409d4f3521..8e6a0a2335b 100644 --- a/.rubocop_todo/style/mutable_constant.yml +++ b/.rubocop_todo/style/mutable_constant.yml @@ -5,7 +5,6 @@ Style/MutableConstant: Exclude: - 'app/finders/group_members_finder.rb' - 'app/graphql/mutations/container_repositories/destroy_tags.rb' - - 'app/graphql/mutations/members/groups/bulk_update.rb' - 'app/graphql/mutations/packages/bulk_destroy.rb' - 'app/helpers/blame_helper.rb' - 'app/models/ci/build_trace_chunks/redis_base.rb' diff --git a/app/assets/javascripts/syntax_highlight.js b/app/assets/javascripts/syntax_highlight.js index cb2bf24abc7..065e1080897 100644 --- a/app/assets/javascripts/syntax_highlight.js +++ b/app/assets/javascripts/syntax_highlight.js @@ -15,6 +15,10 @@ export default function syntaxHighlight($els = null) { const els = $els.get ? $els.get() : $els; const handler = (el) => { + if (el.classList === undefined) { + return el; + } + if (el.classList.contains('js-syntax-highlight')) { // Given the element itself, apply highlighting return el.classList.add(gon.user_color_scheme); diff --git a/app/graphql/mutations/members/bulk_update_base.rb b/app/graphql/mutations/members/bulk_update_base.rb new file mode 100644 index 00000000000..1e0208e864d --- /dev/null +++ b/app/graphql/mutations/members/bulk_update_base.rb @@ -0,0 +1,88 @@ +# frozen_string_literal: true + +module Mutations + module Members + class BulkUpdateBase < BaseMutation + include ::API::Helpers::MembersHelpers + + argument :user_ids, + [::Types::GlobalIDType[::User]], + required: true, + description: 'Global IDs of the members.' + + argument :access_level, + ::Types::MemberAccessLevelEnum, + required: true, + description: 'Access level to update the members to.' + + argument :expires_at, + Types::TimeType, + required: false, + description: 'Date and time the membership expires.' + + MAX_MEMBERS_UPDATE_LIMIT = 50 + MAX_MEMBERS_UPDATE_ERROR = "Count of members to be updated should be less than #{MAX_MEMBERS_UPDATE_LIMIT}." + .freeze + INVALID_MEMBERS_ERROR = 'Only access level of direct members can be updated.' + + def resolve(**args) + result = ::Members::UpdateService + .new(current_user, args.except(:user_ids, source_id_param_name)) + .execute(@updatable_members) + + { + source_members_key => result[:members], + errors: Array.wrap(result[:message]) + } + rescue Gitlab::Access::AccessDeniedError + { + errors: ["Unable to update members, please check user permissions."] + } + end + + private + + def ready?(**args) + source = authorized_find!(source_id: args[source_id_param_name]) + user_ids = args.fetch(:user_ids, {}).map(&:model_id) + @updatable_members = only_direct_members(source, user_ids) + + if @updatable_members.size > MAX_MEMBERS_UPDATE_LIMIT + raise Gitlab::Graphql::Errors::InvalidMemberCountError, MAX_MEMBERS_UPDATE_ERROR + end + + if @updatable_members.size != user_ids.size + raise Gitlab::Graphql::Errors::InvalidMembersError, INVALID_MEMBERS_ERROR + end + + super + end + + def find_object(source_id:) + GitlabSchema.object_from_id(source_id, expected_type: source_type) + end + + def only_direct_members(source, user_ids) + source_members(source) + .with_user(user_ids) + .to_a + end + + def source_id_param_name + "#{source_name}_id".to_sym + end + + def source_members_key + "#{source_name}_members".to_sym + end + + def source_name + source_type.name.downcase + end + + def source_type + raise NotImplementedError + end + end + end +end diff --git a/app/graphql/mutations/members/groups/bulk_update.rb b/app/graphql/mutations/members/groups/bulk_update.rb index d0b19bd9634..fe3c7521c20 100644 --- a/app/graphql/mutations/members/groups/bulk_update.rb +++ b/app/graphql/mutations/members/groups/bulk_update.rb @@ -3,81 +3,22 @@ module Mutations module Members module Groups - class BulkUpdate < ::Mutations::BaseMutation + class BulkUpdate < BulkUpdateBase graphql_name 'GroupMemberBulkUpdate' - - include Gitlab::Utils::StrongMemoize - authorize :admin_group_member field :group_members, - [Types::GroupMemberType], - null: true, - description: 'Group members after mutation.' + [Types::GroupMemberType], + null: true, + description: 'Group members after mutation.' argument :group_id, - ::Types::GlobalIDType[::Group], - required: true, - description: 'Global ID of the group.' - - argument :user_ids, - [::Types::GlobalIDType[::User]], - required: true, - description: 'Global IDs of the group members.' - - argument :access_level, - ::Types::MemberAccessLevelEnum, - required: true, - description: 'Access level to update the members to.' - - argument :expires_at, - Types::TimeType, - required: false, - description: 'Date and time the membership expires.' - - MAX_MEMBERS_UPDATE_LIMIT = 50 - MAX_MEMBERS_UPDATE_ERROR = "Count of members to be updated should be less than #{MAX_MEMBERS_UPDATE_LIMIT}." - INVALID_MEMBERS_ERROR = 'Only access level of direct members can be updated.' - - def resolve(group_id:, **args) - result = ::Members::UpdateService.new(current_user, args.except(:user_ids)).execute(@updatable_group_members) - - { - group_members: result[:members], - errors: Array.wrap(result[:message]) - } - rescue Gitlab::Access::AccessDeniedError - { - errors: ["Unable to update members, please check user permissions."] - } - end - - private - - def ready?(**args) - group = authorized_find!(group_id: args[:group_id]) - user_ids = args.fetch(:user_ids, {}).map(&:model_id) - @updatable_group_members = only_direct_group_members(group, user_ids) - - if @updatable_group_members.size > MAX_MEMBERS_UPDATE_LIMIT - raise Gitlab::Graphql::Errors::InvalidMemberCountError, MAX_MEMBERS_UPDATE_ERROR - end - - if @updatable_group_members.size != user_ids.size - raise Gitlab::Graphql::Errors::InvalidMembersError, INVALID_MEMBERS_ERROR - end - - super - end - - def find_object(group_id:) - GitlabSchema.object_from_id(group_id, expected_type: ::Group) - end + ::Types::GlobalIDType[::Group], + required: true, + description: 'Global ID of the group.' - def only_direct_group_members(group, user_ids) - group - .members - .with_user(user_ids).to_a + def source_type + ::Group end end end diff --git a/app/graphql/mutations/members/projects/bulk_update.rb b/app/graphql/mutations/members/projects/bulk_update.rb new file mode 100644 index 00000000000..cfb88e60c44 --- /dev/null +++ b/app/graphql/mutations/members/projects/bulk_update.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +module Mutations + module Members + module Projects + class BulkUpdate < BulkUpdateBase + graphql_name 'ProjectMemberBulkUpdate' + authorize :admin_project_member + + field :project_members, + [Types::ProjectMemberType], + null: true, + description: 'Project members after mutation.' + + argument :project_id, + ::Types::GlobalIDType[::Project], + required: true, + description: 'Global ID of the project.' + + def source_type + ::Project + end + end + end + end +end diff --git a/app/graphql/types/mutation_type.rb b/app/graphql/types/mutation_type.rb index 08ac6d7f658..108c55f1292 100644 --- a/app/graphql/types/mutation_type.rb +++ b/app/graphql/types/mutation_type.rb @@ -70,6 +70,7 @@ module Types mount_mutation Mutations::Issues::BulkUpdate, alpha: { milestone: '15.9' } mount_mutation Mutations::Labels::Create mount_mutation Mutations::Members::Groups::BulkUpdate + mount_mutation Mutations::Members::Projects::BulkUpdate mount_mutation Mutations::MergeRequests::Accept mount_mutation Mutations::MergeRequests::Create mount_mutation Mutations::MergeRequests::Update diff --git a/app/helpers/diff_helper.rb b/app/helpers/diff_helper.rb index e0a1697cfa9..c5df53ec606 100644 --- a/app/helpers/diff_helper.rb +++ b/app/helpers/diff_helper.rb @@ -34,6 +34,12 @@ module DiffHelper options[:expanded] = true options[:paths] = params.values_at(:old_path, :new_path) options[:use_extra_viewer_as_main] = false + + if Feature.enabled?(:large_ipynb_diffs, @project) && params[:file_identifier]&.include?('.ipynb') + options[:max_patch_bytes_for_file_extension] = { + '.ipynb' => 1.megabyte + } + end end options diff --git a/app/views/projects/compare/index.html.haml b/app/views/projects/compare/index.html.haml index b3590eea631..58da76a3231 100644 --- a/app/views/projects/compare/index.html.haml +++ b/app/views/projects/compare/index.html.haml @@ -1,5 +1,5 @@ -- breadcrumb_title _("Compare Revisions") -- page_title _("Compare") +- breadcrumb_title _("Compare revisions") +- page_title _("Compare revisions") %h1.page-title.gl-font-size-h-display = _("Compare Git revisions") diff --git a/app/views/projects/compare/show.html.haml b/app/views/projects/compare/show.html.haml index 1bdf3d1e6e3..bc378182057 100644 --- a/app/views/projects/compare/show.html.haml +++ b/app/views/projects/compare/show.html.haml @@ -1,4 +1,4 @@ -- add_to_breadcrumbs _("Compare Revisions"), project_compare_index_path(@project) +- add_to_breadcrumbs _("Compare revisions"), project_compare_index_path(@project) - page_title "#{params[:from]}...#{params[:to]}" .sub-header-block.gl-border-b-0.gl-mb-0 diff --git a/app/views/projects/graphs/show.html.haml b/app/views/projects/graphs/show.html.haml index 754de2db8f3..9d6f67bd190 100644 --- a/app/views/projects/graphs/show.html.haml +++ b/app/views/projects/graphs/show.html.haml @@ -1,4 +1,4 @@ -- page_title _('Contributors') +- page_title _('Contributor statistics') - graph_path = project_graph_path(@project, current_ref, ref_type: @ref_type, format: :json) - commits_path = project_commits_path(@project, current_ref, ref_type: @ref_type) diff --git a/config/feature_flags/development/large_ipynb_diffs.yml b/config/feature_flags/development/large_ipynb_diffs.yml new file mode 100644 index 00000000000..fd1f8f487e6 --- /dev/null +++ b/config/feature_flags/development/large_ipynb_diffs.yml @@ -0,0 +1,8 @@ +--- +name: large_ipynb_diffs +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/113370 +rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/393886 +milestone: '15.10' +type: development +group: group::incubation +default_enabled: false diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md index 701070b11d7..5ab6c40960f 100644 --- a/doc/api/graphql/reference/index.md +++ b/doc/api/graphql/reference/index.md @@ -3185,7 +3185,7 @@ Input type: `GroupMemberBulkUpdateInput` | <a id="mutationgroupmemberbulkupdateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. | | <a id="mutationgroupmemberbulkupdateexpiresat"></a>`expiresAt` | [`Time`](#time) | Date and time the membership expires. | | <a id="mutationgroupmemberbulkupdategroupid"></a>`groupId` | [`GroupID!`](#groupid) | Global ID of the group. | -| <a id="mutationgroupmemberbulkupdateuserids"></a>`userIds` | [`[UserID!]!`](#userid) | Global IDs of the group members. | +| <a id="mutationgroupmemberbulkupdateuserids"></a>`userIds` | [`[UserID!]!`](#userid) | Global IDs of the members. | #### Fields @@ -4715,6 +4715,28 @@ Input type: `ProjectInitializeProductAnalyticsInput` | <a id="mutationprojectinitializeproductanalyticserrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. | | <a id="mutationprojectinitializeproductanalyticsproject"></a>`project` | [`Project`](#project) | Project on which the initialization took place. | +### `Mutation.projectMemberBulkUpdate` + +Input type: `ProjectMemberBulkUpdateInput` + +#### Arguments + +| Name | Type | Description | +| ---- | ---- | ----------- | +| <a id="mutationprojectmemberbulkupdateaccesslevel"></a>`accessLevel` | [`MemberAccessLevel!`](#memberaccesslevel) | Access level to update the members to. | +| <a id="mutationprojectmemberbulkupdateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. | +| <a id="mutationprojectmemberbulkupdateexpiresat"></a>`expiresAt` | [`Time`](#time) | Date and time the membership expires. | +| <a id="mutationprojectmemberbulkupdateprojectid"></a>`projectId` | [`ProjectID!`](#projectid) | Global ID of the project. | +| <a id="mutationprojectmemberbulkupdateuserids"></a>`userIds` | [`[UserID!]!`](#userid) | Global IDs of the members. | + +#### Fields + +| Name | Type | Description | +| ---- | ---- | ----------- | +| <a id="mutationprojectmemberbulkupdateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. | +| <a id="mutationprojectmemberbulkupdateerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. | +| <a id="mutationprojectmemberbulkupdateprojectmembers"></a>`projectMembers` | [`[ProjectMember!]`](#projectmember) | Project members after mutation. | + ### `Mutation.projectSetComplianceFramework` Assign (or unset) a compliance framework to a project. diff --git a/doc/architecture/blueprints/search/code_search_with_zoekt.md b/doc/architecture/blueprints/code_search_with_zoekt/index.md index ca74460b98a..ca74460b98a 100644 --- a/doc/architecture/blueprints/search/code_search_with_zoekt.md +++ b/doc/architecture/blueprints/code_search_with_zoekt/index.md diff --git a/doc/user/project/file_lock.md b/doc/user/project/file_lock.md index d6351483b60..b83feda0c96 100644 --- a/doc/user/project/file_lock.md +++ b/doc/user/project/file_lock.md @@ -221,7 +221,7 @@ To view the user who locked the file (if it was not you), hover over the button. To view and remove file locks: 1. On the top bar, select **Main menu > Projects** and find your project. -1. On the left sidebar, select **Repository > Locked Files**. +1. On the left sidebar, select **Repository > Locked files**. This list shows all the files locked either through LFS or GitLab UI. diff --git a/doc/user/project/repository/branches/index.md b/doc/user/project/repository/branches/index.md index 8169956c02e..13ee6fcdc91 100644 --- a/doc/user/project/repository/branches/index.md +++ b/doc/user/project/repository/branches/index.md @@ -62,7 +62,7 @@ issue number. GitLab uses the issue number to import data into the merge request To compare branches in a repository: 1. On the top bar, select **Main menu > Projects** and find your project. -1. On the left sidebar, select **Repository > Compare**. +1. On the left sidebar, select **Repository > Compare revisions**. 1. Select the **Source** branch to search for your desired branch. Exact matches are shown first. You can refine your search with operators: - `^` matches the beginning of the branch name: `^feat` matches `feat/user-authentication`. diff --git a/doc/user/project/repository/index.md b/doc/user/project/repository/index.md index 5b4e1b14489..1d32dd3973d 100644 --- a/doc/user/project/repository/index.md +++ b/doc/user/project/repository/index.md @@ -235,9 +235,9 @@ The size can differ slightly from one instance to another due to compression, ho Administrators can set a [repository size limit](../../admin_area/settings/account_and_limit_settings.md). [GitLab sets the size limits for GitLab.com](../../gitlab_com/index.md#account-and-limit-settings). -## Repository contributor graph +## Repository contributor statistics -All code contributors are displayed under your project's **Repository > Contributors**. +All code contributors are displayed under your project's **Repository > Contributor statistics**. The graph shows the contributor with the most commits to the fewest. diff --git a/lib/gitlab/git/diff_collection.rb b/lib/gitlab/git/diff_collection.rb index 0ffe8bee953..b4dd880ceb7 100644 --- a/lib/gitlab/git/diff_collection.rb +++ b/lib/gitlab/git/diff_collection.rb @@ -24,6 +24,8 @@ module Gitlab limits[:safe_max_lines] = [limits[:max_lines], defaults[:max_lines]].min limits[:safe_max_bytes] = limits[:safe_max_files] * 5.kilobytes # Average 5 KB per file limits[:max_patch_bytes] = Gitlab::Git::Diff.patch_hard_limit_bytes + limits[:max_patch_bytes_for_file_extension] = options.fetch(:max_patch_bytes_for_file_extension, {}) + limits end diff --git a/lib/sidebars/projects/menus/repository_menu.rb b/lib/sidebars/projects/menus/repository_menu.rb index ec91ae741fe..5bfc9e727ff 100644 --- a/lib/sidebars/projects/menus/repository_menu.rb +++ b/lib/sidebars/projects/menus/repository_menu.rb @@ -92,7 +92,7 @@ module Sidebars link = project_graph_path(context.project, context.current_ref, ref_type: ref_type_from_context(context)) ::Sidebars::MenuItem.new( - title: _('Contributors'), + title: _('Contributor statistics'), link: link, active_routes: { path: 'graphs#show' }, item_id: :contributors @@ -112,7 +112,7 @@ module Sidebars def compare_menu_item ::Sidebars::MenuItem.new( - title: _('Compare'), + title: _('Compare revisions'), link: project_compare_index_path(context.project, from: context.project.repository.root_ref, to: context.current_ref), active_routes: { controller: :compare }, item_id: :compare diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 29eb4f9dd47..f58b7d5124a 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -10390,9 +10390,6 @@ msgstr "" msgid "Compare GitLab plans" msgstr "" -msgid "Compare Revisions" -msgstr "" - msgid "Compare branches and continue" msgstr "" @@ -10405,6 +10402,9 @@ msgstr "" msgid "Compare changes with the merge request target branch" msgstr "" +msgid "Compare revisions" +msgstr "" + msgid "Compare submodule commit revisions" msgstr "" @@ -11401,7 +11401,7 @@ msgstr "" msgid "Contributor" msgstr "" -msgid "Contributors" +msgid "Contributor statistics" msgstr "" msgid "Control emails linked to your account" @@ -25756,9 +25756,6 @@ msgstr "" msgid "Locked" msgstr "" -msgid "Locked Files" -msgstr "" - msgid "Locked by %{fileLockUserName}" msgstr "" diff --git a/qa/qa/page/project/sub_menus/repository.rb b/qa/qa/page/project/sub_menus/repository.rb index f9d55c0009c..b8ebaa10a49 100644 --- a/qa/qa/page/project/sub_menus/repository.rb +++ b/qa/qa/page/project/sub_menus/repository.rb @@ -40,7 +40,7 @@ module QA def go_to_repository_contributors hover_repository do within_submenu do - click_element(:sidebar_menu_item_link, menu_item: 'Contributors') + click_element(:sidebar_menu_item_link, menu_item: 'Contributor statistics') end end end diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/server_hooks_custom_error_message_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide/server_hooks_custom_error_message_spec.rb index 080832990c9..8082c54a6ee 100644 --- a/qa/qa/specs/features/browser_ui/3_create/web_ide/server_hooks_custom_error_message_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/web_ide/server_hooks_custom_error_message_spec.rb @@ -1,13 +1,8 @@ # frozen_string_literal: true +# TODO: remove this test when 'vscode_web_ide' feature flag is default enabled module QA - RSpec.describe 'Create', :skip_live_env, except: { job: 'review-qa-*' }, - feature_flag: { name: 'vscode_web_ide', scope: :global }, - product_group: :editor, - quarantine: { - issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/387928', - type: :stale - } do + RSpec.describe 'Create', :skip_live_env, except: { job: 'review-qa-*' }, product_group: :editor do describe 'Git Server Hooks' do let(:file_path) { File.join(Runtime::Path.fixtures_path, 'web_ide', 'README.md') } @@ -20,15 +15,10 @@ module QA end before do - Runtime::Feature.disable(:vscode_web_ide) Flow::Login.sign_in project.visit! end - after do - Runtime::Feature.enable(:vscode_web_ide) - end - context 'with custom error messages' do it 'renders preconfigured error message when user hook failed on commit in WebIDE', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/364751' do diff --git a/spec/features/merge_request/user_sees_real_time_reviewers_spec.rb b/spec/features/merge_request/user_sees_real_time_reviewers_spec.rb new file mode 100644 index 00000000000..e967787d2c7 --- /dev/null +++ b/spec/features/merge_request/user_sees_real_time_reviewers_spec.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Merge request > Real-time reviewers', feature_category: :code_review_workflow do + let_it_be(:project) { create(:project, :public, :repository) } + let(:user) { project.creator } + let(:merge_request) { create(:merge_request, :simple, source_project: project, author: user) } + + before do + sign_in(user) + visit project_merge_request_path(project, merge_request) + end + + it 'updates in real-time', :js do + wait_for_requests + + # Simulate a real-time update of reviewers + merge_request.update!(reviewer_ids: [user.id]) + GraphqlTriggers.merge_request_reviewers_updated(merge_request) + + expect(find('.reviewer')).to have_content(user.name) + end +end diff --git a/spec/frontend/access_tokens/components/new_access_token_app_spec.js b/spec/frontend/access_tokens/components/new_access_token_app_spec.js index e4313bdfa26..753e693cc85 100644 --- a/spec/frontend/access_tokens/components/new_access_token_app_spec.js +++ b/spec/frontend/access_tokens/components/new_access_token_app_spec.js @@ -4,12 +4,12 @@ import { setHTMLFixture, resetHTMLFixture } from 'helpers/fixtures'; import { mountExtended } from 'helpers/vue_test_utils_helper'; import NewAccessTokenApp from '~/access_tokens/components/new_access_token_app.vue'; import { EVENT_ERROR, EVENT_SUCCESS, FORM_SELECTOR } from '~/access_tokens/components/constants'; -import { createAlert, VARIANT_INFO } from '~/flash'; +import { createAlert, VARIANT_INFO } from '~/alert'; import { __, sprintf } from '~/locale'; import DomElementListener from '~/vue_shared/components/dom_element_listener.vue'; import InputCopyToggleVisibility from '~/vue_shared/components/form/input_copy_toggle_visibility.vue'; -jest.mock('~/flash'); +jest.mock('~/alert'); describe('~/access_tokens/components/new_access_token_app', () => { let wrapper; diff --git a/spec/frontend/contributors/store/actions_spec.js b/spec/frontend/contributors/store/actions_spec.js index 72b22548aa2..a15b9ad2978 100644 --- a/spec/frontend/contributors/store/actions_spec.js +++ b/spec/frontend/contributors/store/actions_spec.js @@ -2,11 +2,11 @@ import MockAdapter from 'axios-mock-adapter'; import testAction from 'helpers/vuex_action_helper'; import * as actions from '~/contributors/stores/actions'; import * as types from '~/contributors/stores/mutation_types'; -import { createAlert } from '~/flash'; +import { createAlert } from '~/alert'; import axios from '~/lib/utils/axios_utils'; import { HTTP_STATUS_BAD_REQUEST, HTTP_STATUS_OK } from '~/lib/utils/http_status'; -jest.mock('~/flash'); +jest.mock('~/alert'); describe('Contributors store actions', () => { describe('fetchChartData', () => { @@ -38,7 +38,7 @@ describe('Contributors store actions', () => { ); }); - it('should show flash on API error', async () => { + it('should show alert on API error', async () => { mock.onGet().reply(HTTP_STATUS_BAD_REQUEST, 'Not Found'); await testAction( diff --git a/spec/frontend/deploy_freeze/store/actions_spec.js b/spec/frontend/deploy_freeze/store/actions_spec.js index cd823e1fc28..d39577baa59 100644 --- a/spec/frontend/deploy_freeze/store/actions_spec.js +++ b/spec/frontend/deploy_freeze/store/actions_spec.js @@ -4,14 +4,14 @@ import Api from '~/api'; import * as actions from '~/deploy_freeze/store/actions'; import * as types from '~/deploy_freeze/store/mutation_types'; import getInitialState from '~/deploy_freeze/store/state'; -import { createAlert } from '~/flash'; +import { createAlert } from '~/alert'; import * as logger from '~/lib/logger'; import axios from '~/lib/utils/axios_utils'; import { freezePeriodsFixture } from '../helpers'; import { timezoneDataFixture } from '../../vue_shared/components/timezone_dropdown/helpers'; jest.mock('~/api.js'); -jest.mock('~/flash'); +jest.mock('~/alert'); describe('deploy freeze store actions', () => { const freezePeriodFixture = freezePeriodsFixture[0]; diff --git a/spec/frontend/filtered_search/filtered_search_manager_spec.js b/spec/frontend/filtered_search/filtered_search_manager_spec.js index 26af7af701b..8c16ff100eb 100644 --- a/spec/frontend/filtered_search/filtered_search_manager_spec.js +++ b/spec/frontend/filtered_search/filtered_search_manager_spec.js @@ -8,11 +8,11 @@ import IssuableFilteredSearchTokenKeys from '~/filtered_search/issuable_filtered import RecentSearchesRoot from '~/filtered_search/recent_searches_root'; import RecentSearchesService from '~/filtered_search/services/recent_searches_service'; import RecentSearchesServiceError from '~/filtered_search/services/recent_searches_service_error'; -import { createAlert } from '~/flash'; +import { createAlert } from '~/alert'; import { BACKSPACE_KEY_CODE, DELETE_KEY_CODE } from '~/lib/utils/keycodes'; import { visitUrl, getParameterByName } from '~/lib/utils/url_utility'; -jest.mock('~/flash'); +jest.mock('~/alert'); jest.mock('~/lib/utils/url_utility', () => ({ ...jest.requireActual('~/lib/utils/url_utility'), getParameterByName: jest.fn(), diff --git a/spec/frontend/filtered_search/visual_token_value_spec.js b/spec/frontend/filtered_search/visual_token_value_spec.js index d3fa8fae9ab..138a4e183a9 100644 --- a/spec/frontend/filtered_search/visual_token_value_spec.js +++ b/spec/frontend/filtered_search/visual_token_value_spec.js @@ -5,11 +5,11 @@ import FilteredSearchSpecHelper from 'helpers/filtered_search_spec_helper'; import { TEST_HOST } from 'helpers/test_constants'; import DropdownUtils from '~/filtered_search/dropdown_utils'; import VisualTokenValue from '~/filtered_search/visual_token_value'; -import { createAlert } from '~/flash'; +import { createAlert } from '~/alert'; import AjaxCache from '~/lib/utils/ajax_cache'; import UsersCache from '~/lib/utils/users_cache'; -jest.mock('~/flash'); +jest.mock('~/alert'); describe('Filtered Search Visual Tokens', () => { const findElements = (tokenElement) => { diff --git a/spec/frontend/groups/components/app_spec.js b/spec/frontend/groups/components/app_spec.js index 4e6ddd89a55..ec397cc44f9 100644 --- a/spec/frontend/groups/components/app_spec.js +++ b/spec/frontend/groups/components/app_spec.js @@ -3,7 +3,7 @@ import AxiosMockAdapter from 'axios-mock-adapter'; import Vue, { nextTick } from 'vue'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import waitForPromises from 'helpers/wait_for_promises'; -import { createAlert } from '~/flash'; +import { createAlert } from '~/alert'; import appComponent from '~/groups/components/app.vue'; import groupFolderComponent from '~/groups/components/group_folder.vue'; import groupItemComponent from '~/groups/components/group_item.vue'; @@ -34,7 +34,7 @@ import { const $toast = { show: jest.fn(), }; -jest.mock('~/flash'); +jest.mock('~/alert'); describe('AppComponent', () => { let wrapper; @@ -117,7 +117,7 @@ describe('AppComponent', () => { }); }); - it('should show flash error when request fails', () => { + it('should show alert error when request fails', () => { mock.onGet('/dashboard/groups.json').reply(HTTP_STATUS_BAD_REQUEST); jest.spyOn(window, 'scrollTo').mockImplementation(() => {}); @@ -325,7 +325,7 @@ describe('AppComponent', () => { }); }); - it('should show error flash message if request failed to leave group', () => { + it('should show error alert message if request failed to leave group', () => { const message = 'An error occurred. Please try again.'; jest .spyOn(vm.service, 'leaveGroup') @@ -342,7 +342,7 @@ describe('AppComponent', () => { }); }); - it('should show appropriate error flash message if request forbids to leave group', () => { + it('should show appropriate error alert message if request forbids to leave group', () => { const message = 'Failed to leave the group. Please make sure you are not the only owner.'; jest.spyOn(vm.service, 'leaveGroup').mockRejectedValue({ status: HTTP_STATUS_FORBIDDEN }); jest.spyOn(vm.store, 'removeGroup'); diff --git a/spec/frontend/groups/components/group_name_and_path_spec.js b/spec/frontend/groups/components/group_name_and_path_spec.js index 9965b608f27..0a18e657c94 100644 --- a/spec/frontend/groups/components/group_name_and_path_spec.js +++ b/spec/frontend/groups/components/group_name_and_path_spec.js @@ -7,11 +7,11 @@ import waitForPromises from 'helpers/wait_for_promises'; import createMockApollo from 'helpers/mock_apollo_helper'; import GroupNameAndPath from '~/groups/components/group_name_and_path.vue'; import { getGroupPathAvailability } from '~/rest_api'; -import { createAlert } from '~/flash'; +import { createAlert } from '~/alert'; import { helpPagePath } from '~/helpers/help_page_helper'; import searchGroupsWhereUserCanCreateSubgroups from '~/groups/queries/search_groups_where_user_can_create_subgroups.query.graphql'; -jest.mock('~/flash'); +jest.mock('~/alert'); jest.mock('~/rest_api', () => ({ getGroupPathAvailability: jest.fn(), })); diff --git a/spec/frontend/header_search/store/actions_spec.js b/spec/frontend/header_search/store/actions_spec.js index bd93b0edadf..95a619ebeca 100644 --- a/spec/frontend/header_search/store/actions_spec.js +++ b/spec/frontend/header_search/store/actions_spec.js @@ -16,7 +16,7 @@ import { MOCK_ISSUE_PATH, } from '../mock_data'; -jest.mock('~/flash'); +jest.mock('~/alert'); describe('Header Search Store Actions', () => { let state; diff --git a/spec/frontend/issuable/related_issues/components/related_issues_root_spec.js b/spec/frontend/issuable/related_issues/components/related_issues_root_spec.js index 96c0b87e2cb..337a7c9a175 100644 --- a/spec/frontend/issuable/related_issues/components/related_issues_root_spec.js +++ b/spec/frontend/issuable/related_issues/components/related_issues_root_spec.js @@ -7,7 +7,7 @@ import { issuable1, issuable2, } from 'jest/issuable/components/related_issuable_mock_data'; -import { createAlert } from '~/flash'; +import { createAlert } from '~/alert'; import axios from '~/lib/utils/axios_utils'; import { HTTP_STATUS_CONFLICT, @@ -19,7 +19,7 @@ import RelatedIssuesBlock from '~/related_issues/components/related_issues_block import RelatedIssuesRoot from '~/related_issues/components/related_issues_root.vue'; import relatedIssuesService from '~/related_issues/services/related_issues_service'; -jest.mock('~/flash'); +jest.mock('~/alert'); describe('RelatedIssuesRoot', () => { let wrapper; diff --git a/spec/frontend/merge_request_spec.js b/spec/frontend/merge_request_spec.js index 579cee8c022..be16b5ebfd2 100644 --- a/spec/frontend/merge_request_spec.js +++ b/spec/frontend/merge_request_spec.js @@ -3,12 +3,12 @@ import $ from 'jquery'; import { loadHTMLFixture, resetHTMLFixture } from 'helpers/fixtures'; import { TEST_HOST } from 'spec/test_constants'; import waitForPromises from 'helpers/wait_for_promises'; -import { createAlert } from '~/flash'; +import { createAlert } from '~/alert'; import axios from '~/lib/utils/axios_utils'; import { HTTP_STATUS_CONFLICT, HTTP_STATUS_OK } from '~/lib/utils/http_status'; import MergeRequest from '~/merge_request'; -jest.mock('~/flash'); +jest.mock('~/alert'); describe('MergeRequest', () => { const test = {}; diff --git a/spec/frontend/pipelines/components/jobs/failed_jobs_app_spec.js b/spec/frontend/pipelines/components/jobs/failed_jobs_app_spec.js index d1da7cb3acf..24732e71d5d 100644 --- a/spec/frontend/pipelines/components/jobs/failed_jobs_app_spec.js +++ b/spec/frontend/pipelines/components/jobs/failed_jobs_app_spec.js @@ -4,7 +4,7 @@ import Vue from 'vue'; import VueApollo from 'vue-apollo'; import createMockApollo from 'helpers/mock_apollo_helper'; import waitForPromises from 'helpers/wait_for_promises'; -import { createAlert } from '~/flash'; +import { createAlert } from '~/alert'; import FailedJobsApp from '~/pipelines/components/jobs/failed_jobs_app.vue'; import FailedJobsTable from '~/pipelines/components/jobs/failed_jobs_table.vue'; import GetFailedJobsQuery from '~/pipelines/graphql/queries/get_failed_jobs.query.graphql'; @@ -12,7 +12,7 @@ import { mockFailedJobsQueryResponse, mockFailedJobsSummaryData } from '../../mo Vue.use(VueApollo); -jest.mock('~/flash'); +jest.mock('~/alert'); describe('Failed Jobs App', () => { let wrapper; diff --git a/spec/frontend/pipelines/components/jobs/failed_jobs_table_spec.js b/spec/frontend/pipelines/components/jobs/failed_jobs_table_spec.js index 0df15afd70d..e2bb8906128 100644 --- a/spec/frontend/pipelines/components/jobs/failed_jobs_table_spec.js +++ b/spec/frontend/pipelines/components/jobs/failed_jobs_table_spec.js @@ -4,7 +4,7 @@ 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 { createAlert } from '~/flash'; +import { createAlert } from '~/alert'; import { redirectTo } from '~/lib/utils/url_utility'; import FailedJobsTable from '~/pipelines/components/jobs/failed_jobs_table.vue'; import RetryFailedJobMutation from '~/pipelines/graphql/mutations/retry_failed_job.mutation.graphql'; @@ -15,7 +15,7 @@ import { mockPreparedFailedJobsDataNoPermission, } from '../../mock_data'; -jest.mock('~/flash'); +jest.mock('~/alert'); jest.mock('~/lib/utils/url_utility'); Vue.use(VueApollo); diff --git a/spec/frontend/pipelines/components/jobs/jobs_app_spec.js b/spec/frontend/pipelines/components/jobs/jobs_app_spec.js index 9bc14266593..26dee132690 100644 --- a/spec/frontend/pipelines/components/jobs/jobs_app_spec.js +++ b/spec/frontend/pipelines/components/jobs/jobs_app_spec.js @@ -4,7 +4,7 @@ import Vue from 'vue'; import VueApollo from 'vue-apollo'; import createMockApollo from 'helpers/mock_apollo_helper'; import waitForPromises from 'helpers/wait_for_promises'; -import { createAlert } from '~/flash'; +import { createAlert } from '~/alert'; import JobsApp from '~/pipelines/components/jobs/jobs_app.vue'; import JobsTable from '~/jobs/components/table/jobs_table.vue'; import getPipelineJobsQuery from '~/pipelines/graphql/queries/get_pipeline_jobs.query.graphql'; @@ -12,7 +12,7 @@ import { mockPipelineJobsQueryResponse } from '../../mock_data'; Vue.use(VueApollo); -jest.mock('~/flash'); +jest.mock('~/alert'); describe('Jobs app', () => { let wrapper; diff --git a/spec/frontend/pipelines/pipelines_actions_spec.js b/spec/frontend/pipelines/pipelines_actions_spec.js index e034d52a33c..3b2a7c0a76d 100644 --- a/spec/frontend/pipelines/pipelines_actions_spec.js +++ b/spec/frontend/pipelines/pipelines_actions_spec.js @@ -5,7 +5,7 @@ import { nextTick } from 'vue'; import { mockTracking, unmockTracking } from 'helpers/tracking_helper'; import waitForPromises from 'helpers/wait_for_promises'; import { TEST_HOST } from 'spec/test_constants'; -import { createAlert } from '~/flash'; +import { createAlert } from '~/alert'; import axios from '~/lib/utils/axios_utils'; import { HTTP_STATUS_INTERNAL_SERVER_ERROR, HTTP_STATUS_OK } from '~/lib/utils/http_status'; import { confirmAction } from '~/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal'; @@ -13,7 +13,7 @@ import PipelinesManualActions from '~/pipelines/components/pipelines_list/pipeli import GlCountdown from '~/vue_shared/components/gl_countdown.vue'; import { TRACKING_CATEGORIES } from '~/pipelines/constants'; -jest.mock('~/flash'); +jest.mock('~/alert'); jest.mock('~/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal'); describe('Pipelines Actions dropdown', () => { diff --git a/spec/frontend/pipelines/pipelines_spec.js b/spec/frontend/pipelines/pipelines_spec.js index 2523b901506..67478f9307f 100644 --- a/spec/frontend/pipelines/pipelines_spec.js +++ b/spec/frontend/pipelines/pipelines_spec.js @@ -11,7 +11,7 @@ import { mockTracking } from 'helpers/tracking_helper'; import { extendedWrapper } from 'helpers/vue_test_utils_helper'; import waitForPromises from 'helpers/wait_for_promises'; import Api from '~/api'; -import { createAlert, VARIANT_WARNING } from '~/flash'; +import { createAlert, VARIANT_WARNING } from '~/alert'; import axios from '~/lib/utils/axios_utils'; import { HTTP_STATUS_INTERNAL_SERVER_ERROR, HTTP_STATUS_OK } from '~/lib/utils/http_status'; import NavigationControls from '~/pipelines/components/pipelines_list/nav_controls.vue'; @@ -25,7 +25,7 @@ import TablePagination from '~/vue_shared/components/pagination/table_pagination import { stageReply, users, mockSearch, branches } from './mock_data'; -jest.mock('~/flash'); +jest.mock('~/alert'); const mockProjectPath = 'twitter/flight'; const mockProjectId = '21'; diff --git a/spec/frontend/pipelines/test_reports/stores/actions_spec.js b/spec/frontend/pipelines/test_reports/stores/actions_spec.js index e813a63a53f..e05d2151f0a 100644 --- a/spec/frontend/pipelines/test_reports/stores/actions_spec.js +++ b/spec/frontend/pipelines/test_reports/stores/actions_spec.js @@ -2,13 +2,13 @@ import MockAdapter from 'axios-mock-adapter'; import testReports from 'test_fixtures/pipelines/test_report.json'; import { TEST_HOST } from 'helpers/test_constants'; import testAction from 'helpers/vuex_action_helper'; -import { createAlert } from '~/flash'; +import { createAlert } from '~/alert'; import axios from '~/lib/utils/axios_utils'; import { HTTP_STATUS_OK } from '~/lib/utils/http_status'; import * as actions from '~/pipelines/stores/test_reports/actions'; import * as types from '~/pipelines/stores/test_reports/mutation_types'; -jest.mock('~/flash'); +jest.mock('~/alert'); describe('Actions TestReports Store', () => { let mock; @@ -49,7 +49,7 @@ describe('Actions TestReports Store', () => { ); }); - it('should create flash on API error', async () => { + it('should create alert on API error', async () => { await testAction( actions.fetchSummary, null, diff --git a/spec/frontend/pipelines/test_reports/stores/mutations_spec.js b/spec/frontend/pipelines/test_reports/stores/mutations_spec.js index 82c70c6db58..9c374ea817a 100644 --- a/spec/frontend/pipelines/test_reports/stores/mutations_spec.js +++ b/spec/frontend/pipelines/test_reports/stores/mutations_spec.js @@ -1,9 +1,9 @@ import testReports from 'test_fixtures/pipelines/test_report.json'; import * as types from '~/pipelines/stores/test_reports/mutation_types'; import mutations from '~/pipelines/stores/test_reports/mutations'; -import { createAlert } from '~/flash'; +import { createAlert } from '~/alert'; -jest.mock('~/flash'); +jest.mock('~/alert'); describe('Mutations TestReports Store', () => { let mockState; @@ -58,7 +58,7 @@ describe('Mutations TestReports Store', () => { expect(mockState.errorMessage).toBe(message); }); - it('should show a flash message otherwise', () => { + it('should show an alert message otherwise', () => { mutations[types.SET_SUITE_ERROR](mockState, {}); expect(createAlert).toHaveBeenCalled(); diff --git a/spec/frontend/search/store/actions_spec.js b/spec/frontend/search/store/actions_spec.js index 0f270ff2491..cf0d4492305 100644 --- a/spec/frontend/search/store/actions_spec.js +++ b/spec/frontend/search/store/actions_spec.js @@ -1,7 +1,7 @@ import MockAdapter from 'axios-mock-adapter'; import testAction from 'helpers/vuex_action_helper'; import Api from '~/api'; -import { createAlert } from '~/flash'; +import { createAlert } from '~/alert'; import * as logger from '~/lib/logger'; import axios from '~/lib/utils/axios_utils'; import { HTTP_STATUS_INTERNAL_SERVER_ERROR, HTTP_STATUS_OK } from '~/lib/utils/http_status'; @@ -33,7 +33,7 @@ import { MOCK_AGGREGATIONS, } from '../mock_data'; -jest.mock('~/flash'); +jest.mock('~/alert'); jest.mock('~/lib/utils/url_utility', () => ({ setUrlParams: jest.fn(), joinPaths: jest.fn().mockReturnValue(''), @@ -47,7 +47,7 @@ describe('Global Search Store Actions', () => { let mock; let state; - const flashCallback = (callCount) => { + const alertCallback = (callCount) => { expect(createAlert).toHaveBeenCalledTimes(callCount); createAlert.mockClear(); }; @@ -63,12 +63,12 @@ describe('Global Search Store Actions', () => { }); describe.each` - action | axiosMock | type | expectedMutations | flashCallCount + action | axiosMock | type | expectedMutations | alertCallCount ${actions.fetchGroups} | ${{ method: 'onGet', code: HTTP_STATUS_OK, res: MOCK_GROUPS }} | ${'success'} | ${[{ type: types.REQUEST_GROUPS }, { type: types.RECEIVE_GROUPS_SUCCESS, payload: MOCK_GROUPS }]} | ${0} ${actions.fetchGroups} | ${{ method: 'onGet', code: HTTP_STATUS_INTERNAL_SERVER_ERROR, res: null }} | ${'error'} | ${[{ type: types.REQUEST_GROUPS }, { type: types.RECEIVE_GROUPS_ERROR }]} | ${1} ${actions.fetchProjects} | ${{ method: 'onGet', code: HTTP_STATUS_OK, res: MOCK_PROJECTS }} | ${'success'} | ${[{ type: types.REQUEST_PROJECTS }, { type: types.RECEIVE_PROJECTS_SUCCESS, payload: MOCK_PROJECTS }]} | ${0} ${actions.fetchProjects} | ${{ method: 'onGet', code: HTTP_STATUS_INTERNAL_SERVER_ERROR, res: null }} | ${'error'} | ${[{ type: types.REQUEST_PROJECTS }, { type: types.RECEIVE_PROJECTS_ERROR }]} | ${1} - `(`axios calls`, ({ action, axiosMock, type, expectedMutations, flashCallCount }) => { + `(`axios calls`, ({ action, axiosMock, type, expectedMutations, alertCallCount }) => { describe(action.name, () => { describe(`on ${type}`, () => { beforeEach(() => { @@ -76,7 +76,7 @@ describe('Global Search Store Actions', () => { }); it(`should dispatch the correct mutations`, () => { return testAction({ action, state, expectedMutations }).then(() => - flashCallback(flashCallCount), + alertCallback(alertCallCount), ); }); }); @@ -84,12 +84,12 @@ describe('Global Search Store Actions', () => { }); describe.each` - action | axiosMock | type | expectedMutations | flashCallCount + action | axiosMock | type | expectedMutations | alertCallCount ${actions.loadFrequentGroups} | ${{ method: 'onGet', code: HTTP_STATUS_OK }} | ${'success'} | ${[PROMISE_ALL_EXPECTED_MUTATIONS.resGroups]} | ${0} ${actions.loadFrequentGroups} | ${{ method: 'onGet', code: HTTP_STATUS_INTERNAL_SERVER_ERROR }} | ${'error'} | ${[]} | ${1} ${actions.loadFrequentProjects} | ${{ method: 'onGet', code: HTTP_STATUS_OK }} | ${'success'} | ${[PROMISE_ALL_EXPECTED_MUTATIONS.resProjects]} | ${0} ${actions.loadFrequentProjects} | ${{ method: 'onGet', code: HTTP_STATUS_INTERNAL_SERVER_ERROR }} | ${'error'} | ${[]} | ${1} - `('Promise.all calls', ({ action, axiosMock, type, expectedMutations, flashCallCount }) => { + `('Promise.all calls', ({ action, axiosMock, type, expectedMutations, alertCallCount }) => { describe(action.name, () => { describe(`on ${type}`, () => { beforeEach(() => { @@ -103,7 +103,7 @@ describe('Global Search Store Actions', () => { it(`should dispatch the correct mutations`, () => { return testAction({ action, state, expectedMutations }).then(() => { - flashCallback(flashCallCount); + alertCallback(alertCallCount); }); }); }); diff --git a/spec/frontend/vue_merge_request_widget/components/approvals/approvals_spec.js b/spec/frontend/vue_merge_request_widget/components/approvals/approvals_spec.js index 80a7565cbee..e78e1be7882 100644 --- a/spec/frontend/vue_merge_request_widget/components/approvals/approvals_spec.js +++ b/spec/frontend/vue_merge_request_widget/components/approvals/approvals_spec.js @@ -6,7 +6,7 @@ import approvedByCurrentUser from 'test_fixtures/graphql/merge_requests/approval import createMockApollo from 'helpers/mock_apollo_helper'; import waitForPromises from 'helpers/wait_for_promises'; import { getIdFromGraphQLId } from '~/graphql_shared/utils'; -import { createAlert } from '~/flash'; +import { createAlert } from '~/alert'; import Approvals from '~/vue_merge_request_widget/components/approvals/approvals.vue'; import ApprovalsSummary from '~/vue_merge_request_widget/components/approvals/approvals_summary.vue'; import ApprovalsSummaryOptional from '~/vue_merge_request_widget/components/approvals/approvals_summary_optional.vue'; @@ -21,7 +21,7 @@ import { createCanApproveResponse } from 'jest/approvals/mock_data'; Vue.use(VueApollo); const mockAlertDismiss = jest.fn(); -jest.mock('~/flash', () => ({ +jest.mock('~/alert', () => ({ createAlert: jest.fn().mockImplementation(() => ({ dismiss: mockAlertDismiss, })), @@ -295,7 +295,7 @@ describe('MRWidget approvals', () => { return nextTick(); }); - it('flashes error message', () => { + it('alerts error message', () => { expect(createAlert).toHaveBeenCalledWith({ message: UNAPPROVE_ERROR }); }); }); diff --git a/spec/frontend/vue_merge_request_widget/components/states/work_in_progress_spec.js b/spec/frontend/vue_merge_request_widget/components/states/work_in_progress_spec.js index e610ceb2122..43ce1769ff3 100644 --- a/spec/frontend/vue_merge_request_widget/components/states/work_in_progress_spec.js +++ b/spec/frontend/vue_merge_request_widget/components/states/work_in_progress_spec.js @@ -1,7 +1,7 @@ import Vue from 'vue'; import VueApollo from 'vue-apollo'; import getStateQueryResponse from 'test_fixtures/graphql/merge_requests/get_state.query.graphql.json'; -import { createAlert } from '~/flash'; +import { createAlert } from '~/alert'; import WorkInProgress, { MSG_SOMETHING_WENT_WRONG, MSG_MARK_READY, @@ -22,7 +22,7 @@ const TEST_MR_IID = '23'; const TEST_MR_TITLE = 'Test MR Title'; const TEST_PROJECT_PATH = 'lorem/ipsum'; -jest.mock('~/flash'); +jest.mock('~/alert'); jest.mock('~/merge_request'); describe('~/vue_merge_request_widget/components/states/work_in_progress.vue', () => { diff --git a/spec/graphql/mutations/members/bulk_update_base_spec.rb b/spec/graphql/mutations/members/bulk_update_base_spec.rb new file mode 100644 index 00000000000..61a27984824 --- /dev/null +++ b/spec/graphql/mutations/members/bulk_update_base_spec.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Mutations::Members::BulkUpdateBase, feature_category: :subgroups do + include GraphqlHelpers + + let_it_be(:user) { create(:user) } + let_it_be(:group) { create(:group).tap { |group| group.add_owner(user) } } + + it 'raises a NotImplementedError error if the source_type method is called on the base class' do + mutation = described_class.new(context: { current_user: user }, object: nil, field: nil) + + expect { mutation.resolve(group_id: group.to_gid.to_s) }.to raise_error(NotImplementedError) + end +end diff --git a/spec/helpers/diff_helper_spec.rb b/spec/helpers/diff_helper_spec.rb index a46f8c13f00..2318bbf861a 100644 --- a/spec/helpers/diff_helper_spec.rb +++ b/spec/helpers/diff_helper_spec.rb @@ -47,6 +47,12 @@ RSpec.describe DiffHelper do end describe 'diff_options' do + let(:large_notebooks_enabled) { false } + + before do + stub_feature_flags(large_ipynb_diffs: large_notebooks_enabled) + end + it 'returns no collapse false' do expect(diff_options).to include(expanded: false) end @@ -56,21 +62,48 @@ RSpec.describe DiffHelper do expect(diff_options).to include(expanded: true) end - it 'returns no collapse true if action name diff_for_path' do - allow(controller).to receive(:action_name) { 'diff_for_path' } - expect(diff_options).to include(expanded: true) - end + context 'when action name is diff_for_path' do + before do + allow(controller).to receive(:action_name) { 'diff_for_path' } + end - it 'returns paths if action name diff_for_path and param old path' do - allow(controller).to receive(:params) { { old_path: 'lib/wadus.rb' } } - allow(controller).to receive(:action_name) { 'diff_for_path' } - expect(diff_options[:paths]).to include('lib/wadus.rb') - end + it 'returns expanded true' do + expect(diff_options).to include(expanded: true) + end - it 'returns paths if action name diff_for_path and param new path' do - allow(controller).to receive(:params) { { new_path: 'lib/wadus.rb' } } - allow(controller).to receive(:action_name) { 'diff_for_path' } - expect(diff_options[:paths]).to include('lib/wadus.rb') + it 'returns paths if param old path' do + allow(controller).to receive(:params) { { old_path: 'lib/wadus.rb' } } + expect(diff_options[:paths]).to include('lib/wadus.rb') + end + + it 'returns paths if param new path' do + allow(controller).to receive(:params) { { new_path: 'lib/wadus.rb' } } + expect(diff_options[:paths]).to include('lib/wadus.rb') + end + + it 'does not set max_patch_bytes_for_file_extension' do + expect(diff_options[:max_patch_bytes_for_file_extension]).to be_nil + end + + context 'when file_identifier include .ipynb' do + before do + allow(controller).to receive(:params) { { file_identifier: 'something.ipynb' } } + end + + context 'when large_ipynb_diffs is disabled' do + it 'does not set max_patch_bytes_for_file_extension' do + expect(diff_options[:max_patch_bytes_for_file_extension]).to be_nil + end + end + + context 'when large_ipynb_diffs is enabled' do + let(:large_notebooks_enabled) { true } + + it 'sets max_patch_bytes_for_file_extension' do + expect(diff_options[:max_patch_bytes_for_file_extension]).to eq({ '.ipynb' => 1.megabyte }) + end + end + end end end diff --git a/spec/lib/gitlab/git/diff_collection_spec.rb b/spec/lib/gitlab/git/diff_collection_spec.rb index 7fa5bd8a92b..5fa0447091c 100644 --- a/spec/lib/gitlab/git/diff_collection_spec.rb +++ b/spec/lib/gitlab/git/diff_collection_spec.rb @@ -777,6 +777,26 @@ RSpec.describe Gitlab::Git::DiffCollection do end end + describe '.limits' do + let(:options) { {} } + + subject { described_class.limits(options) } + + context 'when options do not include max_patch_bytes_for_file_extension' do + it 'sets max_patch_bytes_for_file_extension as empty' do + expect(subject[:max_patch_bytes_for_file_extension]).to eq({}) + end + end + + context 'when options include max_patch_bytes_for_file_extension' do + let(:options) { { max_patch_bytes_for_file_extension: { '.file' => 1 } } } + + it 'sets value for max_patch_bytes_for_file_extension' do + expect(subject[:max_patch_bytes_for_file_extension]).to eq({ '.file' => 1 }) + end + end + end + def fake_diff(line_length, line_count) { 'diff' => "#{'a' * line_length}\n" * line_count } end diff --git a/spec/lib/sidebars/projects/menus/repository_menu_spec.rb b/spec/lib/sidebars/projects/menus/repository_menu_spec.rb index 40ca2107698..b0631aacdb9 100644 --- a/spec/lib/sidebars/projects/menus/repository_menu_spec.rb +++ b/spec/lib/sidebars/projects/menus/repository_menu_spec.rb @@ -85,7 +85,7 @@ RSpec.describe Sidebars::Projects::Menus::RepositoryMenu, feature_category: :sou end end - describe 'Contributors' do + describe 'Contributor statistics' do let_it_be(:item_id) { :contributors } context 'when analytics is disabled' do diff --git a/spec/requests/api/graphql/mutations/members/groups/bulk_update_spec.rb b/spec/requests/api/graphql/mutations/members/groups/bulk_update_spec.rb index ad70129a7bc..f15b52f53a3 100644 --- a/spec/requests/api/graphql/mutations/members/groups/bulk_update_spec.rb +++ b/spec/requests/api/graphql/mutations/members/groups/bulk_update_spec.rb @@ -5,126 +5,14 @@ require 'spec_helper' RSpec.describe 'GroupMemberBulkUpdate', feature_category: :subgroups do include GraphqlHelpers - let_it_be(:current_user) { create(:user) } - let_it_be(:user1) { create(:user) } - let_it_be(:user2) { create(:user) } - let_it_be(:group) { create(:group) } - let_it_be(:group_member1) { create(:group_member, group: group, user: user1) } - let_it_be(:group_member2) { create(:group_member, group: group, user: user2) } + let_it_be(:parent_group) { create(:group) } + let_it_be(:parent_group_member) { create(:group_member, group: parent_group) } + let_it_be(:group) { create(:group, parent: parent_group) } + let_it_be(:source) { group } + let_it_be(:member_type) { :group_member } let_it_be(:mutation_name) { :group_member_bulk_update } + let_it_be(:source_id_key) { 'group_id' } + let_it_be(:response_member_field) { 'groupMembers' } - let(:input) do - { - 'group_id' => group.to_global_id.to_s, - 'user_ids' => [user1.to_global_id.to_s, user2.to_global_id.to_s], - 'access_level' => 'GUEST' - } - end - - let(:extra_params) { { expires_at: 10.days.from_now } } - let(:input_params) { input.merge(extra_params) } - let(:mutation) { graphql_mutation(mutation_name, input_params) } - let(:mutation_response) { graphql_mutation_response(mutation_name) } - - context 'when user is not logged-in' do - it_behaves_like 'a mutation that returns a top-level access error' - end - - context 'when user is not an owner' do - before do - group.add_maintainer(current_user) - end - - it_behaves_like 'a mutation that returns a top-level access error' - end - - context 'when user is an owner' do - before do - group.add_owner(current_user) - end - - shared_examples 'updates the user access role' do - specify do - post_graphql_mutation(mutation, current_user: current_user) - - new_access_levels = mutation_response['groupMembers'].map { |member| member['accessLevel']['integerValue'] } - expect(response).to have_gitlab_http_status(:success) - expect(mutation_response['errors']).to be_empty - expect(new_access_levels).to all(be Gitlab::Access::GUEST) - end - end - - it_behaves_like 'updates the user access role' - - context 'when inherited members are passed' do - let_it_be(:subgroup) { create(:group, parent: group) } - let_it_be(:subgroup_member) { create(:group_member, group: subgroup) } - - let(:input) do - { - 'group_id' => group.to_global_id.to_s, - 'user_ids' => [user1.to_global_id.to_s, user2.to_global_id.to_s, subgroup_member.user.to_global_id.to_s], - 'access_level' => 'GUEST' - } - end - - it 'does not update the members' do - post_graphql_mutation(mutation, current_user: current_user) - - error = Mutations::Members::Groups::BulkUpdate::INVALID_MEMBERS_ERROR - expect(json_response['errors'].first['message']).to include(error) - end - end - - context 'when members count is more than the allowed limit' do - let(:max_members_update_limit) { 1 } - - before do - stub_const('Mutations::Members::Groups::BulkUpdate::MAX_MEMBERS_UPDATE_LIMIT', max_members_update_limit) - end - - it 'does not update the members' do - post_graphql_mutation(mutation, current_user: current_user) - - error = Mutations::Members::Groups::BulkUpdate::MAX_MEMBERS_UPDATE_ERROR - expect(json_response['errors'].first['message']).to include(error) - end - end - - context 'when the update service raises access denied error' do - before do - allow_next_instance_of(Members::UpdateService) do |instance| - allow(instance).to receive(:execute).and_raise(Gitlab::Access::AccessDeniedError) - end - end - - it 'does not update the members' do - post_graphql_mutation(mutation, current_user: current_user) - - expect(mutation_response['groupMembers']).to be_nil - expect(mutation_response['errors']) - .to contain_exactly("Unable to update members, please check user permissions.") - end - end - - context 'when the update service returns an error message' do - before do - allow_next_instance_of(Members::UpdateService) do |instance| - error_result = { - message: 'Expires at cannot be a date in the past', - status: :error, - members: [group_member1] - } - allow(instance).to receive(:execute).and_return(error_result) - end - end - - it 'will pass through the error' do - post_graphql_mutation(mutation, current_user: current_user) - - expect(mutation_response['groupMembers'].first['id']).to eq(group_member1.to_global_id.to_s) - expect(mutation_response['errors']).to contain_exactly('Expires at cannot be a date in the past') - end - end - end + it_behaves_like 'members bulk update mutation' end diff --git a/spec/requests/api/graphql/mutations/members/projects/bulk_update_spec.rb b/spec/requests/api/graphql/mutations/members/projects/bulk_update_spec.rb new file mode 100644 index 00000000000..cbef9715cbe --- /dev/null +++ b/spec/requests/api/graphql/mutations/members/projects/bulk_update_spec.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'ProjectMemberBulkUpdate', feature_category: :projects do + include GraphqlHelpers + + let_it_be(:parent_group) { create(:group) } + let_it_be(:parent_group_member) { create(:group_member, group: parent_group) } + let_it_be(:project) { create(:project, group: parent_group) } + let_it_be(:source) { project } + let_it_be(:member_type) { :project_member } + let_it_be(:mutation_name) { :project_member_bulk_update } + let_it_be(:source_id_key) { 'project_id' } + let_it_be(:response_member_field) { 'projectMembers' } + + it_behaves_like 'members bulk update mutation' +end diff --git a/spec/support/shared_contexts/navbar_structure_context.rb b/spec/support/shared_contexts/navbar_structure_context.rb index e1ac0e3fd0a..3af0b30bca0 100644 --- a/spec/support/shared_contexts/navbar_structure_context.rb +++ b/spec/support/shared_contexts/navbar_structure_context.rb @@ -34,10 +34,10 @@ RSpec.shared_context 'project navbar structure' do _('Commits'), _('Branches'), _('Tags'), - _('Contributors'), + _('Contributor statistics'), _('Graph'), - _('Compare'), - (_('Locked Files') if Gitlab.ee?) + _('Compare revisions'), + (_('Locked files') if Gitlab.ee?) ] }, { diff --git a/spec/support/shared_examples/graphql/mutations/members/bulk_update_shared_examples.rb b/spec/support/shared_examples/graphql/mutations/members/bulk_update_shared_examples.rb new file mode 100644 index 00000000000..e885b5d283e --- /dev/null +++ b/spec/support/shared_examples/graphql/mutations/members/bulk_update_shared_examples.rb @@ -0,0 +1,123 @@ +# frozen_string_literal: true + +RSpec.shared_examples 'members bulk update mutation' do + let_it_be(:current_user) { create(:user) } + let_it_be(:user1) { create(:user) } + let_it_be(:user2) { create(:user) } + let_it_be(:member1) { create(member_type, source: source, user: user1) } + let_it_be(:member2) { create(member_type, source: source, user: user2) } + + let(:extra_params) { { expires_at: 10.days.from_now } } + let(:input_params) { input.merge(extra_params) } + let(:mutation) { graphql_mutation(mutation_name, input_params) } + let(:mutation_response) { graphql_mutation_response(mutation_name) } + + let(:input) do + { + source_id_key => source.to_global_id.to_s, + 'user_ids' => [user1.to_global_id.to_s, user2.to_global_id.to_s], + 'access_level' => 'GUEST' + } + end + + context 'when user is not logged-in' do + it_behaves_like 'a mutation that returns a top-level access error' + end + + context 'when user is not an owner' do + before do + source.add_developer(current_user) + end + + it_behaves_like 'a mutation that returns a top-level access error' + end + + context 'when user is an owner' do + before do + source.add_owner(current_user) + end + + shared_examples 'updates the user access role' do + specify do + post_graphql_mutation(mutation, current_user: current_user) + + new_access_levels = mutation_response[response_member_field].map do |member| + member['accessLevel']['integerValue'] + end + expect(response).to have_gitlab_http_status(:success) + expect(mutation_response['errors']).to be_empty + expect(new_access_levels).to all(be Gitlab::Access::GUEST) + end + end + + it_behaves_like 'updates the user access role' + + context 'when inherited members are passed' do + let(:input) do + { + source_id_key => source.to_global_id.to_s, + 'user_ids' => [user1.to_global_id.to_s, user2.to_global_id.to_s, parent_group_member.user.to_global_id.to_s], + 'access_level' => 'GUEST' + } + end + + it 'does not update the members' do + post_graphql_mutation(mutation, current_user: current_user) + + error = Mutations::Members::BulkUpdateBase::INVALID_MEMBERS_ERROR + expect(json_response['errors'].first['message']).to include(error) + end + end + + context 'when members count is more than the allowed limit' do + let(:max_members_update_limit) { 1 } + + before do + stub_const('Mutations::Members::BulkUpdateBase::MAX_MEMBERS_UPDATE_LIMIT', max_members_update_limit) + end + + it 'does not update the members' do + post_graphql_mutation(mutation, current_user: current_user) + + error = Mutations::Members::BulkUpdateBase::MAX_MEMBERS_UPDATE_ERROR + expect(json_response['errors'].first['message']).to include(error) + end + end + + context 'when the update service raises access denied error' do + before do + allow_next_instance_of(Members::UpdateService) do |instance| + allow(instance).to receive(:execute).and_raise(Gitlab::Access::AccessDeniedError) + end + end + + it 'does not update the members' do + post_graphql_mutation(mutation, current_user: current_user) + + expect(mutation_response[response_member_field]).to be_nil + expect(mutation_response['errors']) + .to contain_exactly("Unable to update members, please check user permissions.") + end + end + + context 'when the update service returns an error message' do + before do + allow_next_instance_of(Members::UpdateService) do |instance| + error_result = { + message: 'Expires at cannot be a date in the past', + status: :error, + members: [member1] + } + allow(instance).to receive(:execute).and_return(error_result) + end + end + + it 'will pass through the error' do + post_graphql_mutation(mutation, current_user: current_user) + + expect(mutation_response[response_member_field].first['id']).to eq(member1.to_global_id.to_s) + expect(mutation_response['errors']).to contain_exactly('Expires at cannot be a date in the past') + end + end + end +end diff --git a/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb b/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb index dc9575dc767..0df490f9b41 100644 --- a/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb +++ b/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb @@ -106,11 +106,11 @@ RSpec.describe 'layouts/nav/sidebar/_project', feature_category: :navigation do end end - describe 'Contributors' do + describe 'Contributor statistics' do it 'has a link to the project contributors path' do render - expect(rendered).to have_link('Contributors', href: project_graph_path(project, current_ref, ref_type: 'heads')) + expect(rendered).to have_link('Contributor statistics', href: project_graph_path(project, current_ref, ref_type: 'heads')) end end @@ -122,11 +122,11 @@ RSpec.describe 'layouts/nav/sidebar/_project', feature_category: :navigation do end end - describe 'Compare' do + describe 'Compare revisions' do it 'has a link to the project compare path' do render - expect(rendered).to have_link('Compare', href: project_compare_index_path(project, from: project.repository.root_ref, to: current_ref)) + expect(rendered).to have_link('Compare revisions', href: project_compare_index_path(project, from: project.repository.root_ref, to: current_ref)) end end end |