From 2af44d609eb8a1579169f9a350bc531d1081d77f Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Wed, 21 Apr 2021 12:09:16 +0000 Subject: Add latest changes from gitlab-org/gitlab@master --- .rubocop_manual_todo.yml | 24 ------- app/assets/javascripts/notebook/cells/markdown.vue | 35 +++++++++ app/finders/users_with_pending_todos_finder.rb | 16 ----- .../sidebars/container_with_html_options.rb | 42 ----------- app/models/concerns/sidebars/has_active_routes.rb | 16 ----- app/models/concerns/sidebars/has_hint.rb | 16 ----- app/models/concerns/sidebars/has_icon.rb | 27 ------- app/models/concerns/sidebars/has_pill.rb | 21 ------ app/models/concerns/sidebars/positionable_list.rb | 37 ---------- app/models/concerns/sidebars/renderable.rb | 12 ---- app/models/group.rb | 2 - app/models/sidebars/context.rb | 21 ------ app/models/sidebars/menu.rb | 82 ---------------------- app/models/sidebars/menu_item.rb | 21 ------ app/models/sidebars/panel.rb | 75 -------------------- app/models/sidebars/projects/context.rb | 11 --- .../sidebars/projects/menus/learn_gitlab/menu.rb | 41 ----------- .../projects/menus/project_overview/menu.rb | 45 ------------ .../menus/project_overview/menu_items/activity.rb | 35 --------- .../menus/project_overview/menu_items/details.rb | 36 ---------- .../menus/project_overview/menu_items/releases.rb | 40 ----------- .../sidebars/projects/menus/repository/menu.rb | 59 ---------------- .../menus/repository/menu_items/branches.rb | 35 --------- .../menus/repository/menu_items/commits.rb | 35 --------- .../menus/repository/menu_items/compare.rb | 28 -------- .../menus/repository/menu_items/contributors.rb | 28 -------- .../projects/menus/repository/menu_items/files.rb | 28 -------- .../projects/menus/repository/menu_items/graphs.rb | 28 -------- .../projects/menus/repository/menu_items/tags.rb | 28 -------- app/models/sidebars/projects/menus/scope/menu.rb | 21 ------ app/models/sidebars/projects/panel.rb | 26 ------- app/models/user.rb | 2 +- app/services/todo_service.rb | 2 +- app/views/admin/groups/_group.html.haml | 2 +- app/views/admin/users/_users.html.haml | 18 ++--- app/views/dashboard/todos/index.html.haml | 4 +- .../groups/milestones/_header_title.html.haml | 2 +- app/views/profiles/preferences/show.html.haml | 2 +- ...4-set-hipchat-metric-definitions-as-removed.yml | 5 ++ changelogs/unreleased/326839-improve-message.yml | 5 ++ ...t-for-done-todos-when-deleting-todo-targets.yml | 5 ++ ...rings-in-milestones-_header_title-html-haml.yml | 5 ++ changelogs/unreleased/gl-badge-admin-groups.yml | 5 ++ changelogs/unreleased/gl-badge-admin-users.yml | 5 ++ changelogs/unreleased/gl-badge-todos.yml | 5 ++ changelogs/unreleased/gl-form-preferences.yml | 5 ++ changelogs/unreleased/rails-save-bang-graphql.yml | 5 ++ ...spec-empty-lines-after-letitbe-spec-workers.yml | 5 ++ changelogs/unreleased/sh-jupyter-fix-images.yml | 5 ++ .../20210216175910_projects_hipchat_active.yml | 3 +- .../20210216175912_groups_hipchat_active.yml | 3 +- .../20210216175913_templates_hipchat_active.yml | 3 +- .../20210216175915_instances_hipchat_active.yml | 3 +- ...16175917_projects_inheriting_hipchat_active.yml | 3 +- ...0216175919_groups_inheriting_hipchat_active.yml | 3 +- doc/administration/terraform_state.md | 2 +- doc/development/changelog.md | 2 +- doc/development/pipelines.md | 53 ++++++++++++++ doc/development/usage_ping/dictionary.md | 12 ++-- doc/user/project/time_tracking.md | 2 +- lib/gitlab/git_access.rb | 2 +- lib/gitlab/utils/usage_data.rb | 2 +- .../concerns/container_with_html_options.rb | 44 ++++++++++++ lib/sidebars/concerns/has_active_routes.rb | 18 +++++ lib/sidebars/concerns/has_hint.rb | 18 +++++ lib/sidebars/concerns/has_icon.rb | 29 ++++++++ lib/sidebars/concerns/has_pill.rb | 23 ++++++ lib/sidebars/concerns/positionable_list.rb | 39 ++++++++++ lib/sidebars/concerns/renderable.rb | 14 ++++ lib/sidebars/context.rb | 21 ++++++ lib/sidebars/menu.rb | 82 ++++++++++++++++++++++ lib/sidebars/menu_item.rb | 21 ++++++ lib/sidebars/panel.rb | 75 ++++++++++++++++++++ lib/sidebars/projects/context.rb | 11 +++ lib/sidebars/projects/menus/learn_gitlab/menu.rb | 41 +++++++++++ .../projects/menus/project_overview/menu.rb | 45 ++++++++++++ .../menus/project_overview/menu_items/activity.rb | 35 +++++++++ .../menus/project_overview/menu_items/details.rb | 36 ++++++++++ .../menus/project_overview/menu_items/releases.rb | 40 +++++++++++ lib/sidebars/projects/menus/repository/menu.rb | 59 ++++++++++++++++ .../menus/repository/menu_items/branches.rb | 35 +++++++++ .../menus/repository/menu_items/commits.rb | 35 +++++++++ .../menus/repository/menu_items/compare.rb | 28 ++++++++ .../menus/repository/menu_items/contributors.rb | 28 ++++++++ .../projects/menus/repository/menu_items/files.rb | 28 ++++++++ .../projects/menus/repository/menu_items/graphs.rb | 28 ++++++++ .../projects/menus/repository/menu_items/tags.rb | 28 ++++++++ lib/sidebars/projects/menus/scope/menu.rb | 21 ++++++ lib/sidebars/projects/panel.rb | 26 +++++++ locale/gitlab.pot | 16 ++++- .../users_with_pending_todos_finder_spec.rb | 19 ----- spec/frontend/fixtures/raw.rb | 4 ++ .../components/dashboards_dropdown_spec.js | 2 +- .../components/duplicate_dashboard_form_spec.js | 2 +- .../components/duplicate_dashboard_modal_spec.js | 2 +- spec/frontend/monitoring/mock_data.js | 18 ++--- spec/frontend/notebook/cells/markdown_spec.js | 37 +++++++++- .../repository/components/table/index_spec.js | 4 +- .../repository/components/table/parent_row_spec.js | 14 ++-- .../repository/components/table/row_spec.js | 6 +- .../components/upload_blob_modal_spec.js | 6 +- spec/frontend/repository/log_tree_spec.js | 6 +- spec/frontend/repository/router_spec.js | 16 ++--- spec/frontend/repository/utils/title_spec.js | 4 +- .../mutations/merge_requests/set_locked_spec.rb | 2 +- .../mutations/merge_requests/set_wip_spec.rb | 2 +- spec/graphql/resolvers/boards_resolver_spec.rb | 2 +- spec/lib/gitlab/git_access_spec.rb | 10 +-- .../concerns/container_with_html_options_spec.rb | 21 ++++++ .../sidebars/concerns/positionable_list_spec.rb | 59 ++++++++++++++++ spec/lib/sidebars/menu_spec.rb | 67 ++++++++++++++++++ spec/lib/sidebars/panel_spec.rb | 34 +++++++++ spec/lib/sidebars/projects/context_spec.rb | 13 ++++ .../projects/menus/learn_gitlab/menu_spec.rb | 31 ++++++++ .../project_overview/menu_items/releases_spec.rb | 38 ++++++++++ .../projects/menus/project_overview/menu_spec.rb | 18 +++++ .../projects/menus/repository/menu_spec.rb | 38 ++++++++++ spec/lib/sidebars/projects/panel_spec.rb | 14 ++++ .../sidebars/container_with_html_options_spec.rb | 21 ------ .../concerns/sidebars/positionable_list_spec.rb | 59 ---------------- spec/models/group_spec.rb | 6 +- spec/models/sidebars/menu_spec.rb | 67 ------------------ spec/models/sidebars/panel_spec.rb | 34 --------- spec/models/sidebars/projects/context_spec.rb | 13 ---- .../projects/menus/learn_gitlab/menu_spec.rb | 31 -------- .../project_overview/menu_items/releases_spec.rb | 38 ---------- .../projects/menus/project_overview/menu_spec.rb | 18 ----- .../projects/menus/repository/menu_spec.rb | 38 ---------- spec/models/sidebars/projects/panel_spec.rb | 14 ---- spec/models/user_spec.rb | 15 ++++ ...test_manual_post_test_needs_deploy_is_stage.yml | 50 +++++++++++++ spec/services/todo_service_spec.rb | 13 +--- spec/support/helpers/test_env.rb | 2 +- .../lib/gitlab/sql/set_operator_shared_examples.rb | 2 +- .../create_cross_project_pipeline_worker_spec.rb | 1 + spec/workers/cluster_update_app_worker_spec.rb | 1 + .../canary_ingress/update_worker_spec.rb | 1 + spec/workers/expire_job_cache_worker_spec.rb | 1 + .../gitlab/jira_import/import_issue_worker_spec.rb | 1 + .../jira_import/stage/start_import_worker_spec.rb | 1 + .../stuck_jira_import_jobs_worker_spec.rb | 1 + spec/workers/import_issues_csv_worker_spec.rb | 1 + .../add_severity_system_note_worker_spec.rb | 1 + .../process_alert_worker_spec.rb | 1 + .../process_prometheus_alert_worker_spec.rb | 1 + .../jira_connect/sync_project_worker_spec.rb | 1 + .../onboarding_issue_created_worker_spec.rb | 1 + .../packages/composer/cache_update_worker_spec.rb | 1 + .../pages_domain_ssl_renewal_cron_worker_spec.rb | 1 + .../projects/git_garbage_collect_worker_spec.rb | 1 + .../create_default_alerts_worker_spec.rb | 1 + .../propagate_integration_group_worker_spec.rb | 1 + .../propagate_integration_project_worker_spec.rb | 1 + spec/workers/run_pipeline_schedule_worker_spec.rb | 1 + .../update_external_pull_requests_worker_spec.rb | 1 + 155 files changed, 1619 insertions(+), 1387 deletions(-) delete mode 100644 app/finders/users_with_pending_todos_finder.rb delete mode 100644 app/models/concerns/sidebars/container_with_html_options.rb delete mode 100644 app/models/concerns/sidebars/has_active_routes.rb delete mode 100644 app/models/concerns/sidebars/has_hint.rb delete mode 100644 app/models/concerns/sidebars/has_icon.rb delete mode 100644 app/models/concerns/sidebars/has_pill.rb delete mode 100644 app/models/concerns/sidebars/positionable_list.rb delete mode 100644 app/models/concerns/sidebars/renderable.rb delete mode 100644 app/models/sidebars/context.rb delete mode 100644 app/models/sidebars/menu.rb delete mode 100644 app/models/sidebars/menu_item.rb delete mode 100644 app/models/sidebars/panel.rb delete mode 100644 app/models/sidebars/projects/context.rb delete mode 100644 app/models/sidebars/projects/menus/learn_gitlab/menu.rb delete mode 100644 app/models/sidebars/projects/menus/project_overview/menu.rb delete mode 100644 app/models/sidebars/projects/menus/project_overview/menu_items/activity.rb delete mode 100644 app/models/sidebars/projects/menus/project_overview/menu_items/details.rb delete mode 100644 app/models/sidebars/projects/menus/project_overview/menu_items/releases.rb delete mode 100644 app/models/sidebars/projects/menus/repository/menu.rb delete mode 100644 app/models/sidebars/projects/menus/repository/menu_items/branches.rb delete mode 100644 app/models/sidebars/projects/menus/repository/menu_items/commits.rb delete mode 100644 app/models/sidebars/projects/menus/repository/menu_items/compare.rb delete mode 100644 app/models/sidebars/projects/menus/repository/menu_items/contributors.rb delete mode 100644 app/models/sidebars/projects/menus/repository/menu_items/files.rb delete mode 100644 app/models/sidebars/projects/menus/repository/menu_items/graphs.rb delete mode 100644 app/models/sidebars/projects/menus/repository/menu_items/tags.rb delete mode 100644 app/models/sidebars/projects/menus/scope/menu.rb delete mode 100644 app/models/sidebars/projects/panel.rb create mode 100644 changelogs/unreleased/322604-set-hipchat-metric-definitions-as-removed.yml create mode 100644 changelogs/unreleased/326839-improve-message.yml create mode 100644 changelogs/unreleased/327110-update-cached-count-for-done-todos-when-deleting-todo-targets.yml create mode 100644 changelogs/unreleased/Externalize-strings-in-milestones-_header_title-html-haml.yml create mode 100644 changelogs/unreleased/gl-badge-admin-groups.yml create mode 100644 changelogs/unreleased/gl-badge-admin-users.yml create mode 100644 changelogs/unreleased/gl-badge-todos.yml create mode 100644 changelogs/unreleased/gl-form-preferences.yml create mode 100644 changelogs/unreleased/rails-save-bang-graphql.yml create mode 100644 changelogs/unreleased/rspec-empty-lines-after-letitbe-spec-workers.yml create mode 100644 changelogs/unreleased/sh-jupyter-fix-images.yml create mode 100644 lib/sidebars/concerns/container_with_html_options.rb create mode 100644 lib/sidebars/concerns/has_active_routes.rb create mode 100644 lib/sidebars/concerns/has_hint.rb create mode 100644 lib/sidebars/concerns/has_icon.rb create mode 100644 lib/sidebars/concerns/has_pill.rb create mode 100644 lib/sidebars/concerns/positionable_list.rb create mode 100644 lib/sidebars/concerns/renderable.rb create mode 100644 lib/sidebars/context.rb create mode 100644 lib/sidebars/menu.rb create mode 100644 lib/sidebars/menu_item.rb create mode 100644 lib/sidebars/panel.rb create mode 100644 lib/sidebars/projects/context.rb create mode 100644 lib/sidebars/projects/menus/learn_gitlab/menu.rb create mode 100644 lib/sidebars/projects/menus/project_overview/menu.rb create mode 100644 lib/sidebars/projects/menus/project_overview/menu_items/activity.rb create mode 100644 lib/sidebars/projects/menus/project_overview/menu_items/details.rb create mode 100644 lib/sidebars/projects/menus/project_overview/menu_items/releases.rb create mode 100644 lib/sidebars/projects/menus/repository/menu.rb create mode 100644 lib/sidebars/projects/menus/repository/menu_items/branches.rb create mode 100644 lib/sidebars/projects/menus/repository/menu_items/commits.rb create mode 100644 lib/sidebars/projects/menus/repository/menu_items/compare.rb create mode 100644 lib/sidebars/projects/menus/repository/menu_items/contributors.rb create mode 100644 lib/sidebars/projects/menus/repository/menu_items/files.rb create mode 100644 lib/sidebars/projects/menus/repository/menu_items/graphs.rb create mode 100644 lib/sidebars/projects/menus/repository/menu_items/tags.rb create mode 100644 lib/sidebars/projects/menus/scope/menu.rb create mode 100644 lib/sidebars/projects/panel.rb delete mode 100644 spec/finders/users_with_pending_todos_finder_spec.rb create mode 100644 spec/lib/sidebars/concerns/container_with_html_options_spec.rb create mode 100644 spec/lib/sidebars/concerns/positionable_list_spec.rb create mode 100644 spec/lib/sidebars/menu_spec.rb create mode 100644 spec/lib/sidebars/panel_spec.rb create mode 100644 spec/lib/sidebars/projects/context_spec.rb create mode 100644 spec/lib/sidebars/projects/menus/learn_gitlab/menu_spec.rb create mode 100644 spec/lib/sidebars/projects/menus/project_overview/menu_items/releases_spec.rb create mode 100644 spec/lib/sidebars/projects/menus/project_overview/menu_spec.rb create mode 100644 spec/lib/sidebars/projects/menus/repository/menu_spec.rb create mode 100644 spec/lib/sidebars/projects/panel_spec.rb delete mode 100644 spec/models/concerns/sidebars/container_with_html_options_spec.rb delete mode 100644 spec/models/concerns/sidebars/positionable_list_spec.rb delete mode 100644 spec/models/sidebars/menu_spec.rb delete mode 100644 spec/models/sidebars/panel_spec.rb delete mode 100644 spec/models/sidebars/projects/context_spec.rb delete mode 100644 spec/models/sidebars/projects/menus/learn_gitlab/menu_spec.rb delete mode 100644 spec/models/sidebars/projects/menus/project_overview/menu_items/releases_spec.rb delete mode 100644 spec/models/sidebars/projects/menus/project_overview/menu_spec.rb delete mode 100644 spec/models/sidebars/projects/menus/repository/menu_spec.rb delete mode 100644 spec/models/sidebars/projects/panel_spec.rb create mode 100644 spec/services/ci/pipeline_processing/test_cases/dag_test_manual_post_test_needs_deploy_is_stage.yml diff --git a/.rubocop_manual_todo.yml b/.rubocop_manual_todo.yml index f428105cb32..52ad0a59569 100644 --- a/.rubocop_manual_todo.yml +++ b/.rubocop_manual_todo.yml @@ -153,9 +153,6 @@ Rails/SaveBang: - 'spec/controllers/sessions_controller_spec.rb' - 'spec/frontend/fixtures/issues.rb' - 'spec/frontend/fixtures/merge_requests.rb' - - 'spec/graphql/mutations/merge_requests/set_locked_spec.rb' - - 'spec/graphql/mutations/merge_requests/set_wip_spec.rb' - - 'spec/graphql/resolvers/boards_resolver_spec.rb' - 'spec/lib/after_commit_queue_spec.rb' - 'spec/lib/backup/manager_spec.rb' - 'spec/lib/gitlab/alerting/alert_spec.rb' @@ -893,27 +890,6 @@ RSpec/EmptyLineAfterFinalLetItBe: - spec/views/search/_results.html.haml_spec.rb - spec/views/shared/_label_row.html.haml_spec.rb - spec/views/shared/milestones/_top.html.haml_spec.rb - - spec/workers/ci/create_cross_project_pipeline_worker_spec.rb - - spec/workers/cluster_update_app_worker_spec.rb - - spec/workers/environments/canary_ingress/update_worker_spec.rb - - spec/workers/expire_job_cache_worker_spec.rb - - spec/workers/gitlab/jira_import/import_issue_worker_spec.rb - - spec/workers/gitlab/jira_import/stage/start_import_worker_spec.rb - - spec/workers/gitlab/jira_import/stuck_jira_import_jobs_worker_spec.rb - - spec/workers/import_issues_csv_worker_spec.rb - - spec/workers/incident_management/add_severity_system_note_worker_spec.rb - - spec/workers/incident_management/process_alert_worker_spec.rb - - spec/workers/incident_management/process_prometheus_alert_worker_spec.rb - - spec/workers/jira_connect/sync_project_worker_spec.rb - - spec/workers/namespaces/onboarding_issue_created_worker_spec.rb - - spec/workers/packages/composer/cache_update_worker_spec.rb - - spec/workers/pages_domain_ssl_renewal_cron_worker_spec.rb - - spec/workers/projects/git_garbage_collect_worker_spec.rb - - spec/workers/prometheus/create_default_alerts_worker_spec.rb - - spec/workers/propagate_integration_group_worker_spec.rb - - spec/workers/propagate_integration_project_worker_spec.rb - - spec/workers/run_pipeline_schedule_worker_spec.rb - - spec/workers/update_external_pull_requests_worker_spec.rb RSpec/TimecopFreeze: Exclude: diff --git a/app/assets/javascripts/notebook/cells/markdown.vue b/app/assets/javascripts/notebook/cells/markdown.vue index c09db6851e5..9bf26e5a182 100644 --- a/app/assets/javascripts/notebook/cells/markdown.vue +++ b/app/assets/javascripts/notebook/cells/markdown.vue @@ -3,6 +3,7 @@ import katex from 'katex'; import marked from 'marked'; import { sanitize } from '~/lib/dompurify'; +import { hasContent } from '~/lib/utils/text_utility'; import Prompt from './prompt.vue'; const renderer = new marked.Renderer(); @@ -88,6 +89,38 @@ renderer.listitem = (t) => { const [text, inline] = renderKatex(t); return `
  • ${text}
  • `; }; +renderer.originalImage = renderer.image; + +renderer.image = function image(href, title, text) { + const attachmentHeader = `attachment:`; // eslint-disable-line @gitlab/require-i18n-strings + + if (!this.attachments || !href.startsWith(attachmentHeader)) { + return this.originalImage(href, title, text); + } + + let img = ``; + const filename = href.substring(attachmentHeader.length); + + if (hasContent(filename)) { + const attachment = this.attachments[filename]; + + if (attachment) { + const imageType = Object.keys(attachment)[0]; + + if (hasContent(imageType)) { + const data = attachment[imageType]; + const inlined = `data:${imageType};base64,${data}"`; // eslint-disable-line @gitlab/require-i18n-strings + img = this.originalImage(inlined, title, text); + } + } + } + + if (!hasContent(img)) { + return this.originalImage(href, title, text); + } + + return sanitize(img); +}; marked.setOptions({ renderer, @@ -105,6 +138,8 @@ export default { }, computed: { markdown() { + renderer.attachments = this.cell.attachments; + return sanitize(marked(this.cell.source.join('').replace(/\\/g, '\\\\')), { // allowedTags from GitLab's inline HTML guidelines // https://docs.gitlab.com/ee/user/markdown.html#inline-html diff --git a/app/finders/users_with_pending_todos_finder.rb b/app/finders/users_with_pending_todos_finder.rb deleted file mode 100644 index 461bd92a366..00000000000 --- a/app/finders/users_with_pending_todos_finder.rb +++ /dev/null @@ -1,16 +0,0 @@ -# frozen_string_literal: true - -# Finder that given a target (e.g. an issue) finds all the users that have -# pending todos for said target. -class UsersWithPendingTodosFinder - attr_reader :target - - # target - The target, such as an Issue or MergeRequest. - def initialize(target) - @target = target - end - - def execute - User.for_todos(target.todos.pending) - end -end diff --git a/app/models/concerns/sidebars/container_with_html_options.rb b/app/models/concerns/sidebars/container_with_html_options.rb deleted file mode 100644 index 12ea366c66a..00000000000 --- a/app/models/concerns/sidebars/container_with_html_options.rb +++ /dev/null @@ -1,42 +0,0 @@ -# frozen_string_literal: true - -module Sidebars - module ContainerWithHtmlOptions - # The attributes returned from this method - # will be applied to helper methods like - # `link_to` or the div containing the container. - def container_html_options - { - aria: { label: title } - }.merge(extra_container_html_options) - end - - # Classes will override mostly this method - # and not `container_html_options`. - def extra_container_html_options - {} - end - - # Attributes to pass to the html_options attribute - # in the helper method that sets the active class - # on each element. - def nav_link_html_options - {} - end - - def title - raise NotImplementedError - end - - # The attributes returned from this method - # will be applied right next to the title, - # for example in the span that renders the title. - def title_html_options - {} - end - - def link - raise NotImplementedError - end - end -end diff --git a/app/models/concerns/sidebars/has_active_routes.rb b/app/models/concerns/sidebars/has_active_routes.rb deleted file mode 100644 index e7a153f067a..00000000000 --- a/app/models/concerns/sidebars/has_active_routes.rb +++ /dev/null @@ -1,16 +0,0 @@ -# frozen_string_literal: true - -module Sidebars - module HasActiveRoutes - # This method will indicate for which paths or - # controllers, the menu or menu item should - # be set as active. - # - # The returned values are passed to the `nav_link` helper method, - # so the params can be either `path`, `page`, `controller`. - # Param 'action' is not supported. - def active_routes - {} - end - end -end diff --git a/app/models/concerns/sidebars/has_hint.rb b/app/models/concerns/sidebars/has_hint.rb deleted file mode 100644 index 21dca39dca0..00000000000 --- a/app/models/concerns/sidebars/has_hint.rb +++ /dev/null @@ -1,16 +0,0 @@ -# frozen_string_literal: true - -# This module has the necessary methods to store -# hints for menus. Hints are elements displayed -# when the user hover the menu item. -module Sidebars - module HasHint - def show_hint? - false - end - - def hint_html_options - {} - end - end -end diff --git a/app/models/concerns/sidebars/has_icon.rb b/app/models/concerns/sidebars/has_icon.rb deleted file mode 100644 index d1a87918285..00000000000 --- a/app/models/concerns/sidebars/has_icon.rb +++ /dev/null @@ -1,27 +0,0 @@ -# frozen_string_literal: true - -# This module has the necessary methods to show -# sprites or images next to the menu item. -module Sidebars - module HasIcon - def sprite_icon - nil - end - - def sprite_icon_html_options - {} - end - - def image_path - nil - end - - def image_html_options - {} - end - - def icon_or_image? - sprite_icon || image_path - end - end -end diff --git a/app/models/concerns/sidebars/has_pill.rb b/app/models/concerns/sidebars/has_pill.rb deleted file mode 100644 index ad7064fe63d..00000000000 --- a/app/models/concerns/sidebars/has_pill.rb +++ /dev/null @@ -1,21 +0,0 @@ -# frozen_string_literal: true - -# This module introduces the logic to show the "pill" element -# next to the menu item, indicating the a count. -module Sidebars - module HasPill - def has_pill? - false - end - - # In this method we will need to provide the query - # to retrieve the elements count - def pill_count - raise NotImplementedError - end - - def pill_html_options - {} - end - end -end diff --git a/app/models/concerns/sidebars/positionable_list.rb b/app/models/concerns/sidebars/positionable_list.rb deleted file mode 100644 index 30830d547f3..00000000000 --- a/app/models/concerns/sidebars/positionable_list.rb +++ /dev/null @@ -1,37 +0,0 @@ -# frozen_string_literal: true - -# This module handles elements in a list. All elements -# must have a different class -module Sidebars - module PositionableList - def add_element(list, element) - list << element - end - - def insert_element_before(list, before_element, new_element) - index = index_of(list, before_element) - - if index - list.insert(index, new_element) - else - list.unshift(new_element) - end - end - - def insert_element_after(list, after_element, new_element) - index = index_of(list, after_element) - - if index - list.insert(index + 1, new_element) - else - add_element(list, new_element) - end - end - - private - - def index_of(list, element) - list.index { |e| e.is_a?(element) } - end - end -end diff --git a/app/models/concerns/sidebars/renderable.rb b/app/models/concerns/sidebars/renderable.rb deleted file mode 100644 index a3976af8515..00000000000 --- a/app/models/concerns/sidebars/renderable.rb +++ /dev/null @@ -1,12 +0,0 @@ -# frozen_string_literal: true - -module Sidebars - module Renderable - # This method will control whether the menu or menu_item - # should be rendered. It will be overriden by specific - # classes. - def render? - true - end - end -end diff --git a/app/models/group.rb b/app/models/group.rb index 2967c1ffc1d..60a0e27428d 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -118,8 +118,6 @@ class Group < Namespace .where("project_authorizations.user_id IN (?)", user_ids) end - delegate :default_branch_name, to: :namespace_settings - class << self def sort_by_attribute(method) if method == 'storage_size_desc' diff --git a/app/models/sidebars/context.rb b/app/models/sidebars/context.rb deleted file mode 100644 index d9ac2705aaf..00000000000 --- a/app/models/sidebars/context.rb +++ /dev/null @@ -1,21 +0,0 @@ -# frozen_string_literal: true - -# This class stores all the information needed to display and -# render the sidebar and menus. -# It usually stores information regarding the context and calculated -# values where the logic is in helpers. -module Sidebars - class Context - attr_reader :current_user, :container - - def initialize(current_user:, container:, **args) - @current_user = current_user - @container = container - - args.each do |key, value| - singleton_class.public_send(:attr_reader, key) # rubocop:disable GitlabSecurity/PublicSend - instance_variable_set("@#{key}", value) - end - end - end -end diff --git a/app/models/sidebars/menu.rb b/app/models/sidebars/menu.rb deleted file mode 100644 index a5c8be2bb31..00000000000 --- a/app/models/sidebars/menu.rb +++ /dev/null @@ -1,82 +0,0 @@ -# frozen_string_literal: true - -module Sidebars - class Menu - extend ::Gitlab::Utils::Override - include ::Gitlab::Routing - include GitlabRoutingHelper - include Gitlab::Allowable - include ::Sidebars::HasPill - include ::Sidebars::HasIcon - include ::Sidebars::PositionableList - include ::Sidebars::Renderable - include ::Sidebars::ContainerWithHtmlOptions - include ::Sidebars::HasActiveRoutes - - attr_reader :context - delegate :current_user, :container, to: :@context - - def initialize(context) - @context = context - @items = [] - - configure_menu_items - end - - def configure_menu_items - # No-op - end - - override :render? - def render? - @items.empty? || renderable_items.any? - end - - # Menus might have or not a link - override :link - def link - nil - end - - # This method normalizes the information retrieved from the submenus and this menu - # Value from menus is something like: [{ path: 'foo', path: 'bar', controller: :foo }] - # This method filters the information and returns: { path: ['foo', 'bar'], controller: :foo } - def all_active_routes - @all_active_routes ||= begin - ([active_routes] + renderable_items.map(&:active_routes)).flatten.each_with_object({}) do |pairs, hash| - pairs.each do |k, v| - hash[k] ||= [] - hash[k] += Array(v) - hash[k].uniq! - end - - hash - end - end - end - - def has_items? - @items.any? - end - - def add_item(item) - add_element(@items, item) - end - - def insert_item_before(before_item, new_item) - insert_element_before(@items, before_item, new_item) - end - - def insert_item_after(after_item, new_item) - insert_element_after(@items, after_item, new_item) - end - - def has_renderable_items? - renderable_items.any? - end - - def renderable_items - @renderable_items ||= @items.select(&:render?) - end - end -end diff --git a/app/models/sidebars/menu_item.rb b/app/models/sidebars/menu_item.rb deleted file mode 100644 index 7466b31898e..00000000000 --- a/app/models/sidebars/menu_item.rb +++ /dev/null @@ -1,21 +0,0 @@ -# frozen_string_literal: true - -module Sidebars - class MenuItem - extend ::Gitlab::Utils::Override - include ::Gitlab::Routing - include GitlabRoutingHelper - include Gitlab::Allowable - include ::Sidebars::HasIcon - include ::Sidebars::HasHint - include ::Sidebars::Renderable - include ::Sidebars::ContainerWithHtmlOptions - include ::Sidebars::HasActiveRoutes - - attr_reader :context - - def initialize(context) - @context = context - end - end -end diff --git a/app/models/sidebars/panel.rb b/app/models/sidebars/panel.rb deleted file mode 100644 index 5c8191ebda3..00000000000 --- a/app/models/sidebars/panel.rb +++ /dev/null @@ -1,75 +0,0 @@ -# frozen_string_literal: true - -module Sidebars - class Panel - extend ::Gitlab::Utils::Override - include ::Sidebars::PositionableList - - attr_reader :context, :scope_menu, :hidden_menu - - def initialize(context) - @context = context - @scope_menu = nil - @hidden_menu = nil - @menus = [] - - configure_menus - end - - def configure_menus - # No-op - end - - def add_menu(menu) - add_element(@menus, menu) - end - - def insert_menu_before(before_menu, new_menu) - insert_element_before(@menus, before_menu, new_menu) - end - - def insert_menu_after(after_menu, new_menu) - insert_element_after(@menus, after_menu, new_menu) - end - - def set_scope_menu(scope_menu) - @scope_menu = scope_menu - end - - def set_hidden_menu(hidden_menu) - @hidden_menu = hidden_menu - end - - def aria_label - raise NotImplementedError - end - - def has_renderable_menus? - renderable_menus.any? - end - - def renderable_menus - @renderable_menus ||= @menus.select(&:render?) - end - - def container - context.container - end - - # Auxiliar method that helps with the migration from - # regular views to the new logic - def render_raw_scope_menu_partial - # No-op - end - - # Auxiliar method that helps with the migration from - # regular views to the new logic. - # - # Any menu inside this partial will be added after - # all the menus added in the `configure_menus` - # method. - def render_raw_menus_partial - # No-op - end - end -end diff --git a/app/models/sidebars/projects/context.rb b/app/models/sidebars/projects/context.rb deleted file mode 100644 index 4c82309035d..00000000000 --- a/app/models/sidebars/projects/context.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true - -module Sidebars - module Projects - class Context < ::Sidebars::Context - def initialize(current_user:, container:, **args) - super(current_user: current_user, container: container, project: container, **args) - end - end - end -end diff --git a/app/models/sidebars/projects/menus/learn_gitlab/menu.rb b/app/models/sidebars/projects/menus/learn_gitlab/menu.rb deleted file mode 100644 index 4b572846d1a..00000000000 --- a/app/models/sidebars/projects/menus/learn_gitlab/menu.rb +++ /dev/null @@ -1,41 +0,0 @@ -# frozen_string_literal: true - -module Sidebars - module Projects - module Menus - module LearnGitlab - class Menu < ::Sidebars::Menu - override :link - def link - project_learn_gitlab_path(context.project) - end - - override :active_routes - def active_routes - { controller: :learn_gitlab } - end - - override :title - def title - _('Learn GitLab') - end - - override :extra_container_html_options - def nav_link_html_options - { class: 'home' } - end - - override :sprite_icon - def sprite_icon - 'home' - end - - override :render? - def render? - context.learn_gitlab_experiment_enabled - end - end - end - end - end -end diff --git a/app/models/sidebars/projects/menus/project_overview/menu.rb b/app/models/sidebars/projects/menus/project_overview/menu.rb deleted file mode 100644 index e6aa8ed159f..00000000000 --- a/app/models/sidebars/projects/menus/project_overview/menu.rb +++ /dev/null @@ -1,45 +0,0 @@ -# frozen_string_literal: true - -module Sidebars - module Projects - module Menus - module ProjectOverview - class Menu < ::Sidebars::Menu - override :configure_menu_items - def configure_menu_items - add_item(MenuItems::Details.new(context)) - add_item(MenuItems::Activity.new(context)) - add_item(MenuItems::Releases.new(context)) - end - - override :link - def link - project_path(context.project) - end - - override :extra_container_html_options - def extra_container_html_options - { - class: 'shortcuts-project rspec-project-link' - } - end - - override :extra_container_html_options - def nav_link_html_options - { class: 'home' } - end - - override :title - def title - _('Project overview') - end - - override :sprite_icon - def sprite_icon - 'home' - end - end - end - end - end -end diff --git a/app/models/sidebars/projects/menus/project_overview/menu_items/activity.rb b/app/models/sidebars/projects/menus/project_overview/menu_items/activity.rb deleted file mode 100644 index 46d0f0bc43b..00000000000 --- a/app/models/sidebars/projects/menus/project_overview/menu_items/activity.rb +++ /dev/null @@ -1,35 +0,0 @@ -# frozen_string_literal: true - -module Sidebars - module Projects - module Menus - module ProjectOverview - module MenuItems - class Activity < ::Sidebars::MenuItem - override :link - def link - activity_project_path(context.project) - end - - override :extra_container_html_options - def extra_container_html_options - { - class: 'shortcuts-project-activity' - } - end - - override :active_routes - def active_routes - { path: 'projects#activity' } - end - - override :title - def title - _('Activity') - end - end - end - end - end - end -end diff --git a/app/models/sidebars/projects/menus/project_overview/menu_items/details.rb b/app/models/sidebars/projects/menus/project_overview/menu_items/details.rb deleted file mode 100644 index c40c2ed8fa2..00000000000 --- a/app/models/sidebars/projects/menus/project_overview/menu_items/details.rb +++ /dev/null @@ -1,36 +0,0 @@ -# frozen_string_literal: true - -module Sidebars - module Projects - module Menus - module ProjectOverview - module MenuItems - class Details < ::Sidebars::MenuItem - override :link - def link - project_path(context.project) - end - - override :extra_container_html_options - def extra_container_html_options - { - aria: { label: _('Project details') }, - class: 'shortcuts-project' - } - end - - override :active_routes - def active_routes - { path: 'projects#show' } - end - - override :title - def title - _('Details') - end - end - end - end - end - end -end diff --git a/app/models/sidebars/projects/menus/project_overview/menu_items/releases.rb b/app/models/sidebars/projects/menus/project_overview/menu_items/releases.rb deleted file mode 100644 index 5e8348f4398..00000000000 --- a/app/models/sidebars/projects/menus/project_overview/menu_items/releases.rb +++ /dev/null @@ -1,40 +0,0 @@ -# frozen_string_literal: true - -module Sidebars - module Projects - module Menus - module ProjectOverview - module MenuItems - class Releases < ::Sidebars::MenuItem - override :link - def link - project_releases_path(context.project) - end - - override :extra_container_html_options - def extra_container_html_options - { - class: 'shortcuts-project-releases' - } - end - - override :render? - def render? - can?(context.current_user, :read_release, context.project) && !context.project.empty_repo? - end - - override :active_routes - def active_routes - { controller: :releases } - end - - override :title - def title - _('Releases') - end - end - end - end - end - end -end diff --git a/app/models/sidebars/projects/menus/repository/menu.rb b/app/models/sidebars/projects/menus/repository/menu.rb deleted file mode 100644 index f49a0479521..00000000000 --- a/app/models/sidebars/projects/menus/repository/menu.rb +++ /dev/null @@ -1,59 +0,0 @@ -# frozen_string_literal: true - -module Sidebars - module Projects - module Menus - module Repository - class Menu < ::Sidebars::Menu - override :configure_menu_items - def configure_menu_items - add_item(MenuItems::Files.new(context)) - add_item(MenuItems::Commits.new(context)) - add_item(MenuItems::Branches.new(context)) - add_item(MenuItems::Tags.new(context)) - add_item(MenuItems::Contributors.new(context)) - add_item(MenuItems::Graphs.new(context)) - add_item(MenuItems::Compare.new(context)) - end - - override :link - def link - project_tree_path(context.project) - end - - override :extra_container_html_options - def extra_container_html_options - { - class: 'shortcuts-tree' - } - end - - override :title - def title - _('Repository') - end - - override :title_html_options - def title_html_options - { - id: 'js-onboarding-repo-link' - } - end - - override :sprite_icon - def sprite_icon - 'doc-text' - end - - override :render? - def render? - can?(context.current_user, :download_code, context.project) && - !context.project.empty_repo? - end - end - end - end - end -end - -Sidebars::Projects::Menus::Repository::Menu.prepend_if_ee('EE::Sidebars::Projects::Menus::Repository::Menu') diff --git a/app/models/sidebars/projects/menus/repository/menu_items/branches.rb b/app/models/sidebars/projects/menus/repository/menu_items/branches.rb deleted file mode 100644 index 4a62803dd2b..00000000000 --- a/app/models/sidebars/projects/menus/repository/menu_items/branches.rb +++ /dev/null @@ -1,35 +0,0 @@ -# frozen_string_literal: true - -module Sidebars - module Projects - module Menus - module Repository - module MenuItems - class Branches < ::Sidebars::MenuItem - override :link - def link - project_branches_path(context.project) - end - - override :extra_container_html_options - def extra_container_html_options - { - id: 'js-onboarding-branches-link' - } - end - - override :active_routes - def active_routes - { controller: :branches } - end - - override :title - def title - _('Branches') - end - end - end - end - end - end -end diff --git a/app/models/sidebars/projects/menus/repository/menu_items/commits.rb b/app/models/sidebars/projects/menus/repository/menu_items/commits.rb deleted file mode 100644 index 647cf89133e..00000000000 --- a/app/models/sidebars/projects/menus/repository/menu_items/commits.rb +++ /dev/null @@ -1,35 +0,0 @@ -# frozen_string_literal: true - -module Sidebars - module Projects - module Menus - module Repository - module MenuItems - class Commits < ::Sidebars::MenuItem - override :link - def link - project_commits_path(context.project, context.current_ref) - end - - override :extra_container_html_options - def extra_container_html_options - { - id: 'js-onboarding-commits-link' - } - end - - override :active_routes - def active_routes - { controller: %w(commit commits) } - end - - override :title - def title - _('Commits') - end - end - end - end - end - end -end diff --git a/app/models/sidebars/projects/menus/repository/menu_items/compare.rb b/app/models/sidebars/projects/menus/repository/menu_items/compare.rb deleted file mode 100644 index 4812636b63f..00000000000 --- a/app/models/sidebars/projects/menus/repository/menu_items/compare.rb +++ /dev/null @@ -1,28 +0,0 @@ -# frozen_string_literal: true - -module Sidebars - module Projects - module Menus - module Repository - module MenuItems - class Compare < ::Sidebars::MenuItem - override :link - def link - project_compare_index_path(context.project, from: context.project.repository.root_ref, to: context.current_ref) - end - - override :active_routes - def active_routes - { controller: :compare } - end - - override :title - def title - _('Compare') - end - end - end - end - end - end -end diff --git a/app/models/sidebars/projects/menus/repository/menu_items/contributors.rb b/app/models/sidebars/projects/menus/repository/menu_items/contributors.rb deleted file mode 100644 index d60fd05bb64..00000000000 --- a/app/models/sidebars/projects/menus/repository/menu_items/contributors.rb +++ /dev/null @@ -1,28 +0,0 @@ -# frozen_string_literal: true - -module Sidebars - module Projects - module Menus - module Repository - module MenuItems - class Contributors < ::Sidebars::MenuItem - override :link - def link - project_graph_path(context.project, context.current_ref) - end - - override :active_routes - def active_routes - { path: 'graphs#show' } - end - - override :title - def title - _('Contributors') - end - end - end - end - end - end -end diff --git a/app/models/sidebars/projects/menus/repository/menu_items/files.rb b/app/models/sidebars/projects/menus/repository/menu_items/files.rb deleted file mode 100644 index 4989efe9fa5..00000000000 --- a/app/models/sidebars/projects/menus/repository/menu_items/files.rb +++ /dev/null @@ -1,28 +0,0 @@ -# frozen_string_literal: true - -module Sidebars - module Projects - module Menus - module Repository - module MenuItems - class Files < ::Sidebars::MenuItem - override :link - def link - project_tree_path(context.project, context.current_ref) - end - - override :active_routes - def active_routes - { controller: %w[tree blob blame edit_tree new_tree find_file] } - end - - override :title - def title - _('Files') - end - end - end - end - end - end -end diff --git a/app/models/sidebars/projects/menus/repository/menu_items/graphs.rb b/app/models/sidebars/projects/menus/repository/menu_items/graphs.rb deleted file mode 100644 index a57021be4d0..00000000000 --- a/app/models/sidebars/projects/menus/repository/menu_items/graphs.rb +++ /dev/null @@ -1,28 +0,0 @@ -# frozen_string_literal: true - -module Sidebars - module Projects - module Menus - module Repository - module MenuItems - class Graphs < ::Sidebars::MenuItem - override :link - def link - project_network_path(context.project, context.current_ref) - end - - override :active_routes - def active_routes - { controller: :network } - end - - override :title - def title - _('Graph') - end - end - end - end - end - end -end diff --git a/app/models/sidebars/projects/menus/repository/menu_items/tags.rb b/app/models/sidebars/projects/menus/repository/menu_items/tags.rb deleted file mode 100644 index d84bc89b93c..00000000000 --- a/app/models/sidebars/projects/menus/repository/menu_items/tags.rb +++ /dev/null @@ -1,28 +0,0 @@ -# frozen_string_literal: true - -module Sidebars - module Projects - module Menus - module Repository - module MenuItems - class Tags < ::Sidebars::MenuItem - override :link - def link - project_tags_path(context.project) - end - - override :active_routes - def active_routes - { controller: :tags } - end - - override :title - def title - _('Tags') - end - end - end - end - end - end -end diff --git a/app/models/sidebars/projects/menus/scope/menu.rb b/app/models/sidebars/projects/menus/scope/menu.rb deleted file mode 100644 index 3b699083f75..00000000000 --- a/app/models/sidebars/projects/menus/scope/menu.rb +++ /dev/null @@ -1,21 +0,0 @@ -# frozen_string_literal: true - -module Sidebars - module Projects - module Menus - module Scope - class Menu < ::Sidebars::Menu - override :link - def link - project_path(context.project) - end - - override :title - def title - context.project.name - end - end - end - end - end -end diff --git a/app/models/sidebars/projects/panel.rb b/app/models/sidebars/projects/panel.rb deleted file mode 100644 index ec4fac53a40..00000000000 --- a/app/models/sidebars/projects/panel.rb +++ /dev/null @@ -1,26 +0,0 @@ -# frozen_string_literal: true - -module Sidebars - module Projects - class Panel < ::Sidebars::Panel - override :configure_menus - def configure_menus - set_scope_menu(Sidebars::Projects::Menus::Scope::Menu.new(context)) - - add_menu(Sidebars::Projects::Menus::ProjectOverview::Menu.new(context)) - add_menu(Sidebars::Projects::Menus::LearnGitlab::Menu.new(context)) - add_menu(Sidebars::Projects::Menus::Repository::Menu.new(context)) - end - - override :render_raw_menus_partial - def render_raw_menus_partial - 'layouts/nav/sidebar/project_menus' - end - - override :aria_label - def aria_label - _('Project navigation') - end - end - end -end diff --git a/app/models/user.rb b/app/models/user.rb index 4f9874ab94b..92d11d231ec 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -376,7 +376,7 @@ class User < ApplicationRecord scope :by_name, -> (names) { iwhere(name: Array(names)) } scope :by_user_email, -> (emails) { iwhere(email: Array(emails)) } scope :by_emails, -> (emails) { joins(:emails).where(emails: { email: Array(emails).map(&:downcase) }) } - scope :for_todos, -> (todos) { where(id: todos.select(:user_id)) } + scope :for_todos, -> (todos) { where(id: todos.select(:user_id).distinct) } scope :with_emails, -> { preload(:emails) } scope :with_dashboard, -> (dashboard) { where(dashboard: dashboard) } scope :with_public_profile, -> { where(private_profile: false) } diff --git a/app/services/todo_service.rb b/app/services/todo_service.rb index e473a6dc594..d3e7d3040af 100644 --- a/app/services/todo_service.rb +++ b/app/services/todo_service.rb @@ -43,7 +43,7 @@ class TodoService # updates the todo counts for those users. # def destroy_target(target) - todo_users = UsersWithPendingTodosFinder.new(target).execute.to_a + todo_users = User.for_todos(target.todos).to_a yield target diff --git a/app/views/admin/groups/_group.html.haml b/app/views/admin/groups/_group.html.haml index df7af86e089..bbc65850794 100644 --- a/app/views/admin/groups/_group.html.haml +++ b/app/views/admin/groups/_group.html.haml @@ -15,7 +15,7 @@ = markdown_field(group, :description) .stats.gl-text-gray-500.gl-flex-shrink-0.gl-display-none.gl-sm-display-flex - %span.badge.badge-pill + %span.badge.badge-muted.badge-pill.gl-badge.sm = storage_counter(group.storage_size) = render_if_exists 'admin/namespace_plan_badge', namespace: group, css_class: 'gl-ml-5 gl-mr-0' diff --git a/app/views/admin/users/_users.html.haml b/app/views/admin/users/_users.html.haml index c79b2e978f2..cd128e39c4f 100644 --- a/app/views/admin/users/_users.html.haml +++ b/app/views/admin/users/_users.html.haml @@ -7,39 +7,39 @@ = nav_link(html_options: { class: active_when(params[:filter].nil?) }) do = link_to admin_users_path do = s_('AdminUsers|Active') - %small.badge.badge-pill= limited_counter_with_delimiter(User.active_without_ghosts) + %small.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= limited_counter_with_delimiter(User.active_without_ghosts) = nav_link(html_options: { class: active_when(params[:filter] == 'admins') }) do = link_to admin_users_path(filter: "admins") do = s_('AdminUsers|Admins') - %small.badge.badge-pill= limited_counter_with_delimiter(User.admins) + %small.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= limited_counter_with_delimiter(User.admins) = nav_link(html_options: { class: "#{active_when(params[:filter] == 'two_factor_enabled')} filter-two-factor-enabled" }) do = link_to admin_users_path(filter: 'two_factor_enabled') do = s_('AdminUsers|2FA Enabled') - %small.badge.badge-pill= limited_counter_with_delimiter(User.with_two_factor) + %small.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= limited_counter_with_delimiter(User.with_two_factor) = nav_link(html_options: { class: "#{active_when(params[:filter] == 'two_factor_disabled')} filter-two-factor-disabled" }) do = link_to admin_users_path(filter: 'two_factor_disabled') do = s_('AdminUsers|2FA Disabled') - %small.badge.badge-pill= limited_counter_with_delimiter(User.without_two_factor) + %small.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= limited_counter_with_delimiter(User.without_two_factor) = nav_link(html_options: { class: active_when(params[:filter] == 'external') }) do = link_to admin_users_path(filter: 'external') do = s_('AdminUsers|External') - %small.badge.badge-pill= limited_counter_with_delimiter(User.external) + %small.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= limited_counter_with_delimiter(User.external) = nav_link(html_options: { class: active_when(params[:filter] == 'blocked') }) do = link_to admin_users_path(filter: "blocked") do = s_('AdminUsers|Blocked') - %small.badge.badge-pill= limited_counter_with_delimiter(User.blocked) + %small.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= limited_counter_with_delimiter(User.blocked) = nav_link(html_options: { class: "#{active_when(params[:filter] == 'blocked_pending_approval')} filter-blocked-pending-approval" }) do = link_to admin_users_path(filter: "blocked_pending_approval"), data: { qa_selector: 'pending_approval_tab' } do = s_('AdminUsers|Pending approval') - %small.badge.badge-pill= limited_counter_with_delimiter(User.blocked_pending_approval) + %small.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= limited_counter_with_delimiter(User.blocked_pending_approval) = nav_link(html_options: { class: active_when(params[:filter] == 'deactivated') }) do = link_to admin_users_path(filter: "deactivated") do = s_('AdminUsers|Deactivated') - %small.badge.badge-pill= limited_counter_with_delimiter(User.deactivated) + %small.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= limited_counter_with_delimiter(User.deactivated) = nav_link(html_options: { class: active_when(params[:filter] == 'wop') }) do = link_to admin_users_path(filter: "wop") do = s_('AdminUsers|Without projects') - %small.badge.badge-pill= limited_counter_with_delimiter(User.without_projects) + %small.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= limited_counter_with_delimiter(User.without_projects) .nav-controls = render_if_exists 'admin/users/admin_email_users' = render_if_exists 'admin/users/admin_export_user_permissions' diff --git a/app/views/dashboard/todos/index.html.haml b/app/views/dashboard/todos/index.html.haml index a0016417f0c..66587518efc 100644 --- a/app/views/dashboard/todos/index.html.haml +++ b/app/views/dashboard/todos/index.html.haml @@ -15,13 +15,13 @@ = link_to todos_filter_path(state: 'pending') do %span To Do - %span.badge.badge-pill + %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm = number_with_delimiter(todos_pending_count) %li.todos-done{ class: active_when(params[:state] == 'done') }> = link_to todos_filter_path(state: 'done') do %span Done - %span.badge.badge-pill + %span.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm = number_with_delimiter(todos_done_count) .nav-controls diff --git a/app/views/groups/milestones/_header_title.html.haml b/app/views/groups/milestones/_header_title.html.haml index 24eb39b8e2f..f222dba1f90 100644 --- a/app/views/groups/milestones/_header_title.html.haml +++ b/app/views/groups/milestones/_header_title.html.haml @@ -1,2 +1,2 @@ - breadcrumb_title @milestone.title -- add_to_breadcrumbs "Milestones", group_milestones_path(@group) +- add_to_breadcrumbs _("Milestones"), group_milestones_path(@group) diff --git a/app/views/profiles/preferences/show.html.haml b/app/views/profiles/preferences/show.html.haml index 535964028f4..0adad6b64a0 100644 --- a/app/views/profiles/preferences/show.html.haml +++ b/app/views/profiles/preferences/show.html.haml @@ -100,7 +100,7 @@ .form-group = f.label :tab_width, s_('Preferences|Tab width'), class: 'label-bold' = f.number_field :tab_width, - class: 'form-control', + class: 'form-control gl-form-input', min: Gitlab::TabWidth::MIN, max: Gitlab::TabWidth::MAX, required: true diff --git a/changelogs/unreleased/322604-set-hipchat-metric-definitions-as-removed.yml b/changelogs/unreleased/322604-set-hipchat-metric-definitions-as-removed.yml new file mode 100644 index 00000000000..7f50948715f --- /dev/null +++ b/changelogs/unreleased/322604-set-hipchat-metric-definitions-as-removed.yml @@ -0,0 +1,5 @@ +--- +title: Set Hipchat metric definitions status to removed +merge_request: 59779 +author: +type: removed diff --git a/changelogs/unreleased/326839-improve-message.yml b/changelogs/unreleased/326839-improve-message.yml new file mode 100644 index 00000000000..62d5d15073c --- /dev/null +++ b/changelogs/unreleased/326839-improve-message.yml @@ -0,0 +1,5 @@ +--- +title: Improve message for :project_not_found error to indicate possible cause +merge_request: 58945 +author: Ignacy Moryc @ignacy +type: changed diff --git a/changelogs/unreleased/327110-update-cached-count-for-done-todos-when-deleting-todo-targets.yml b/changelogs/unreleased/327110-update-cached-count-for-done-todos-when-deleting-todo-targets.yml new file mode 100644 index 00000000000..118155c9172 --- /dev/null +++ b/changelogs/unreleased/327110-update-cached-count-for-done-todos-when-deleting-todo-targets.yml @@ -0,0 +1,5 @@ +--- +title: Update cached count for "done" todos when deleting todo targets +merge_request: 58773 +author: +type: fixed diff --git a/changelogs/unreleased/Externalize-strings-in-milestones-_header_title-html-haml.yml b/changelogs/unreleased/Externalize-strings-in-milestones-_header_title-html-haml.yml new file mode 100644 index 00000000000..342b7acf5e2 --- /dev/null +++ b/changelogs/unreleased/Externalize-strings-in-milestones-_header_title-html-haml.yml @@ -0,0 +1,5 @@ +--- +title: Externalize strings in milestones/_header_title.html.haml +merge_request: 58300 +author: nuwe1 +type: other diff --git a/changelogs/unreleased/gl-badge-admin-groups.yml b/changelogs/unreleased/gl-badge-admin-groups.yml new file mode 100644 index 00000000000..1fcbdce8655 --- /dev/null +++ b/changelogs/unreleased/gl-badge-admin-groups.yml @@ -0,0 +1,5 @@ +--- +title: Add gl-badge for storage badge in admin groups page +merge_request: 57954 +author: Yogi (@yo) +type: changed diff --git a/changelogs/unreleased/gl-badge-admin-users.yml b/changelogs/unreleased/gl-badge-admin-users.yml new file mode 100644 index 00000000000..55f7f481644 --- /dev/null +++ b/changelogs/unreleased/gl-badge-admin-users.yml @@ -0,0 +1,5 @@ +--- +title: Add gl-badge for badges in admin users nav +merge_request: 57951 +author: Yogi (@yo) +type: changed diff --git a/changelogs/unreleased/gl-badge-todos.yml b/changelogs/unreleased/gl-badge-todos.yml new file mode 100644 index 00000000000..887171aac21 --- /dev/null +++ b/changelogs/unreleased/gl-badge-todos.yml @@ -0,0 +1,5 @@ +--- +title: Add gl-badge for badges in todos nav +merge_request: 57943 +author: Yogi (@yo) +type: changed diff --git a/changelogs/unreleased/gl-form-preferences.yml b/changelogs/unreleased/gl-form-preferences.yml new file mode 100644 index 00000000000..8fb8ec9027d --- /dev/null +++ b/changelogs/unreleased/gl-form-preferences.yml @@ -0,0 +1,5 @@ +--- +title: Apply gl-form-input for fields in preferences page +merge_request: 58004 +author: Yogi (@yo) +type: changed diff --git a/changelogs/unreleased/rails-save-bang-graphql.yml b/changelogs/unreleased/rails-save-bang-graphql.yml new file mode 100644 index 00000000000..0ae9aa06c2b --- /dev/null +++ b/changelogs/unreleased/rails-save-bang-graphql.yml @@ -0,0 +1,5 @@ +--- +title: Fix Rails/SaveBang rubocop offenses in spec/graphql +merge_request: 57912 +author: Abdul Wadood @abdulwd +type: fixed diff --git a/changelogs/unreleased/rspec-empty-lines-after-letitbe-spec-workers.yml b/changelogs/unreleased/rspec-empty-lines-after-letitbe-spec-workers.yml new file mode 100644 index 00000000000..715beb2016b --- /dev/null +++ b/changelogs/unreleased/rspec-empty-lines-after-letitbe-spec-workers.yml @@ -0,0 +1,5 @@ +--- +title: Fix RSpec/EmptyLineAfterFinalLetItBe rubocop offenses in spec/workers +merge_request: 58421 +author: Abdul Wadood @abdulwd +type: fixed diff --git a/changelogs/unreleased/sh-jupyter-fix-images.yml b/changelogs/unreleased/sh-jupyter-fix-images.yml new file mode 100644 index 00000000000..d40385702f1 --- /dev/null +++ b/changelogs/unreleased/sh-jupyter-fix-images.yml @@ -0,0 +1,5 @@ +--- +title: Fix images not showing in Jupyter Markdown tables +merge_request: 59551 +author: +type: fixed diff --git a/config/metrics/counts_all/20210216175910_projects_hipchat_active.yml b/config/metrics/counts_all/20210216175910_projects_hipchat_active.yml index cc49000a57f..32bbcb11c30 100644 --- a/config/metrics/counts_all/20210216175910_projects_hipchat_active.yml +++ b/config/metrics/counts_all/20210216175910_projects_hipchat_active.yml @@ -6,7 +6,8 @@ product_stage: create product_group: group::ecosystem product_category: integrations value_type: number -status: data_available +status: removed +milestone_removed: '13.11' time_frame: all data_source: database distribution: diff --git a/config/metrics/counts_all/20210216175912_groups_hipchat_active.yml b/config/metrics/counts_all/20210216175912_groups_hipchat_active.yml index 1496bc21bcd..1a8224ba446 100644 --- a/config/metrics/counts_all/20210216175912_groups_hipchat_active.yml +++ b/config/metrics/counts_all/20210216175912_groups_hipchat_active.yml @@ -6,7 +6,8 @@ product_stage: create product_group: group::ecosystem product_category: integrations value_type: number -status: data_available +status: removed +milestone_removed: '13.11' time_frame: all data_source: database distribution: diff --git a/config/metrics/counts_all/20210216175913_templates_hipchat_active.yml b/config/metrics/counts_all/20210216175913_templates_hipchat_active.yml index 3f285fe0ed6..6b24dedf93a 100644 --- a/config/metrics/counts_all/20210216175913_templates_hipchat_active.yml +++ b/config/metrics/counts_all/20210216175913_templates_hipchat_active.yml @@ -6,7 +6,8 @@ product_stage: create product_group: group::ecosystem product_category: integrations value_type: number -status: data_available +status: removed +milestone_removed: '13.11' time_frame: all data_source: database distribution: diff --git a/config/metrics/counts_all/20210216175915_instances_hipchat_active.yml b/config/metrics/counts_all/20210216175915_instances_hipchat_active.yml index 0e2f5c5fe1b..18d5e6f9666 100644 --- a/config/metrics/counts_all/20210216175915_instances_hipchat_active.yml +++ b/config/metrics/counts_all/20210216175915_instances_hipchat_active.yml @@ -6,7 +6,8 @@ product_stage: create product_group: group::ecosystem product_category: integrations value_type: number -status: data_available +status: removed +milestone_removed: '13.11' time_frame: all data_source: database distribution: diff --git a/config/metrics/counts_all/20210216175917_projects_inheriting_hipchat_active.yml b/config/metrics/counts_all/20210216175917_projects_inheriting_hipchat_active.yml index 0980e3b587c..da9f9df4fb7 100644 --- a/config/metrics/counts_all/20210216175917_projects_inheriting_hipchat_active.yml +++ b/config/metrics/counts_all/20210216175917_projects_inheriting_hipchat_active.yml @@ -6,7 +6,8 @@ product_stage: create product_group: group::ecosystem product_category: integrations value_type: number -status: data_available +status: removed +milestone_removed: '13.11' time_frame: all data_source: database distribution: diff --git a/config/metrics/counts_all/20210216175919_groups_inheriting_hipchat_active.yml b/config/metrics/counts_all/20210216175919_groups_inheriting_hipchat_active.yml index 63c4ee9771d..4d4c265d377 100644 --- a/config/metrics/counts_all/20210216175919_groups_inheriting_hipchat_active.yml +++ b/config/metrics/counts_all/20210216175919_groups_inheriting_hipchat_active.yml @@ -6,7 +6,8 @@ product_stage: create product_group: group::ecosystem product_category: integrations value_type: number -status: data_available +status: removed +milestone_removed: '13.11' time_frame: all data_source: database distribution: diff --git a/doc/administration/terraform_state.md b/doc/administration/terraform_state.md index 0c01279b04c..898d98495d9 100644 --- a/doc/administration/terraform_state.md +++ b/doc/administration/terraform_state.md @@ -4,7 +4,7 @@ group: Configure info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments --- -# Terraform state administration (alpha) **(FREE)** +# Terraform state administration **(FREE)** > [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2673) in GitLab 12.10. diff --git a/doc/development/changelog.md b/doc/development/changelog.md index eef18d6850d..f77f918d2a1 100644 --- a/doc/development/changelog.md +++ b/doc/development/changelog.md @@ -54,7 +54,7 @@ the `author` field. GitLab team members **should not**. - Any docs-only changes **should not** have a changelog entry. - Any change behind a feature flag **disabled** by default **should not** have a changelog entry. - Any change behind a feature flag that is **enabled** by default **should** have a changelog entry. -- Any change that adds new Usage Data metrics and changes that needs to be documented in Product Intelligence [Metrics Dictionary](usage_ping/dictionary.md) **should** have a changelog entry. +- Any change that adds new Usage Data metrics, sets the status of existing ones to `removed`, and changes that need to be documented in Product Intelligence [Metrics Dictionary](usage_ping/dictionary.md) **should** have a changelog entry. - A change that adds snowplow events **should** have a changelog entry - - A change that [removes a feature flag, or removes a feature and its feature flag](feature_flags/index.md) **must** have a changelog entry. - A fix for a regression introduced and then fixed in the same release (i.e., diff --git a/doc/development/pipelines.md b/doc/development/pipelines.md index 8a93a46247e..9b636260c13 100644 --- a/doc/development/pipelines.md +++ b/doc/development/pipelines.md @@ -424,6 +424,59 @@ This experiment is only enabled when the CI/CD variable `RSPEC_FAIL_FAST_ENABLED The test files related to the Merge Request are determined using the [`test_file_finder`](https://gitlab.com/gitlab-org/ci-cd/test_file_finder) gem. We are using a custom mapping between source file to test files, maintained in the `tests.yml` file. +### RSpec minimal job experiment + +As part of the objective to improve overall pipeline duration, we are experimenting with a minimal set of RSpec tests. +The purpose of this experiment is to verify if we are able to run a minimal set of RSpec tests in a Merge Request pipeline, +without resulting in increased number of broken master. + +To identify the minimal set of tests needed, we use [Crystalball gem](https://github.com/toptal/crystalball) to create a test mapping. +The test mapping contains a map of each source files to a list of test files which is dependent of the source file. +This mapping is currently generated using a combination of test coverage tracing and a static mapping. +In the `detect-tests` job, we use this mapping to identify the minimal tests needed for the current Merge Request. + +In this experiment, each `rspec` job is accompanied with a `minimal` version. +For example, `rspec unit` job has a corresponding `rspec unit minimal` job. +During the experiment, each Merge Request pipeline will contain both versions of the job, running in parallel. + +To illustrate this: + +```mermaid +graph LR + A --"artifact: list of test files"--> C1 & D1 & E1 & F1 + + subgraph "prepare stage"; + A["detect-tests"]; + end + + subgraph "test stage"; + C["rspec migration"]; + C1["rspec migration minimal"]; + D["rspec unit"]; + D1["rspec unit minimal"]; + E["rspec integration"]; + E1["rspec integration minimal"]; + F["rspec system"]; + F1["rspec system minimal"]; + end +``` + +The result of both set of jobs in the pipeline is then compared to identify any false positive. +A list of such pipeline can be found in [Sisense](https://app.periscopedata.com/app/gitlab/496118/Engineering-Productivity-Sandbox?widget=10492739&udv=833427). + +A false positive is defined as a pipeline where the `minimal` jobs passed, but the non-`minimal` jobs failed. +This indicates that the changeset resulted in a test failure, which was not detected by the `minimal` jobs. +Consequently, this signifies a gap in the test mapping used, which would need to be rectified. + +#### Findings + +After a round of the experiment done in December 2020, +we discovered that it was challenging to achieve a mapping that gives high confidence at the moment, +because of 2 reasons: + +- Each identified gap in the test mapping is unique, each needing its own investigation and improvement to the creation of the test mapping. +- There is a large number of flaky tests which added a lot of noise in the data, slowing down the investigation process. + ### PostgreSQL versions testing Even though [Omnibus defaults to PG12 for new installs and upgrades](https://docs.gitlab.com/omnibus/package-information/postgresql_versions.html), diff --git a/doc/development/usage_ping/dictionary.md b/doc/development/usage_ping/dictionary.md index 1f1e5225804..7c5d1c79d64 100644 --- a/doc/development/usage_ping/dictionary.md +++ b/doc/development/usage_ping/dictionary.md @@ -1300,7 +1300,7 @@ Count of groups with active integrations for HipChat Group: `group::ecosystem` -Status: `data_available` +Status: `removed` Tiers: `free`, `premium`, `ultimate` @@ -1516,7 +1516,7 @@ Count of active groups inheriting integrations for HipChat Group: `group::ecosystem` -Status: `data_available` +Status: `removed` Tiers: `free`, `premium`, `ultimate` @@ -2356,7 +2356,7 @@ Count of active instance-level integrations for HipChat Group: `group::ecosystem` -Status: `data_available` +Status: `removed` Tiers: `free`, `premium`, `ultimate` @@ -3952,7 +3952,7 @@ Count of projects with active integrations for HipChat Group: `group::ecosystem` -Status: `data_available` +Status: `removed` Tiers: `free`, `premium`, `ultimate` @@ -4180,7 +4180,7 @@ Count of active projects inheriting integrations for HipChat Group: `group::ecosystem` -Status: `data_available` +Status: `removed` Tiers: `free`, `premium`, `ultimate` @@ -5632,7 +5632,7 @@ Count of active service templates for HipChat Group: `group::ecosystem` -Status: `data_available` +Status: `removed` Tiers: `free`, `premium`, `ultimate` diff --git a/doc/user/project/time_tracking.md b/doc/user/project/time_tracking.md index 78e7ded9784..402422cb3f3 100644 --- a/doc/user/project/time_tracking.md +++ b/doc/user/project/time_tracking.md @@ -98,4 +98,4 @@ With this option enabled, `75h` is displayed instead of `1w 4d 3h`. ## Other interesting links -- [Time Tracking landing page in the GitLab handbook](https://about.gitlab.com/solutions/time-tracking/) +- [Time Tracking solutions page](https://about.gitlab.com/solutions/time-tracking/) diff --git a/lib/gitlab/git_access.rb b/lib/gitlab/git_access.rb index 31e4755192e..0258e890e5b 100644 --- a/lib/gitlab/git_access.rb +++ b/lib/gitlab/git_access.rb @@ -22,7 +22,7 @@ module Gitlab auth_download: 'You are not allowed to download code.', deploy_key_upload: 'This deploy key does not have write access to this project.', no_repo: 'A repository for this project does not exist yet.', - project_not_found: 'The project you were looking for could not be found.', + project_not_found: "The project you were looking for could not be found or you don't have permission to view it.", command_not_allowed: "The command you're trying to execute is not allowed.", upload_pack_disabled_over_http: 'Pulling over HTTP is not allowed.', receive_pack_disabled_over_http: 'Pushing over HTTP is not allowed.', diff --git a/lib/gitlab/utils/usage_data.rb b/lib/gitlab/utils/usage_data.rb index efa2f7a943f..43a36e014c0 100644 --- a/lib/gitlab/utils/usage_data.rb +++ b/lib/gitlab/utils/usage_data.rb @@ -121,7 +121,7 @@ module Gitlab count_grouped = relation.group(column).select(Arel.star.count.as('count_grouped')) cte = Gitlab::SQL::CTE.new(:count_cte, count_grouped) - # For example, 9 segements gives 10 buckets + # For example, 9 segments gives 10 buckets bucket_segments = bucket_size - 1 width_bucket = Arel::Nodes::NamedFunction diff --git a/lib/sidebars/concerns/container_with_html_options.rb b/lib/sidebars/concerns/container_with_html_options.rb new file mode 100644 index 00000000000..c81690ea68d --- /dev/null +++ b/lib/sidebars/concerns/container_with_html_options.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +module Sidebars + module Concerns + module ContainerWithHtmlOptions + # The attributes returned from this method + # will be applied to helper methods like + # `link_to` or the div containing the container. + def container_html_options + { + aria: { label: title } + }.merge(extra_container_html_options) + end + + # Classes will override mostly this method + # and not `container_html_options`. + def extra_container_html_options + {} + end + + # Attributes to pass to the html_options attribute + # in the helper method that sets the active class + # on each element. + def nav_link_html_options + {} + end + + def title + raise NotImplementedError + end + + # The attributes returned from this method + # will be applied right next to the title, + # for example in the span that renders the title. + def title_html_options + {} + end + + def link + raise NotImplementedError + end + end + end +end diff --git a/lib/sidebars/concerns/has_active_routes.rb b/lib/sidebars/concerns/has_active_routes.rb new file mode 100644 index 00000000000..50c9f8c85a1 --- /dev/null +++ b/lib/sidebars/concerns/has_active_routes.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +module Sidebars + module Concerns + module HasActiveRoutes + # This method will indicate for which paths or + # controllers, the menu or menu item should + # be set as active. + # + # The returned values are passed to the `nav_link` helper method, + # so the params can be either `path`, `page`, `controller`. + # Param 'action' is not supported. + def active_routes + {} + end + end + end +end diff --git a/lib/sidebars/concerns/has_hint.rb b/lib/sidebars/concerns/has_hint.rb new file mode 100644 index 00000000000..dc4f765e974 --- /dev/null +++ b/lib/sidebars/concerns/has_hint.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +# This module has the necessary methods to store +# hints for menus. Hints are elements displayed +# when the user hover the menu item. +module Sidebars + module Concerns + module HasHint + def show_hint? + false + end + + def hint_html_options + {} + end + end + end +end diff --git a/lib/sidebars/concerns/has_icon.rb b/lib/sidebars/concerns/has_icon.rb new file mode 100644 index 00000000000..afff466239d --- /dev/null +++ b/lib/sidebars/concerns/has_icon.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +# This module has the necessary methods to show +# sprites or images next to the menu item. +module Sidebars + module Concerns + module HasIcon + def sprite_icon + nil + end + + def sprite_icon_html_options + {} + end + + def image_path + nil + end + + def image_html_options + {} + end + + def icon_or_image? + sprite_icon || image_path + end + end + end +end diff --git a/lib/sidebars/concerns/has_pill.rb b/lib/sidebars/concerns/has_pill.rb new file mode 100644 index 00000000000..5082ed477e6 --- /dev/null +++ b/lib/sidebars/concerns/has_pill.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +# This module introduces the logic to show the "pill" element +# next to the menu item, indicating the a count. +module Sidebars + module Concerns + module HasPill + def has_pill? + false + end + + # In this method we will need to provide the query + # to retrieve the elements count + def pill_count + raise NotImplementedError + end + + def pill_html_options + {} + end + end + end +end diff --git a/lib/sidebars/concerns/positionable_list.rb b/lib/sidebars/concerns/positionable_list.rb new file mode 100644 index 00000000000..84804d1249f --- /dev/null +++ b/lib/sidebars/concerns/positionable_list.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +# This module handles elements in a list. All elements +# must have a different class +module Sidebars + module Concerns + module PositionableList + def add_element(list, element) + list << element + end + + def insert_element_before(list, before_element, new_element) + index = index_of(list, before_element) + + if index + list.insert(index, new_element) + else + list.unshift(new_element) + end + end + + def insert_element_after(list, after_element, new_element) + index = index_of(list, after_element) + + if index + list.insert(index + 1, new_element) + else + add_element(list, new_element) + end + end + + private + + def index_of(list, element) + list.index { |e| e.is_a?(element) } + end + end + end +end diff --git a/lib/sidebars/concerns/renderable.rb b/lib/sidebars/concerns/renderable.rb new file mode 100644 index 00000000000..750efa2fcb8 --- /dev/null +++ b/lib/sidebars/concerns/renderable.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module Sidebars + module Concerns + module Renderable + # This method will control whether the menu or menu_item + # should be rendered. It will be overriden by specific + # classes. + def render? + true + end + end + end +end diff --git a/lib/sidebars/context.rb b/lib/sidebars/context.rb new file mode 100644 index 00000000000..d9ac2705aaf --- /dev/null +++ b/lib/sidebars/context.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +# This class stores all the information needed to display and +# render the sidebar and menus. +# It usually stores information regarding the context and calculated +# values where the logic is in helpers. +module Sidebars + class Context + attr_reader :current_user, :container + + def initialize(current_user:, container:, **args) + @current_user = current_user + @container = container + + args.each do |key, value| + singleton_class.public_send(:attr_reader, key) # rubocop:disable GitlabSecurity/PublicSend + instance_variable_set("@#{key}", value) + end + end + end +end diff --git a/lib/sidebars/menu.rb b/lib/sidebars/menu.rb new file mode 100644 index 00000000000..21acdc6267a --- /dev/null +++ b/lib/sidebars/menu.rb @@ -0,0 +1,82 @@ +# frozen_string_literal: true + +module Sidebars + class Menu + extend ::Gitlab::Utils::Override + include ::Gitlab::Routing + include GitlabRoutingHelper + include Gitlab::Allowable + include ::Sidebars::Concerns::HasPill + include ::Sidebars::Concerns::HasIcon + include ::Sidebars::Concerns::PositionableList + include ::Sidebars::Concerns::Renderable + include ::Sidebars::Concerns::ContainerWithHtmlOptions + include ::Sidebars::Concerns::HasActiveRoutes + + attr_reader :context + delegate :current_user, :container, to: :@context + + def initialize(context) + @context = context + @items = [] + + configure_menu_items + end + + def configure_menu_items + # No-op + end + + override :render? + def render? + @items.empty? || renderable_items.any? + end + + # Menus might have or not a link + override :link + def link + nil + end + + # This method normalizes the information retrieved from the submenus and this menu + # Value from menus is something like: [{ path: 'foo', path: 'bar', controller: :foo }] + # This method filters the information and returns: { path: ['foo', 'bar'], controller: :foo } + def all_active_routes + @all_active_routes ||= begin + ([active_routes] + renderable_items.map(&:active_routes)).flatten.each_with_object({}) do |pairs, hash| + pairs.each do |k, v| + hash[k] ||= [] + hash[k] += Array(v) + hash[k].uniq! + end + + hash + end + end + end + + def has_items? + @items.any? + end + + def add_item(item) + add_element(@items, item) + end + + def insert_item_before(before_item, new_item) + insert_element_before(@items, before_item, new_item) + end + + def insert_item_after(after_item, new_item) + insert_element_after(@items, after_item, new_item) + end + + def has_renderable_items? + renderable_items.any? + end + + def renderable_items + @renderable_items ||= @items.select(&:render?) + end + end +end diff --git a/lib/sidebars/menu_item.rb b/lib/sidebars/menu_item.rb new file mode 100644 index 00000000000..84c79fe0c39 --- /dev/null +++ b/lib/sidebars/menu_item.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module Sidebars + class MenuItem + extend ::Gitlab::Utils::Override + include ::Gitlab::Routing + include GitlabRoutingHelper + include Gitlab::Allowable + include ::Sidebars::Concerns::HasIcon + include ::Sidebars::Concerns::HasHint + include ::Sidebars::Concerns::Renderable + include ::Sidebars::Concerns::ContainerWithHtmlOptions + include ::Sidebars::Concerns::HasActiveRoutes + + attr_reader :context + + def initialize(context) + @context = context + end + end +end diff --git a/lib/sidebars/panel.rb b/lib/sidebars/panel.rb new file mode 100644 index 00000000000..6e9c20d0d92 --- /dev/null +++ b/lib/sidebars/panel.rb @@ -0,0 +1,75 @@ +# frozen_string_literal: true + +module Sidebars + class Panel + extend ::Gitlab::Utils::Override + include ::Sidebars::Concerns::PositionableList + + attr_reader :context, :scope_menu, :hidden_menu + + def initialize(context) + @context = context + @scope_menu = nil + @hidden_menu = nil + @menus = [] + + configure_menus + end + + def configure_menus + # No-op + end + + def add_menu(menu) + add_element(@menus, menu) + end + + def insert_menu_before(before_menu, new_menu) + insert_element_before(@menus, before_menu, new_menu) + end + + def insert_menu_after(after_menu, new_menu) + insert_element_after(@menus, after_menu, new_menu) + end + + def set_scope_menu(scope_menu) + @scope_menu = scope_menu + end + + def set_hidden_menu(hidden_menu) + @hidden_menu = hidden_menu + end + + def aria_label + raise NotImplementedError + end + + def has_renderable_menus? + renderable_menus.any? + end + + def renderable_menus + @renderable_menus ||= @menus.select(&:render?) + end + + def container + context.container + end + + # Auxiliar method that helps with the migration from + # regular views to the new logic + def render_raw_scope_menu_partial + # No-op + end + + # Auxiliar method that helps with the migration from + # regular views to the new logic. + # + # Any menu inside this partial will be added after + # all the menus added in the `configure_menus` + # method. + def render_raw_menus_partial + # No-op + end + end +end diff --git a/lib/sidebars/projects/context.rb b/lib/sidebars/projects/context.rb new file mode 100644 index 00000000000..4c82309035d --- /dev/null +++ b/lib/sidebars/projects/context.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module Sidebars + module Projects + class Context < ::Sidebars::Context + def initialize(current_user:, container:, **args) + super(current_user: current_user, container: container, project: container, **args) + end + end + end +end diff --git a/lib/sidebars/projects/menus/learn_gitlab/menu.rb b/lib/sidebars/projects/menus/learn_gitlab/menu.rb new file mode 100644 index 00000000000..4b572846d1a --- /dev/null +++ b/lib/sidebars/projects/menus/learn_gitlab/menu.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +module Sidebars + module Projects + module Menus + module LearnGitlab + class Menu < ::Sidebars::Menu + override :link + def link + project_learn_gitlab_path(context.project) + end + + override :active_routes + def active_routes + { controller: :learn_gitlab } + end + + override :title + def title + _('Learn GitLab') + end + + override :extra_container_html_options + def nav_link_html_options + { class: 'home' } + end + + override :sprite_icon + def sprite_icon + 'home' + end + + override :render? + def render? + context.learn_gitlab_experiment_enabled + end + end + end + end + end +end diff --git a/lib/sidebars/projects/menus/project_overview/menu.rb b/lib/sidebars/projects/menus/project_overview/menu.rb new file mode 100644 index 00000000000..e6aa8ed159f --- /dev/null +++ b/lib/sidebars/projects/menus/project_overview/menu.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +module Sidebars + module Projects + module Menus + module ProjectOverview + class Menu < ::Sidebars::Menu + override :configure_menu_items + def configure_menu_items + add_item(MenuItems::Details.new(context)) + add_item(MenuItems::Activity.new(context)) + add_item(MenuItems::Releases.new(context)) + end + + override :link + def link + project_path(context.project) + end + + override :extra_container_html_options + def extra_container_html_options + { + class: 'shortcuts-project rspec-project-link' + } + end + + override :extra_container_html_options + def nav_link_html_options + { class: 'home' } + end + + override :title + def title + _('Project overview') + end + + override :sprite_icon + def sprite_icon + 'home' + end + end + end + end + end +end diff --git a/lib/sidebars/projects/menus/project_overview/menu_items/activity.rb b/lib/sidebars/projects/menus/project_overview/menu_items/activity.rb new file mode 100644 index 00000000000..46d0f0bc43b --- /dev/null +++ b/lib/sidebars/projects/menus/project_overview/menu_items/activity.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +module Sidebars + module Projects + module Menus + module ProjectOverview + module MenuItems + class Activity < ::Sidebars::MenuItem + override :link + def link + activity_project_path(context.project) + end + + override :extra_container_html_options + def extra_container_html_options + { + class: 'shortcuts-project-activity' + } + end + + override :active_routes + def active_routes + { path: 'projects#activity' } + end + + override :title + def title + _('Activity') + end + end + end + end + end + end +end diff --git a/lib/sidebars/projects/menus/project_overview/menu_items/details.rb b/lib/sidebars/projects/menus/project_overview/menu_items/details.rb new file mode 100644 index 00000000000..c40c2ed8fa2 --- /dev/null +++ b/lib/sidebars/projects/menus/project_overview/menu_items/details.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +module Sidebars + module Projects + module Menus + module ProjectOverview + module MenuItems + class Details < ::Sidebars::MenuItem + override :link + def link + project_path(context.project) + end + + override :extra_container_html_options + def extra_container_html_options + { + aria: { label: _('Project details') }, + class: 'shortcuts-project' + } + end + + override :active_routes + def active_routes + { path: 'projects#show' } + end + + override :title + def title + _('Details') + end + end + end + end + end + end +end diff --git a/lib/sidebars/projects/menus/project_overview/menu_items/releases.rb b/lib/sidebars/projects/menus/project_overview/menu_items/releases.rb new file mode 100644 index 00000000000..5e8348f4398 --- /dev/null +++ b/lib/sidebars/projects/menus/project_overview/menu_items/releases.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +module Sidebars + module Projects + module Menus + module ProjectOverview + module MenuItems + class Releases < ::Sidebars::MenuItem + override :link + def link + project_releases_path(context.project) + end + + override :extra_container_html_options + def extra_container_html_options + { + class: 'shortcuts-project-releases' + } + end + + override :render? + def render? + can?(context.current_user, :read_release, context.project) && !context.project.empty_repo? + end + + override :active_routes + def active_routes + { controller: :releases } + end + + override :title + def title + _('Releases') + end + end + end + end + end + end +end diff --git a/lib/sidebars/projects/menus/repository/menu.rb b/lib/sidebars/projects/menus/repository/menu.rb new file mode 100644 index 00000000000..f49a0479521 --- /dev/null +++ b/lib/sidebars/projects/menus/repository/menu.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +module Sidebars + module Projects + module Menus + module Repository + class Menu < ::Sidebars::Menu + override :configure_menu_items + def configure_menu_items + add_item(MenuItems::Files.new(context)) + add_item(MenuItems::Commits.new(context)) + add_item(MenuItems::Branches.new(context)) + add_item(MenuItems::Tags.new(context)) + add_item(MenuItems::Contributors.new(context)) + add_item(MenuItems::Graphs.new(context)) + add_item(MenuItems::Compare.new(context)) + end + + override :link + def link + project_tree_path(context.project) + end + + override :extra_container_html_options + def extra_container_html_options + { + class: 'shortcuts-tree' + } + end + + override :title + def title + _('Repository') + end + + override :title_html_options + def title_html_options + { + id: 'js-onboarding-repo-link' + } + end + + override :sprite_icon + def sprite_icon + 'doc-text' + end + + override :render? + def render? + can?(context.current_user, :download_code, context.project) && + !context.project.empty_repo? + end + end + end + end + end +end + +Sidebars::Projects::Menus::Repository::Menu.prepend_if_ee('EE::Sidebars::Projects::Menus::Repository::Menu') diff --git a/lib/sidebars/projects/menus/repository/menu_items/branches.rb b/lib/sidebars/projects/menus/repository/menu_items/branches.rb new file mode 100644 index 00000000000..4a62803dd2b --- /dev/null +++ b/lib/sidebars/projects/menus/repository/menu_items/branches.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +module Sidebars + module Projects + module Menus + module Repository + module MenuItems + class Branches < ::Sidebars::MenuItem + override :link + def link + project_branches_path(context.project) + end + + override :extra_container_html_options + def extra_container_html_options + { + id: 'js-onboarding-branches-link' + } + end + + override :active_routes + def active_routes + { controller: :branches } + end + + override :title + def title + _('Branches') + end + end + end + end + end + end +end diff --git a/lib/sidebars/projects/menus/repository/menu_items/commits.rb b/lib/sidebars/projects/menus/repository/menu_items/commits.rb new file mode 100644 index 00000000000..647cf89133e --- /dev/null +++ b/lib/sidebars/projects/menus/repository/menu_items/commits.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +module Sidebars + module Projects + module Menus + module Repository + module MenuItems + class Commits < ::Sidebars::MenuItem + override :link + def link + project_commits_path(context.project, context.current_ref) + end + + override :extra_container_html_options + def extra_container_html_options + { + id: 'js-onboarding-commits-link' + } + end + + override :active_routes + def active_routes + { controller: %w(commit commits) } + end + + override :title + def title + _('Commits') + end + end + end + end + end + end +end diff --git a/lib/sidebars/projects/menus/repository/menu_items/compare.rb b/lib/sidebars/projects/menus/repository/menu_items/compare.rb new file mode 100644 index 00000000000..4812636b63f --- /dev/null +++ b/lib/sidebars/projects/menus/repository/menu_items/compare.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +module Sidebars + module Projects + module Menus + module Repository + module MenuItems + class Compare < ::Sidebars::MenuItem + override :link + def link + project_compare_index_path(context.project, from: context.project.repository.root_ref, to: context.current_ref) + end + + override :active_routes + def active_routes + { controller: :compare } + end + + override :title + def title + _('Compare') + end + end + end + end + end + end +end diff --git a/lib/sidebars/projects/menus/repository/menu_items/contributors.rb b/lib/sidebars/projects/menus/repository/menu_items/contributors.rb new file mode 100644 index 00000000000..d60fd05bb64 --- /dev/null +++ b/lib/sidebars/projects/menus/repository/menu_items/contributors.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +module Sidebars + module Projects + module Menus + module Repository + module MenuItems + class Contributors < ::Sidebars::MenuItem + override :link + def link + project_graph_path(context.project, context.current_ref) + end + + override :active_routes + def active_routes + { path: 'graphs#show' } + end + + override :title + def title + _('Contributors') + end + end + end + end + end + end +end diff --git a/lib/sidebars/projects/menus/repository/menu_items/files.rb b/lib/sidebars/projects/menus/repository/menu_items/files.rb new file mode 100644 index 00000000000..4989efe9fa5 --- /dev/null +++ b/lib/sidebars/projects/menus/repository/menu_items/files.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +module Sidebars + module Projects + module Menus + module Repository + module MenuItems + class Files < ::Sidebars::MenuItem + override :link + def link + project_tree_path(context.project, context.current_ref) + end + + override :active_routes + def active_routes + { controller: %w[tree blob blame edit_tree new_tree find_file] } + end + + override :title + def title + _('Files') + end + end + end + end + end + end +end diff --git a/lib/sidebars/projects/menus/repository/menu_items/graphs.rb b/lib/sidebars/projects/menus/repository/menu_items/graphs.rb new file mode 100644 index 00000000000..a57021be4d0 --- /dev/null +++ b/lib/sidebars/projects/menus/repository/menu_items/graphs.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +module Sidebars + module Projects + module Menus + module Repository + module MenuItems + class Graphs < ::Sidebars::MenuItem + override :link + def link + project_network_path(context.project, context.current_ref) + end + + override :active_routes + def active_routes + { controller: :network } + end + + override :title + def title + _('Graph') + end + end + end + end + end + end +end diff --git a/lib/sidebars/projects/menus/repository/menu_items/tags.rb b/lib/sidebars/projects/menus/repository/menu_items/tags.rb new file mode 100644 index 00000000000..d84bc89b93c --- /dev/null +++ b/lib/sidebars/projects/menus/repository/menu_items/tags.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +module Sidebars + module Projects + module Menus + module Repository + module MenuItems + class Tags < ::Sidebars::MenuItem + override :link + def link + project_tags_path(context.project) + end + + override :active_routes + def active_routes + { controller: :tags } + end + + override :title + def title + _('Tags') + end + end + end + end + end + end +end diff --git a/lib/sidebars/projects/menus/scope/menu.rb b/lib/sidebars/projects/menus/scope/menu.rb new file mode 100644 index 00000000000..3b699083f75 --- /dev/null +++ b/lib/sidebars/projects/menus/scope/menu.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module Sidebars + module Projects + module Menus + module Scope + class Menu < ::Sidebars::Menu + override :link + def link + project_path(context.project) + end + + override :title + def title + context.project.name + end + end + end + end + end +end diff --git a/lib/sidebars/projects/panel.rb b/lib/sidebars/projects/panel.rb new file mode 100644 index 00000000000..ec4fac53a40 --- /dev/null +++ b/lib/sidebars/projects/panel.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +module Sidebars + module Projects + class Panel < ::Sidebars::Panel + override :configure_menus + def configure_menus + set_scope_menu(Sidebars::Projects::Menus::Scope::Menu.new(context)) + + add_menu(Sidebars::Projects::Menus::ProjectOverview::Menu.new(context)) + add_menu(Sidebars::Projects::Menus::LearnGitlab::Menu.new(context)) + add_menu(Sidebars::Projects::Menus::Repository::Menu.new(context)) + end + + override :render_raw_menus_partial + def render_raw_menus_partial + 'layouts/nav/sidebar/project_menus' + end + + override :aria_label + def aria_label + _('Project navigation') + end + end + end +end diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 9e9a86c8d13..e17cd86ab8b 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -11693,6 +11693,9 @@ msgstr "" msgid "Edit iteration" msgstr "" +msgid "Edit iteration cadence" +msgstr "" + msgid "Edit public deploy key" msgstr "" @@ -17941,6 +17944,9 @@ msgstr "" msgid "Iteration" msgstr "" +msgid "Iteration cadences" +msgstr "" + msgid "Iteration changed to" msgstr "" @@ -21346,6 +21352,9 @@ msgstr "" msgid "New iteration" msgstr "" +msgid "New iteration cadence" +msgstr "" + msgid "New iteration created" msgstr "" @@ -30540,13 +30549,13 @@ msgstr "" msgid "SuperSonics|Subscription details" msgstr "" -msgid "SuperSonics|Sync Subscription details" +msgid "SuperSonics|Sync subscription details" msgstr "" msgid "SuperSonics|The subscription details synced successfully." msgstr "" -msgid "SuperSonics|There is a connectivity issue. You can no longer sync your subscription details with GitLab. Get help for the most common connectivity issues by %{connectivityHelpLinkStart}troubleshooting the activation code%{connectivityHelpLinkEnd}." +msgid "SuperSonics|There is a connectivity issue." msgstr "" msgid "SuperSonics|Type" @@ -30555,6 +30564,9 @@ msgstr "" msgid "SuperSonics|Valid From" msgstr "" +msgid "SuperSonics|You can no longer sync your subscription details with GitLab. Get help for the most common connectivity issues by %{connectivityHelpLinkStart}troubleshooting the activation code%{connectivityHelpLinkEnd}." +msgstr "" + msgid "SuperSonics|You do not have an active subscription" msgstr "" diff --git a/spec/finders/users_with_pending_todos_finder_spec.rb b/spec/finders/users_with_pending_todos_finder_spec.rb deleted file mode 100644 index 565b65fbefe..00000000000 --- a/spec/finders/users_with_pending_todos_finder_spec.rb +++ /dev/null @@ -1,19 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe UsersWithPendingTodosFinder do - describe '#execute' do - it 'returns the users for all pending todos of a target' do - issue = create(:issue) - note = create(:note) - todo = create(:todo, :pending, target: issue) - - create(:todo, :pending, target: note) - - users = described_class.new(issue).execute - - expect(users).to eq([todo.user]) - end - end -end diff --git a/spec/frontend/fixtures/raw.rb b/spec/frontend/fixtures/raw.rb index cf51f2389bc..44927bd29d8 100644 --- a/spec/frontend/fixtures/raw.rb +++ b/spec/frontend/fixtures/raw.rb @@ -25,6 +25,10 @@ RSpec.describe 'Raw files', '(JavaScript fixtures)' do @blob = project.repository.blob_at('6d85bb69', 'files/ipython/basic.ipynb') end + it 'blob/notebook/markdown-table.json' do + @blob = project.repository.blob_at('f6b7a707', 'files/ipython/markdown-table.ipynb') + end + it 'blob/notebook/worksheets.json' do @blob = project.repository.blob_at('6d85bb69', 'files/ipython/worksheets.ipynb') end diff --git a/spec/frontend/monitoring/components/dashboards_dropdown_spec.js b/spec/frontend/monitoring/components/dashboards_dropdown_spec.js index c9241834789..589354e7849 100644 --- a/spec/frontend/monitoring/components/dashboards_dropdown_spec.js +++ b/spec/frontend/monitoring/components/dashboards_dropdown_spec.js @@ -6,7 +6,7 @@ import DashboardsDropdown from '~/monitoring/components/dashboards_dropdown.vue' import { dashboardGitResponse } from '../mock_data'; -const defaultBranch = 'master'; +const defaultBranch = 'main'; const starredDashboards = dashboardGitResponse.filter(({ starred }) => starred); const notStarredDashboards = dashboardGitResponse.filter(({ starred }) => !starred); diff --git a/spec/frontend/monitoring/components/duplicate_dashboard_form_spec.js b/spec/frontend/monitoring/components/duplicate_dashboard_form_spec.js index 51b4106d4b1..0dd3afd7c83 100644 --- a/spec/frontend/monitoring/components/duplicate_dashboard_form_spec.js +++ b/spec/frontend/monitoring/components/duplicate_dashboard_form_spec.js @@ -16,7 +16,7 @@ const createMountedWrapper = (props = {}) => { }; describe('DuplicateDashboardForm', () => { - const defaultBranch = 'master'; + const defaultBranch = 'main'; const findByRef = (ref) => wrapper.find({ ref }); const setValue = (ref, val) => { diff --git a/spec/frontend/monitoring/components/duplicate_dashboard_modal_spec.js b/spec/frontend/monitoring/components/duplicate_dashboard_modal_spec.js index 1bc89e509b5..7e7a7a66d77 100644 --- a/spec/frontend/monitoring/components/duplicate_dashboard_modal_spec.js +++ b/spec/frontend/monitoring/components/duplicate_dashboard_modal_spec.js @@ -37,7 +37,7 @@ describe('duplicate dashboard modal', () => { return shallowMount(DuplicateDashboardModal, { propsData: { - defaultBranch: 'master', + defaultBranch: 'main', modalId: 'id', }, store, diff --git a/spec/frontend/monitoring/mock_data.js b/spec/frontend/monitoring/mock_data.js index 29a7c86491d..00be5868ba3 100644 --- a/spec/frontend/monitoring/mock_data.js +++ b/spec/frontend/monitoring/mock_data.js @@ -15,7 +15,7 @@ const customDashboardsData = new Array(30).fill(null).map((_, idx) => ({ can_edit: true, system_dashboard: false, out_of_the_box_dashboard: false, - project_blob_path: `${mockProjectDir}/blob/master/dashboards/.gitlab/dashboards/dashboard_${idx}.yml`, + project_blob_path: `${mockProjectDir}/blob/main/dashboards/.gitlab/dashboards/dashboard_${idx}.yml`, path: `.gitlab/dashboards/dashboard_${idx}.yml`, starred: false, })); @@ -32,7 +32,7 @@ export const anomalyDeploymentData = [ iid: 3, sha: 'f5bcd1d9dac6fa4137e2510b9ccd134ef2e84187', ref: { - name: 'master', + name: 'main', }, created_at: '2019-08-19T22:00:00.000Z', deployed_at: '2019-08-19T22:01:00.000Z', @@ -44,7 +44,7 @@ export const anomalyDeploymentData = [ iid: 2, sha: 'f5bcd1d9dac6fa4137e2510b9ccd134ef2e84187', ref: { - name: 'master', + name: 'main', }, created_at: '2019-08-19T23:00:00.000Z', deployed_at: '2019-08-19T23:00:00.000Z', @@ -61,7 +61,7 @@ export const deploymentData = [ commitUrl: 'http://test.host/frontend-fixtures/environments-project/-/commit/f5bcd1d9dac6fa4137e2510b9ccd134ef2e84187', ref: { - name: 'master', + name: 'main', }, created_at: '2019-07-16T10:14:25.589Z', tag: false, @@ -75,7 +75,7 @@ export const deploymentData = [ commitUrl: 'http://test.host/frontend-fixtures/environments-project/-/commit/f5bcd1d9dac6fa4137e2510b9ccd134ef2e84187', ref: { - name: 'master', + name: 'main', }, created_at: '2019-07-16T11:14:25.589Z', tag: false, @@ -187,7 +187,7 @@ export const dashboardGitResponse = [ can_edit: true, system_dashboard: false, out_of_the_box_dashboard: false, - project_blob_path: `${mockProjectDir}/-/blob/master/.gitlab/dashboards/dashboard.yml`, + project_blob_path: `${mockProjectDir}/-/blob/main/.gitlab/dashboards/dashboard.yml`, path: '.gitlab/dashboards/dashboard.yml', starred: true, user_starred_path: `${mockProjectDir}/metrics_user_starred_dashboards?dashboard_path=.gitlab/dashboards/dashboard.yml`, @@ -224,7 +224,7 @@ export const selfMonitoringDashboardGitResponse = [ can_edit: true, system_dashboard: false, out_of_the_box_dashboard: false, - project_blob_path: `${mockProjectDir}/-/blob/master/.gitlab/dashboards/dashboard.yml`, + project_blob_path: `${mockProjectDir}/-/blob/main/.gitlab/dashboards/dashboard.yml`, path: '.gitlab/dashboards/dashboard.yml', starred: true, user_starred_path: `${mockProjectDir}/metrics_user_starred_dashboards?dashboard_path=.gitlab/dashboards/dashboard.yml`, @@ -572,7 +572,7 @@ export const storeVariables = [ ]; export const dashboardHeaderProps = { - defaultBranch: 'master', + defaultBranch: 'main', isRearrangingPanels: false, selectedTimeRange: { start: '2020-01-01T00:00:00.000Z', @@ -581,7 +581,7 @@ export const dashboardHeaderProps = { }; export const dashboardActionsMenuProps = { - defaultBranch: 'master', + defaultBranch: 'main', addingMetricsAvailable: true, customMetricsPath: 'https://path/to/customMetrics', validateQueryPath: 'https://path/to/validateQuery', diff --git a/spec/frontend/notebook/cells/markdown_spec.js b/spec/frontend/notebook/cells/markdown_spec.js index 219d74595bd..d250ffed1a9 100644 --- a/spec/frontend/notebook/cells/markdown_spec.js +++ b/spec/frontend/notebook/cells/markdown_spec.js @@ -27,7 +27,7 @@ describe('Markdown component', () => { return vm.$nextTick(); }); - it('does not render promot', () => { + it('does not render prompt', () => { expect(vm.$el.querySelector('.prompt span')).toBeNull(); }); @@ -50,6 +50,41 @@ describe('Markdown component', () => { expect(vm.$el.querySelector('a').getAttribute('href')).toBeNull(); }); + describe('tables', () => { + beforeEach(() => { + json = getJSONFixture('blob/notebook/markdown-table.json'); + }); + + it('renders images and text', () => { + vm = new Component({ + propsData: { + cell: json.cells[0], + }, + }).$mount(); + + return vm.$nextTick().then(() => { + const images = vm.$el.querySelectorAll('img'); + expect(images.length).toBe(5); + + const columns = vm.$el.querySelectorAll('td'); + expect(columns.length).toBe(6); + + expect(columns[0].textContent).toEqual('Hello '); + expect(columns[1].textContent).toEqual('Test '); + expect(columns[2].textContent).toEqual('World '); + expect(columns[3].textContent).toEqual('Fake '); + expect(columns[4].textContent).toEqual('External image: '); + expect(columns[5].textContent).toEqual('Empty'); + + expect(columns[0].innerHTML).toContain(' { beforeEach(() => { json = getJSONFixture('blob/notebook/math.json'); diff --git a/spec/frontend/repository/components/table/index_spec.js b/spec/frontend/repository/components/table/index_spec.js index af263f43d7d..e9e51abaf0f 100644 --- a/spec/frontend/repository/components/table/index_spec.js +++ b/spec/frontend/repository/components/table/index_spec.js @@ -55,8 +55,8 @@ describe('Repository table component', () => { it.each` path | ref - ${'/'} | ${'master'} - ${'app/assets'} | ${'master'} + ${'/'} | ${'main'} + ${'app/assets'} | ${'main'} ${'/'} | ${'test'} `('renders table caption for $ref in $path', ({ path, ref }) => { factory({ path }); diff --git a/spec/frontend/repository/components/table/parent_row_spec.js b/spec/frontend/repository/components/table/parent_row_spec.js index cf1ed272634..9daae8c36ef 100644 --- a/spec/frontend/repository/components/table/parent_row_spec.js +++ b/spec/frontend/repository/components/table/parent_row_spec.js @@ -12,7 +12,7 @@ function factory(path, loadingPath) { vm = shallowMount(ParentRow, { propsData: { - commitRef: 'master', + commitRef: 'main', path, loadingPath, }, @@ -32,10 +32,10 @@ describe('Repository parent row component', () => { it.each` path | to - ${'app'} | ${'/-/tree/master/'} - ${'app/assets'} | ${'/-/tree/master/app'} - ${'app/assets#/test'} | ${'/-/tree/master/app/assets%23'} - ${'app/assets#/test/world'} | ${'/-/tree/master/app/assets%23/test'} + ${'app'} | ${'/-/tree/main/'} + ${'app/assets'} | ${'/-/tree/main/app'} + ${'app/assets#/test'} | ${'/-/tree/main/app/assets%23'} + ${'app/assets#/test/world'} | ${'/-/tree/main/app/assets%23/test'} `('renders link in $path to $to', ({ path, to }) => { factory(path); @@ -50,7 +50,7 @@ describe('Repository parent row component', () => { vm.find('td').trigger('click'); expect($router.push).toHaveBeenCalledWith({ - path: '/-/tree/master/app', + path: '/-/tree/main/app', }); }); @@ -62,7 +62,7 @@ describe('Repository parent row component', () => { vm.find('a').trigger('click'); expect($router.push).not.toHaveBeenCalledWith({ - path: '/-/tree/master/app', + path: '/-/tree/main/app', }); }); diff --git a/spec/frontend/repository/components/table/row_spec.js b/spec/frontend/repository/components/table/row_spec.js index 3ebffbedcdb..6ba6f993db1 100644 --- a/spec/frontend/repository/components/table/row_spec.js +++ b/spec/frontend/repository/components/table/row_spec.js @@ -30,7 +30,7 @@ function factory(propsData = {}) { }, }); - vm.setData({ escapedRef: 'master' }); + vm.setData({ escapedRef: 'main' }); } describe('Repository table row component', () => { @@ -115,7 +115,7 @@ describe('Repository table row component', () => { return vm.vm.$nextTick().then(() => { expect(vm.find({ ref: 'link' }).props('to')).toEqual({ - path: `/-/tree/master/${encodeURIComponent(path)}`, + path: `/-/tree/main/${encodeURIComponent(path)}`, }); }); }); @@ -130,7 +130,7 @@ describe('Repository table row component', () => { }); return vm.vm.$nextTick().then(() => { - expect(vm.find('.tree-item-link').props('to')).toEqual({ path: '/-/tree/master/test%23' }); + expect(vm.find('.tree-item-link').props('to')).toEqual({ path: '/-/tree/main/test%23' }); }); }); diff --git a/spec/frontend/repository/components/upload_blob_modal_spec.js b/spec/frontend/repository/components/upload_blob_modal_spec.js index 935ed08f67a..ec85d5666fb 100644 --- a/spec/frontend/repository/components/upload_blob_modal_spec.js +++ b/spec/frontend/repository/components/upload_blob_modal_spec.js @@ -20,8 +20,8 @@ jest.mock('~/lib/utils/url_utility', () => ({ const initialProps = { modalId: 'upload-blob', commitMessage: 'Upload New File', - targetBranch: 'master', - originalBranch: 'master', + targetBranch: 'main', + originalBranch: 'main', canPushCode: true, path: 'new_upload', }; @@ -111,7 +111,7 @@ describe('UploadBlobModal', () => { if (canPushCode) { describe('when changing the branch name', () => { it('displays the MR toggle', async () => { - wrapper.setData({ target: 'Not master' }); + wrapper.setData({ target: 'Not main' }); await wrapper.vm.$nextTick(); diff --git a/spec/frontend/repository/log_tree_spec.js b/spec/frontend/repository/log_tree_spec.js index ddc95feccd6..a842053caad 100644 --- a/spec/frontend/repository/log_tree_spec.js +++ b/spec/frontend/repository/log_tree_spec.js @@ -53,7 +53,7 @@ describe('fetchLogsTree', () => { client = { readQuery: () => ({ projectPath: 'gitlab-org/gitlab-foss', - escapedRef: 'master', + escapedRef: 'main', commits: [], }), writeQuery: jest.fn(), @@ -71,7 +71,7 @@ describe('fetchLogsTree', () => { it('calls axios get', () => fetchLogsTree(client, '', '0', resolver).then(() => { - expect(axios.get).toHaveBeenCalledWith('/gitlab-org/gitlab-foss/-/refs/master/logs_tree/', { + expect(axios.get).toHaveBeenCalledWith('/gitlab-org/gitlab-foss/-/refs/main/logs_tree/', { params: { format: 'json', offset: '0' }, }); })); @@ -114,7 +114,7 @@ describe('fetchLogsTree', () => { query: expect.anything(), data: { projectPath: 'gitlab-org/gitlab-foss', - escapedRef: 'master', + escapedRef: 'main', commits: [ expect.objectContaining({ __typename: 'LogTreeCommit', diff --git a/spec/frontend/repository/router_spec.js b/spec/frontend/repository/router_spec.js index 3354b2315fc..bb82fa706fd 100644 --- a/spec/frontend/repository/router_spec.js +++ b/spec/frontend/repository/router_spec.js @@ -5,14 +5,14 @@ import createRouter from '~/repository/router'; describe('Repository router spec', () => { it.each` - path | branch | component | componentName - ${'/'} | ${'master'} | ${IndexPage} | ${'IndexPage'} - ${'/tree/master'} | ${'master'} | ${TreePage} | ${'TreePage'} - ${'/tree/feat(test)'} | ${'feat(test)'} | ${TreePage} | ${'TreePage'} - ${'/-/tree/master'} | ${'master'} | ${TreePage} | ${'TreePage'} - ${'/-/tree/master/app/assets'} | ${'master'} | ${TreePage} | ${'TreePage'} - ${'/-/tree/123/app/assets'} | ${'master'} | ${null} | ${'null'} - ${'/-/blob/master/file.md'} | ${'master'} | ${BlobPage} | ${'BlobPage'} + path | branch | component | componentName + ${'/'} | ${'main'} | ${IndexPage} | ${'IndexPage'} + ${'/tree/main'} | ${'main'} | ${TreePage} | ${'TreePage'} + ${'/tree/feat(test)'} | ${'feat(test)'} | ${TreePage} | ${'TreePage'} + ${'/-/tree/main'} | ${'main'} | ${TreePage} | ${'TreePage'} + ${'/-/tree/main/app/assets'} | ${'main'} | ${TreePage} | ${'TreePage'} + ${'/-/tree/123/app/assets'} | ${'main'} | ${null} | ${'null'} + ${'/-/blob/main/file.md'} | ${'main'} | ${BlobPage} | ${'BlobPage'} `('sets component as $componentName for path "$path"', ({ path, component, branch }) => { const router = createRouter('', branch); diff --git a/spec/frontend/repository/utils/title_spec.js b/spec/frontend/repository/utils/title_spec.js index a1213c13be8..d5206bdea92 100644 --- a/spec/frontend/repository/utils/title_spec.js +++ b/spec/frontend/repository/utils/title_spec.js @@ -8,9 +8,9 @@ describe('setTitle', () => { ${'app/assets'} | ${'app/assets'} ${'app/assets/javascripts'} | ${'app/assets/javascripts'} `('sets document title as $title for $path', ({ path, title }) => { - setTitle(path, 'master', 'GitLab Org / GitLab'); + setTitle(path, 'main', 'GitLab Org / GitLab'); - expect(document.title).toEqual(`${title} · master · GitLab Org / GitLab · GitLab`); + expect(document.title).toEqual(`${title} · main · GitLab Org / GitLab · GitLab`); }); }); diff --git a/spec/graphql/mutations/merge_requests/set_locked_spec.rb b/spec/graphql/mutations/merge_requests/set_locked_spec.rb index 03c709e9bb3..68bb7aa0aa4 100644 --- a/spec/graphql/mutations/merge_requests/set_locked_spec.rb +++ b/spec/graphql/mutations/merge_requests/set_locked_spec.rb @@ -41,7 +41,7 @@ RSpec.describe Mutations::MergeRequests::SetLocked do let(:locked) { false } it 'unlocks the discussion' do - merge_request.update(discussion_locked: true) + merge_request.update!(discussion_locked: true) expect(mutated_merge_request).not_to be_discussion_locked end diff --git a/spec/graphql/mutations/merge_requests/set_wip_spec.rb b/spec/graphql/mutations/merge_requests/set_wip_spec.rb index 69f6a4328b8..fae9c4f7fe0 100644 --- a/spec/graphql/mutations/merge_requests/set_wip_spec.rb +++ b/spec/graphql/mutations/merge_requests/set_wip_spec.rb @@ -41,7 +41,7 @@ RSpec.describe Mutations::MergeRequests::SetWip do let(:wip) { false } it 'removes `wip` from the title' do - merge_request.update(title: "WIP: working on it") + merge_request.update!(title: "WIP: working on it") expect(mutated_merge_request).not_to be_work_in_progress end diff --git a/spec/graphql/resolvers/boards_resolver_spec.rb b/spec/graphql/resolvers/boards_resolver_spec.rb index cb3bcb002ec..221e905f441 100644 --- a/spec/graphql/resolvers/boards_resolver_spec.rb +++ b/spec/graphql/resolvers/boards_resolver_spec.rb @@ -54,7 +54,7 @@ RSpec.describe Resolvers::BoardsResolver do end it 'returns nil if board not found' do - outside_parent = create(board_parent.class.underscore.to_sym) + outside_parent = create(board_parent.class.underscore.to_sym) # rubocop:disable Rails/SaveBang outside_board = create(:board, name: 'outside board', resource_parent: outside_parent) expect(resolve_boards(args: { id: global_id_of(outside_board) })).to eq Board.none diff --git a/spec/lib/gitlab/git_access_spec.rb b/spec/lib/gitlab/git_access_spec.rb index 9a1ecfe6459..2116c9e0128 100644 --- a/spec/lib/gitlab/git_access_spec.rb +++ b/spec/lib/gitlab/git_access_spec.rb @@ -554,19 +554,19 @@ RSpec.describe Gitlab::GitAccess do context 'when the repository is public' do let(:options) { %i[repository_enabled] } - it { expect { pull_access_check }.to raise_error('The project you were looking for could not be found.') } + it { expect { pull_access_check }.to raise_error("The project you were looking for could not be found or you don't have permission to view it.") } end context 'when the repository is private' do let(:options) { %i[repository_private] } - it { expect { pull_access_check }.to raise_error('The project you were looking for could not be found.') } + it { expect { pull_access_check }.to raise_error("The project you were looking for could not be found or you don't have permission to view it.") } end context 'when the repository is disabled' do let(:options) { %i[repository_disabled] } - it { expect { pull_access_check }.to raise_error('The project you were looking for could not be found.') } + it { expect { pull_access_check }.to raise_error("The project you were looking for could not be found or you don't have permission to view it.") } end end end @@ -596,13 +596,13 @@ RSpec.describe Gitlab::GitAccess do context 'when the repository is private' do let(:options) { %i[repository_private] } - it { expect { pull_access_check }.to raise_error('The project you were looking for could not be found.') } + it { expect { pull_access_check }.to raise_error("The project you were looking for could not be found or you don't have permission to view it.") } end context 'when the repository is disabled' do let(:options) { %i[repository_disabled] } - it { expect { pull_access_check }.to raise_error('The project you were looking for could not be found.') } + it { expect { pull_access_check }.to raise_error("The project you were looking for could not be found or you don't have permission to view it.") } end end end diff --git a/spec/lib/sidebars/concerns/container_with_html_options_spec.rb b/spec/lib/sidebars/concerns/container_with_html_options_spec.rb new file mode 100644 index 00000000000..141c9585eed --- /dev/null +++ b/spec/lib/sidebars/concerns/container_with_html_options_spec.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Sidebars::Concerns::ContainerWithHtmlOptions do + subject do + Class.new do + include Sidebars::Concerns::ContainerWithHtmlOptions + + def title + 'Foo' + end + end.new + end + + describe '#container_html_options' do + it 'includes by default aria-label attribute' do + expect(subject.container_html_options).to eq(aria: { label: 'Foo' }) + end + end +end diff --git a/spec/lib/sidebars/concerns/positionable_list_spec.rb b/spec/lib/sidebars/concerns/positionable_list_spec.rb new file mode 100644 index 00000000000..ac933faba13 --- /dev/null +++ b/spec/lib/sidebars/concerns/positionable_list_spec.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Sidebars::Concerns::PositionableList do + subject do + Class.new do + include Sidebars::Concerns::PositionableList + end.new + end + + describe '#add_element' do + it 'adds the element to the last position of the list' do + list = [1, 2] + + subject.add_element(list, 3) + + expect(list).to eq([1, 2, 3]) + end + end + + describe '#insert_element_before' do + let(:user) { build(:user) } + let(:list) { [1, user] } + + it 'adds element before the specific element class' do + subject.insert_element_before(list, User, 2) + + expect(list).to eq [1, 2, user] + end + + context 'when reference element does not exist' do + it 'adds the element to the top of the list' do + subject.insert_element_before(list, Project, 2) + + expect(list).to eq [2, 1, user] + end + end + end + + describe '#insert_element_after' do + let(:user) { build(:user) } + let(:list) { [1, user] } + + it 'adds element after the specific element class' do + subject.insert_element_after(list, Integer, 2) + + expect(list).to eq [1, 2, user] + end + + context 'when reference element does not exist' do + it 'adds the element to the end of the list' do + subject.insert_element_after(list, Project, 2) + + expect(list).to eq [1, user, 2] + end + end + end +end diff --git a/spec/lib/sidebars/menu_spec.rb b/spec/lib/sidebars/menu_spec.rb new file mode 100644 index 00000000000..320f5f1ad1e --- /dev/null +++ b/spec/lib/sidebars/menu_spec.rb @@ -0,0 +1,67 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Sidebars::Menu do + let(:menu) { described_class.new(context) } + let(:context) { Sidebars::Context.new(current_user: nil, container: nil) } + + describe '#all_active_routes' do + it 'gathers all active routes of items and the current menu' do + menu_item1 = Sidebars::MenuItem.new(context) + menu_item2 = Sidebars::MenuItem.new(context) + menu_item3 = Sidebars::MenuItem.new(context) + menu.add_item(menu_item1) + menu.add_item(menu_item2) + menu.add_item(menu_item3) + + allow(menu).to receive(:active_routes).and_return({ path: 'foo' }) + allow(menu_item1).to receive(:active_routes).and_return({ path: %w(bar test) }) + allow(menu_item2).to receive(:active_routes).and_return({ controller: 'fooc' }) + allow(menu_item3).to receive(:active_routes).and_return({ controller: 'barc' }) + + expect(menu.all_active_routes).to eq({ path: %w(foo bar test), controller: %w(fooc barc) }) + end + + it 'does not include routes for non renderable items' do + menu_item = Sidebars::MenuItem.new(context) + menu.add_item(menu_item) + + allow(menu).to receive(:active_routes).and_return({ path: 'foo' }) + allow(menu_item).to receive(:render?).and_return(false) + allow(menu_item).to receive(:active_routes).and_return({ controller: 'bar' }) + + expect(menu.all_active_routes).to eq({ path: ['foo'] }) + end + end + + describe '#render?' do + context 'when the menus has no items' do + it 'returns true' do + expect(menu.render?).to be true + end + end + + context 'when the menu has items' do + let(:menu_item) { Sidebars::MenuItem.new(context) } + + before do + menu.add_item(menu_item) + end + + context 'when items are not renderable' do + it 'returns false' do + allow(menu_item).to receive(:render?).and_return(false) + + expect(menu.render?).to be false + end + end + + context 'when there are renderable items' do + it 'returns true' do + expect(menu.render?).to be true + end + end + end + end +end diff --git a/spec/lib/sidebars/panel_spec.rb b/spec/lib/sidebars/panel_spec.rb new file mode 100644 index 00000000000..0e539460810 --- /dev/null +++ b/spec/lib/sidebars/panel_spec.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Sidebars::Panel do + let(:context) { Sidebars::Context.new(current_user: nil, container: nil) } + let(:panel) { Sidebars::Panel.new(context) } + let(:menu1) { Sidebars::Menu.new(context) } + let(:menu2) { Sidebars::Menu.new(context) } + + describe '#renderable_menus' do + it 'returns only renderable menus' do + panel.add_menu(menu1) + panel.add_menu(menu2) + + allow(menu1).to receive(:render?).and_return(true) + allow(menu2).to receive(:render?).and_return(false) + + expect(panel.renderable_menus).to eq([menu1]) + end + end + + describe '#has_renderable_menus?' do + it 'returns false when no renderable menus' do + expect(panel.has_renderable_menus?).to be false + end + + it 'returns true when no renderable menus' do + panel.add_menu(menu1) + + expect(panel.has_renderable_menus?).to be true + end + end +end diff --git a/spec/lib/sidebars/projects/context_spec.rb b/spec/lib/sidebars/projects/context_spec.rb new file mode 100644 index 00000000000..44578ae1583 --- /dev/null +++ b/spec/lib/sidebars/projects/context_spec.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Sidebars::Projects::Context do + let(:project) { build(:project) } + + subject { described_class.new(current_user: nil, container: project) } + + it 'sets project attribute reader' do + expect(subject.project).to eq(project) + end +end diff --git a/spec/lib/sidebars/projects/menus/learn_gitlab/menu_spec.rb b/spec/lib/sidebars/projects/menus/learn_gitlab/menu_spec.rb new file mode 100644 index 00000000000..bc1815558d3 --- /dev/null +++ b/spec/lib/sidebars/projects/menus/learn_gitlab/menu_spec.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Sidebars::Projects::Menus::LearnGitlab::Menu do + let(:project) { build(:project) } + let(:experiment_enabled) { true } + let(:context) { Sidebars::Projects::Context.new(current_user: nil, container: project, learn_gitlab_experiment_enabled: experiment_enabled) } + + subject { described_class.new(context) } + + it 'does not contain any sub menu' do + expect(subject.instance_variable_get(:@items)).to be_empty + end + + describe '#render?' do + context 'when learn gitlab experiment is enabled' do + it 'returns true' do + expect(subject.render?).to eq true + end + end + + context 'when learn gitlab experiment is disabled' do + let(:experiment_enabled) { false } + + it 'returns false' do + expect(subject.render?).to eq false + end + end + end +end diff --git a/spec/lib/sidebars/projects/menus/project_overview/menu_items/releases_spec.rb b/spec/lib/sidebars/projects/menus/project_overview/menu_items/releases_spec.rb new file mode 100644 index 00000000000..db124c2252e --- /dev/null +++ b/spec/lib/sidebars/projects/menus/project_overview/menu_items/releases_spec.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Sidebars::Projects::Menus::ProjectOverview::MenuItems::Releases do + let_it_be(:project) { create(:project, :repository) } + + let(:user) { project.owner } + let(:context) { Sidebars::Projects::Context.new(current_user: user, container: project) } + + subject { described_class.new(context) } + + describe '#render?' do + context 'when project repository is empty' do + it 'returns false' do + allow(project).to receive(:empty_repo?).and_return(true) + + expect(subject.render?).to eq false + end + end + + context 'when project repository is not empty' do + context 'when user can read releases' do + it 'returns true' do + expect(subject.render?).to eq true + end + end + + context 'when user cannot read releases' do + let(:user) { nil } + + it 'returns false' do + expect(subject.render?).to eq false + end + end + end + end +end diff --git a/spec/lib/sidebars/projects/menus/project_overview/menu_spec.rb b/spec/lib/sidebars/projects/menus/project_overview/menu_spec.rb new file mode 100644 index 00000000000..105a28ce953 --- /dev/null +++ b/spec/lib/sidebars/projects/menus/project_overview/menu_spec.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Sidebars::Projects::Menus::ProjectOverview::Menu do + let(:project) { build(:project) } + let(:context) { Sidebars::Projects::Context.new(current_user: nil, container: project) } + + subject { described_class.new(context) } + + it 'has the required items' do + items = subject.instance_variable_get(:@items) + + expect(items[0]).to be_a(Sidebars::Projects::Menus::ProjectOverview::MenuItems::Details) + expect(items[1]).to be_a(Sidebars::Projects::Menus::ProjectOverview::MenuItems::Activity) + expect(items[2]).to be_a(Sidebars::Projects::Menus::ProjectOverview::MenuItems::Releases) + end +end diff --git a/spec/lib/sidebars/projects/menus/repository/menu_spec.rb b/spec/lib/sidebars/projects/menus/repository/menu_spec.rb new file mode 100644 index 00000000000..04eb3357a6f --- /dev/null +++ b/spec/lib/sidebars/projects/menus/repository/menu_spec.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Sidebars::Projects::Menus::Repository::Menu do + let_it_be(:project) { create(:project, :repository) } + + let(:user) { project.owner } + let(:context) { Sidebars::Projects::Context.new(current_user: user, container: project) } + + subject { described_class.new(context) } + + describe '#render?' do + context 'when project repository is empty' do + it 'returns false' do + allow(project).to receive(:empty_repo?).and_return(true) + + expect(subject.render?).to eq false + end + end + + context 'when project repository is not empty' do + context 'when user can download code' do + it 'returns true' do + expect(subject.render?).to eq true + end + end + + context 'when user cannot download code' do + let(:user) { nil } + + it 'returns false' do + expect(subject.render?).to eq false + end + end + end + end +end diff --git a/spec/lib/sidebars/projects/panel_spec.rb b/spec/lib/sidebars/projects/panel_spec.rb new file mode 100644 index 00000000000..bad9b17bc83 --- /dev/null +++ b/spec/lib/sidebars/projects/panel_spec.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Sidebars::Projects::Panel do + let(:project) { build(:project) } + let(:context) { Sidebars::Projects::Context.new(current_user: nil, container: project) } + + subject { described_class.new(context) } + + it 'has a scope menu' do + expect(subject.scope_menu).to be_a(Sidebars::Projects::Menus::Scope::Menu) + end +end diff --git a/spec/models/concerns/sidebars/container_with_html_options_spec.rb b/spec/models/concerns/sidebars/container_with_html_options_spec.rb deleted file mode 100644 index cc83fc84113..00000000000 --- a/spec/models/concerns/sidebars/container_with_html_options_spec.rb +++ /dev/null @@ -1,21 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Sidebars::ContainerWithHtmlOptions do - subject do - Class.new do - include Sidebars::ContainerWithHtmlOptions - - def title - 'Foo' - end - end.new - end - - describe '#container_html_options' do - it 'includes by default aria-label attribute' do - expect(subject.container_html_options).to eq(aria: { label: 'Foo' }) - end - end -end diff --git a/spec/models/concerns/sidebars/positionable_list_spec.rb b/spec/models/concerns/sidebars/positionable_list_spec.rb deleted file mode 100644 index 231aa5295dd..00000000000 --- a/spec/models/concerns/sidebars/positionable_list_spec.rb +++ /dev/null @@ -1,59 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Sidebars::PositionableList do - subject do - Class.new do - include Sidebars::PositionableList - end.new - end - - describe '#add_element' do - it 'adds the element to the last position of the list' do - list = [1, 2] - - subject.add_element(list, 3) - - expect(list).to eq([1, 2, 3]) - end - end - - describe '#insert_element_before' do - let(:user) { build(:user) } - let(:list) { [1, user] } - - it 'adds element before the specific element class' do - subject.insert_element_before(list, User, 2) - - expect(list).to eq [1, 2, user] - end - - context 'when reference element does not exist' do - it 'adds the element to the top of the list' do - subject.insert_element_before(list, Project, 2) - - expect(list).to eq [2, 1, user] - end - end - end - - describe '#insert_element_after' do - let(:user) { build(:user) } - let(:list) { [1, user] } - - it 'adds element after the specific element class' do - subject.insert_element_after(list, Integer, 2) - - expect(list).to eq [1, 2, user] - end - - context 'when reference element does not exist' do - it 'adds the element to the end of the list' do - subject.insert_element_after(list, Project, 2) - - expect(list).to eq [1, user, 2] - end - end - end -end diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb index 2f82d8a0bbe..05825a4f78c 100644 --- a/spec/models/group_spec.rb +++ b/spec/models/group_spec.rb @@ -2214,17 +2214,17 @@ RSpec.describe Group do end describe "#default_branch_name" do - context "group.namespace_settings does not have a default branch name" do + context "when group.namespace_settings does not have a default branch name" do it "returns nil" do expect(group.default_branch_name).to be_nil end end - context "group.namespace_settings has a default branch name" do + context "when group.namespace_settings has a default branch name" do let(:example_branch_name) { "example_branch_name" } before do - expect(group.namespace_settings) + allow(group.namespace_settings) .to receive(:default_branch_name) .and_return(example_branch_name) end diff --git a/spec/models/sidebars/menu_spec.rb b/spec/models/sidebars/menu_spec.rb deleted file mode 100644 index 320f5f1ad1e..00000000000 --- a/spec/models/sidebars/menu_spec.rb +++ /dev/null @@ -1,67 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Sidebars::Menu do - let(:menu) { described_class.new(context) } - let(:context) { Sidebars::Context.new(current_user: nil, container: nil) } - - describe '#all_active_routes' do - it 'gathers all active routes of items and the current menu' do - menu_item1 = Sidebars::MenuItem.new(context) - menu_item2 = Sidebars::MenuItem.new(context) - menu_item3 = Sidebars::MenuItem.new(context) - menu.add_item(menu_item1) - menu.add_item(menu_item2) - menu.add_item(menu_item3) - - allow(menu).to receive(:active_routes).and_return({ path: 'foo' }) - allow(menu_item1).to receive(:active_routes).and_return({ path: %w(bar test) }) - allow(menu_item2).to receive(:active_routes).and_return({ controller: 'fooc' }) - allow(menu_item3).to receive(:active_routes).and_return({ controller: 'barc' }) - - expect(menu.all_active_routes).to eq({ path: %w(foo bar test), controller: %w(fooc barc) }) - end - - it 'does not include routes for non renderable items' do - menu_item = Sidebars::MenuItem.new(context) - menu.add_item(menu_item) - - allow(menu).to receive(:active_routes).and_return({ path: 'foo' }) - allow(menu_item).to receive(:render?).and_return(false) - allow(menu_item).to receive(:active_routes).and_return({ controller: 'bar' }) - - expect(menu.all_active_routes).to eq({ path: ['foo'] }) - end - end - - describe '#render?' do - context 'when the menus has no items' do - it 'returns true' do - expect(menu.render?).to be true - end - end - - context 'when the menu has items' do - let(:menu_item) { Sidebars::MenuItem.new(context) } - - before do - menu.add_item(menu_item) - end - - context 'when items are not renderable' do - it 'returns false' do - allow(menu_item).to receive(:render?).and_return(false) - - expect(menu.render?).to be false - end - end - - context 'when there are renderable items' do - it 'returns true' do - expect(menu.render?).to be true - end - end - end - end -end diff --git a/spec/models/sidebars/panel_spec.rb b/spec/models/sidebars/panel_spec.rb deleted file mode 100644 index 0e539460810..00000000000 --- a/spec/models/sidebars/panel_spec.rb +++ /dev/null @@ -1,34 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Sidebars::Panel do - let(:context) { Sidebars::Context.new(current_user: nil, container: nil) } - let(:panel) { Sidebars::Panel.new(context) } - let(:menu1) { Sidebars::Menu.new(context) } - let(:menu2) { Sidebars::Menu.new(context) } - - describe '#renderable_menus' do - it 'returns only renderable menus' do - panel.add_menu(menu1) - panel.add_menu(menu2) - - allow(menu1).to receive(:render?).and_return(true) - allow(menu2).to receive(:render?).and_return(false) - - expect(panel.renderable_menus).to eq([menu1]) - end - end - - describe '#has_renderable_menus?' do - it 'returns false when no renderable menus' do - expect(panel.has_renderable_menus?).to be false - end - - it 'returns true when no renderable menus' do - panel.add_menu(menu1) - - expect(panel.has_renderable_menus?).to be true - end - end -end diff --git a/spec/models/sidebars/projects/context_spec.rb b/spec/models/sidebars/projects/context_spec.rb deleted file mode 100644 index 44578ae1583..00000000000 --- a/spec/models/sidebars/projects/context_spec.rb +++ /dev/null @@ -1,13 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Sidebars::Projects::Context do - let(:project) { build(:project) } - - subject { described_class.new(current_user: nil, container: project) } - - it 'sets project attribute reader' do - expect(subject.project).to eq(project) - end -end diff --git a/spec/models/sidebars/projects/menus/learn_gitlab/menu_spec.rb b/spec/models/sidebars/projects/menus/learn_gitlab/menu_spec.rb deleted file mode 100644 index bc1815558d3..00000000000 --- a/spec/models/sidebars/projects/menus/learn_gitlab/menu_spec.rb +++ /dev/null @@ -1,31 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Sidebars::Projects::Menus::LearnGitlab::Menu do - let(:project) { build(:project) } - let(:experiment_enabled) { true } - let(:context) { Sidebars::Projects::Context.new(current_user: nil, container: project, learn_gitlab_experiment_enabled: experiment_enabled) } - - subject { described_class.new(context) } - - it 'does not contain any sub menu' do - expect(subject.instance_variable_get(:@items)).to be_empty - end - - describe '#render?' do - context 'when learn gitlab experiment is enabled' do - it 'returns true' do - expect(subject.render?).to eq true - end - end - - context 'when learn gitlab experiment is disabled' do - let(:experiment_enabled) { false } - - it 'returns false' do - expect(subject.render?).to eq false - end - end - end -end diff --git a/spec/models/sidebars/projects/menus/project_overview/menu_items/releases_spec.rb b/spec/models/sidebars/projects/menus/project_overview/menu_items/releases_spec.rb deleted file mode 100644 index db124c2252e..00000000000 --- a/spec/models/sidebars/projects/menus/project_overview/menu_items/releases_spec.rb +++ /dev/null @@ -1,38 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Sidebars::Projects::Menus::ProjectOverview::MenuItems::Releases do - let_it_be(:project) { create(:project, :repository) } - - let(:user) { project.owner } - let(:context) { Sidebars::Projects::Context.new(current_user: user, container: project) } - - subject { described_class.new(context) } - - describe '#render?' do - context 'when project repository is empty' do - it 'returns false' do - allow(project).to receive(:empty_repo?).and_return(true) - - expect(subject.render?).to eq false - end - end - - context 'when project repository is not empty' do - context 'when user can read releases' do - it 'returns true' do - expect(subject.render?).to eq true - end - end - - context 'when user cannot read releases' do - let(:user) { nil } - - it 'returns false' do - expect(subject.render?).to eq false - end - end - end - end -end diff --git a/spec/models/sidebars/projects/menus/project_overview/menu_spec.rb b/spec/models/sidebars/projects/menus/project_overview/menu_spec.rb deleted file mode 100644 index 105a28ce953..00000000000 --- a/spec/models/sidebars/projects/menus/project_overview/menu_spec.rb +++ /dev/null @@ -1,18 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Sidebars::Projects::Menus::ProjectOverview::Menu do - let(:project) { build(:project) } - let(:context) { Sidebars::Projects::Context.new(current_user: nil, container: project) } - - subject { described_class.new(context) } - - it 'has the required items' do - items = subject.instance_variable_get(:@items) - - expect(items[0]).to be_a(Sidebars::Projects::Menus::ProjectOverview::MenuItems::Details) - expect(items[1]).to be_a(Sidebars::Projects::Menus::ProjectOverview::MenuItems::Activity) - expect(items[2]).to be_a(Sidebars::Projects::Menus::ProjectOverview::MenuItems::Releases) - end -end diff --git a/spec/models/sidebars/projects/menus/repository/menu_spec.rb b/spec/models/sidebars/projects/menus/repository/menu_spec.rb deleted file mode 100644 index 04eb3357a6f..00000000000 --- a/spec/models/sidebars/projects/menus/repository/menu_spec.rb +++ /dev/null @@ -1,38 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Sidebars::Projects::Menus::Repository::Menu do - let_it_be(:project) { create(:project, :repository) } - - let(:user) { project.owner } - let(:context) { Sidebars::Projects::Context.new(current_user: user, container: project) } - - subject { described_class.new(context) } - - describe '#render?' do - context 'when project repository is empty' do - it 'returns false' do - allow(project).to receive(:empty_repo?).and_return(true) - - expect(subject.render?).to eq false - end - end - - context 'when project repository is not empty' do - context 'when user can download code' do - it 'returns true' do - expect(subject.render?).to eq true - end - end - - context 'when user cannot download code' do - let(:user) { nil } - - it 'returns false' do - expect(subject.render?).to eq false - end - end - end - end -end diff --git a/spec/models/sidebars/projects/panel_spec.rb b/spec/models/sidebars/projects/panel_spec.rb deleted file mode 100644 index bad9b17bc83..00000000000 --- a/spec/models/sidebars/projects/panel_spec.rb +++ /dev/null @@ -1,14 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Sidebars::Projects::Panel do - let(:project) { build(:project) } - let(:context) { Sidebars::Projects::Context.new(current_user: nil, container: project) } - - subject { described_class.new(context) } - - it 'has a scope menu' do - expect(subject.scope_menu).to be_a(Sidebars::Projects::Menus::Scope::Menu) - end -end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 3abf2a651a0..393fd53193b 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -1056,6 +1056,21 @@ RSpec.describe User do .to contain_exactly(user) end end + + describe '.for_todos' do + let_it_be(:user1) { create(:user) } + let_it_be(:user2) { create(:user) } + let_it_be(:issue) { create(:issue) } + + let_it_be(:todo1) { create(:todo, target: issue, author: user1, user: user1) } + let_it_be(:todo2) { create(:todo, target: issue, author: user1, user: user1) } + let_it_be(:todo3) { create(:todo, target: issue, author: user2, user: user2) } + + it 'returns users for the given todos' do + expect(described_class.for_todos(issue.todos)) + .to contain_exactly(user1, user2) + end + end end describe "Respond to" do diff --git a/spec/services/ci/pipeline_processing/test_cases/dag_test_manual_post_test_needs_deploy_is_stage.yml b/spec/services/ci/pipeline_processing/test_cases/dag_test_manual_post_test_needs_deploy_is_stage.yml new file mode 100644 index 00000000000..03d5781395d --- /dev/null +++ b/spec/services/ci/pipeline_processing/test_cases/dag_test_manual_post_test_needs_deploy_is_stage.yml @@ -0,0 +1,50 @@ +config: + stages: [build, test, post_test, deploy] + + build: + stage: build + script: exit 0 + + test: + stage: test + script: exit 0 + when: manual + + post_test: + stage: post_test + script: exit 0 + needs: [test] + + deploy: + stage: deploy + script: exit 0 + +init: + expect: + pipeline: pending + stages: + build: pending + test: created + post_test: created + deploy: created + jobs: + build: pending + test: created + post_test: created + deploy: created + +transitions: + - event: success + jobs: [build] + expect: + pipeline: running + stages: + build: success + test: skipped + post_test: skipped + deploy: pending + jobs: + build: success + test: manual + post_test: skipped + deploy: pending diff --git a/spec/services/todo_service_spec.rb b/spec/services/todo_service_spec.rb index 59f936509df..35503010b53 100644 --- a/spec/services/todo_service_spec.rb +++ b/spec/services/todo_service_spec.rb @@ -345,17 +345,10 @@ RSpec.describe TodoService do describe '#destroy_target' do it 'refreshes the todos count cache for users with todos on the target' do - create(:todo, state: :pending, target: issue, user: john_doe, author: john_doe, project: issue.project) + create(:todo, state: :pending, target: issue, user: author, author: author, project: issue.project) + create(:todo, state: :done, target: issue, user: assignee, author: assignee, project: issue.project) - expect_next(Users::UpdateTodoCountCacheService, [john_doe]).to receive(:execute) - - service.destroy_target(issue) { issue.destroy! } - end - - it 'does not refresh the todos count cache for users with only done todos on the target' do - create(:todo, :done, target: issue, user: john_doe, author: john_doe, project: issue.project) - - expect(Users::UpdateTodoCountCacheService).not_to receive(:new) + expect_next(Users::UpdateTodoCountCacheService, [author, assignee]).to receive(:execute) service.destroy_target(issue) { issue.destroy! } end diff --git a/spec/support/helpers/test_env.rb b/spec/support/helpers/test_env.rb index 7ba15a9c00b..87de0fb29cb 100644 --- a/spec/support/helpers/test_env.rb +++ b/spec/support/helpers/test_env.rb @@ -52,7 +52,7 @@ module TestEnv 'wip' => 'b9238ee', 'csv' => '3dd0896', 'v1.1.0' => 'b83d6e3', - 'add-ipython-files' => '93ee732', + 'add-ipython-files' => 'f6b7a70', 'add-pdf-file' => 'e774ebd', 'squash-large-files' => '54cec52', 'add-pdf-text-binary' => '79faa7b', diff --git a/spec/support/shared_examples/lib/gitlab/sql/set_operator_shared_examples.rb b/spec/support/shared_examples/lib/gitlab/sql/set_operator_shared_examples.rb index aa6a51c3646..8d758ed1655 100644 --- a/spec/support/shared_examples/lib/gitlab/sql/set_operator_shared_examples.rb +++ b/spec/support/shared_examples/lib/gitlab/sql/set_operator_shared_examples.rb @@ -21,7 +21,7 @@ RSpec.shared_examples 'SQL set operator' do |operator_keyword| expect(set_operator.to_sql).to eq("(#{to_sql(relation_1)})\n#{operator_keyword}\n(#{to_sql(relation_2)})") end - it 'skips Model.none segements' do + it 'skips Model.none segments' do empty_relation = User.none set_operator = described_class.new([empty_relation, relation_1, relation_2]) diff --git a/spec/workers/ci/create_cross_project_pipeline_worker_spec.rb b/spec/workers/ci/create_cross_project_pipeline_worker_spec.rb index 116e6878281..372b0de1b54 100644 --- a/spec/workers/ci/create_cross_project_pipeline_worker_spec.rb +++ b/spec/workers/ci/create_cross_project_pipeline_worker_spec.rb @@ -6,6 +6,7 @@ RSpec.describe Ci::CreateCrossProjectPipelineWorker do let_it_be(:user) { create(:user) } let_it_be(:project) { create(:project) } let_it_be(:pipeline) { create(:ci_pipeline, project: project) } + let(:bridge) { create(:ci_bridge, user: user, pipeline: pipeline) } let(:service) { double('pipeline creation service') } diff --git a/spec/workers/cluster_update_app_worker_spec.rb b/spec/workers/cluster_update_app_worker_spec.rb index 8b8c1c82099..0db255cf68d 100644 --- a/spec/workers/cluster_update_app_worker_spec.rb +++ b/spec/workers/cluster_update_app_worker_spec.rb @@ -48,6 +48,7 @@ RSpec.describe ClusterUpdateAppWorker do context 'with exclusive lease' do let_it_be(:user) { create(:user) } + let(:application) { create(:clusters_applications_prometheus, :installed) } let(:lease_key) { "#{described_class.name.underscore}-#{application.id}" } diff --git a/spec/workers/environments/canary_ingress/update_worker_spec.rb b/spec/workers/environments/canary_ingress/update_worker_spec.rb index 7bc5108719c..e7782c2fba1 100644 --- a/spec/workers/environments/canary_ingress/update_worker_spec.rb +++ b/spec/workers/environments/canary_ingress/update_worker_spec.rb @@ -4,6 +4,7 @@ require 'spec_helper' RSpec.describe Environments::CanaryIngress::UpdateWorker do let_it_be(:environment) { create(:environment) } + let(:worker) { described_class.new } describe '#perform' do diff --git a/spec/workers/expire_job_cache_worker_spec.rb b/spec/workers/expire_job_cache_worker_spec.rb index 8efead31a42..cbd9dd39336 100644 --- a/spec/workers/expire_job_cache_worker_spec.rb +++ b/spec/workers/expire_job_cache_worker_spec.rb @@ -4,6 +4,7 @@ require 'spec_helper' RSpec.describe ExpireJobCacheWorker do let_it_be(:pipeline) { create(:ci_empty_pipeline) } + let(:project) { pipeline.project } describe '#perform' do diff --git a/spec/workers/gitlab/jira_import/import_issue_worker_spec.rb b/spec/workers/gitlab/jira_import/import_issue_worker_spec.rb index 324e8010887..695e21f4733 100644 --- a/spec/workers/gitlab/jira_import/import_issue_worker_spec.rb +++ b/spec/workers/gitlab/jira_import/import_issue_worker_spec.rb @@ -7,6 +7,7 @@ RSpec.describe Gitlab::JiraImport::ImportIssueWorker do let_it_be(:project) { create(:project) } let_it_be(:jira_issue_label_1) { create(:label, project: project) } let_it_be(:jira_issue_label_2) { create(:label, project: project) } + let(:some_key) { 'some-key' } describe 'modules' do diff --git a/spec/workers/gitlab/jira_import/stage/start_import_worker_spec.rb b/spec/workers/gitlab/jira_import/stage/start_import_worker_spec.rb index 7066e6e912f..e440884553f 100644 --- a/spec/workers/gitlab/jira_import/stage/start_import_worker_spec.rb +++ b/spec/workers/gitlab/jira_import/stage/start_import_worker_spec.rb @@ -5,6 +5,7 @@ require 'spec_helper' RSpec.describe Gitlab::JiraImport::Stage::StartImportWorker do let_it_be(:project) { create(:project, import_type: 'jira') } let_it_be(:jid) { '12345678' } + let(:worker) { described_class.new } describe 'modules' do diff --git a/spec/workers/gitlab/jira_import/stuck_jira_import_jobs_worker_spec.rb b/spec/workers/gitlab/jira_import/stuck_jira_import_jobs_worker_spec.rb index 7f1cb8a2076..92754513988 100644 --- a/spec/workers/gitlab/jira_import/stuck_jira_import_jobs_worker_spec.rb +++ b/spec/workers/gitlab/jira_import/stuck_jira_import_jobs_worker_spec.rb @@ -5,6 +5,7 @@ require 'spec_helper' RSpec.describe ::Gitlab::JiraImport::StuckJiraImportJobsWorker do let_it_be(:current_user) { create(:user) } let_it_be(:project) { create(:project) } + let(:worker) { described_class.new } describe 'with scheduled Jira import' do diff --git a/spec/workers/import_issues_csv_worker_spec.rb b/spec/workers/import_issues_csv_worker_spec.rb index 6a698af49c0..919ab2b1adf 100644 --- a/spec/workers/import_issues_csv_worker_spec.rb +++ b/spec/workers/import_issues_csv_worker_spec.rb @@ -5,6 +5,7 @@ require 'spec_helper' RSpec.describe ImportIssuesCsvWorker do let_it_be(:project) { create(:project) } let_it_be(:user) { create(:user) } + let(:upload) { create(:upload, :with_file) } let(:worker) { described_class.new } diff --git a/spec/workers/incident_management/add_severity_system_note_worker_spec.rb b/spec/workers/incident_management/add_severity_system_note_worker_spec.rb index 203c62ffe6f..bda6f729759 100644 --- a/spec/workers/incident_management/add_severity_system_note_worker_spec.rb +++ b/spec/workers/incident_management/add_severity_system_note_worker_spec.rb @@ -40,6 +40,7 @@ RSpec.describe IncidentManagement::AddSeveritySystemNoteWorker do context 'when issue is not an incident' do let_it_be(:issue) { create(:issue, project: project) } + let(:incident_id) { issue.id } it_behaves_like 'does not add a system note' diff --git a/spec/workers/incident_management/process_alert_worker_spec.rb b/spec/workers/incident_management/process_alert_worker_spec.rb index 41d4f31da24..7db9b191677 100644 --- a/spec/workers/incident_management/process_alert_worker_spec.rb +++ b/spec/workers/incident_management/process_alert_worker_spec.rb @@ -10,6 +10,7 @@ RSpec.describe IncidentManagement::ProcessAlertWorker do let_it_be(:started_at) { Time.now.rfc3339 } let_it_be(:payload) { { 'title' => 'title', 'start_time' => started_at } } let_it_be(:alert) { create(:alert_management_alert, project: project, payload: payload, started_at: started_at) } + let(:created_issue) { Issue.last! } subject { described_class.new.perform(nil, nil, alert.id) } diff --git a/spec/workers/incident_management/process_prometheus_alert_worker_spec.rb b/spec/workers/incident_management/process_prometheus_alert_worker_spec.rb index 2ca4193aa72..56f07459a15 100644 --- a/spec/workers/incident_management/process_prometheus_alert_worker_spec.rb +++ b/spec/workers/incident_management/process_prometheus_alert_worker_spec.rb @@ -6,6 +6,7 @@ RSpec.describe IncidentManagement::ProcessPrometheusAlertWorker do describe '#perform' do let_it_be(:project) { create(:project) } let_it_be(:prometheus_alert) { create(:prometheus_alert, project: project) } + let(:payload_key) { Gitlab::AlertManagement::Payload::Prometheus.new(project: project, payload: alert_params).gitlab_fingerprint } let!(:prometheus_alert_event) { create(:prometheus_alert_event, prometheus_alert: prometheus_alert, payload_key: payload_key) } let!(:settings) { create(:project_incident_management_setting, project: project, create_issue: true) } diff --git a/spec/workers/jira_connect/sync_project_worker_spec.rb b/spec/workers/jira_connect/sync_project_worker_spec.rb index 04cc3bec3af..5c0e7e7609c 100644 --- a/spec/workers/jira_connect/sync_project_worker_spec.rb +++ b/spec/workers/jira_connect/sync_project_worker_spec.rb @@ -5,6 +5,7 @@ require 'spec_helper' RSpec.describe JiraConnect::SyncProjectWorker, factory_default: :keep do describe '#perform' do let_it_be(:project) { create_default(:project).freeze } + let!(:mr_with_jira_title) { create(:merge_request, :unique_branches, title: 'TEST-123') } let!(:mr_with_jira_description) { create(:merge_request, :unique_branches, description: 'TEST-323') } let!(:mr_with_other_title) { create(:merge_request, :unique_branches) } diff --git a/spec/workers/namespaces/onboarding_issue_created_worker_spec.rb b/spec/workers/namespaces/onboarding_issue_created_worker_spec.rb index 459e4f953d0..32e7bdd563d 100644 --- a/spec/workers/namespaces/onboarding_issue_created_worker_spec.rb +++ b/spec/workers/namespaces/onboarding_issue_created_worker_spec.rb @@ -4,6 +4,7 @@ require 'spec_helper' RSpec.describe Namespaces::OnboardingIssueCreatedWorker, '#perform' do let_it_be(:issue) { create(:issue) } + let(:namespace) { issue.namespace } it_behaves_like 'records an onboarding progress action', :issue_created do diff --git a/spec/workers/packages/composer/cache_update_worker_spec.rb b/spec/workers/packages/composer/cache_update_worker_spec.rb index cc6b48c80eb..a0d8aa5d375 100644 --- a/spec/workers/packages/composer/cache_update_worker_spec.rb +++ b/spec/workers/packages/composer/cache_update_worker_spec.rb @@ -8,6 +8,7 @@ RSpec.describe Packages::Composer::CacheUpdateWorker, type: :worker do let_it_be(:json) { { 'name' => package_name } } let_it_be(:group) { create(:group) } let_it_be(:project) { create(:project, :custom_repo, files: { 'composer.json' => json.to_json }, group: group) } + let(:last_sha) { nil } let!(:package) { create(:composer_package, :with_metadatum, project: project, name: package_name, version: '1.0.0', json: json) } let(:job_args) { [project.id, package_name, last_sha] } diff --git a/spec/workers/pages_domain_ssl_renewal_cron_worker_spec.rb b/spec/workers/pages_domain_ssl_renewal_cron_worker_spec.rb index dac8c529984..563bbdef1be 100644 --- a/spec/workers/pages_domain_ssl_renewal_cron_worker_spec.rb +++ b/spec/workers/pages_domain_ssl_renewal_cron_worker_spec.rb @@ -13,6 +13,7 @@ RSpec.describe PagesDomainSslRenewalCronWorker do describe '#perform' do let_it_be(:project) { create :project } + let!(:domain) { create(:pages_domain, project: project, auto_ssl_enabled: false) } let!(:domain_with_enabled_auto_ssl) { create(:pages_domain, project: project, auto_ssl_enabled: true) } let!(:domain_with_obtained_letsencrypt) do diff --git a/spec/workers/projects/git_garbage_collect_worker_spec.rb b/spec/workers/projects/git_garbage_collect_worker_spec.rb index 8c44643ae51..7b54d7df4b2 100644 --- a/spec/workers/projects/git_garbage_collect_worker_spec.rb +++ b/spec/workers/projects/git_garbage_collect_worker_spec.rb @@ -36,6 +36,7 @@ RSpec.describe Projects::GitGarbageCollectWorker do context 'LFS object garbage collection' do let_it_be(:lfs_reference) { create(:lfs_objects_project, project: project) } + let(:lfs_object) { lfs_reference.lfs_object } before do diff --git a/spec/workers/prometheus/create_default_alerts_worker_spec.rb b/spec/workers/prometheus/create_default_alerts_worker_spec.rb index 105fa0415d9..887d677c95f 100644 --- a/spec/workers/prometheus/create_default_alerts_worker_spec.rb +++ b/spec/workers/prometheus/create_default_alerts_worker_spec.rb @@ -4,6 +4,7 @@ require 'spec_helper' RSpec.describe Prometheus::CreateDefaultAlertsWorker do let_it_be(:project) { create(:project) } + let(:worker) { described_class.new } let(:logger) { worker.send(:logger) } let(:service) { instance_double(Prometheus::CreateDefaultAlertsService) } diff --git a/spec/workers/propagate_integration_group_worker_spec.rb b/spec/workers/propagate_integration_group_worker_spec.rb index fbf1fbf1fea..1c72bed323a 100644 --- a/spec/workers/propagate_integration_group_worker_spec.rb +++ b/spec/workers/propagate_integration_group_worker_spec.rb @@ -9,6 +9,7 @@ RSpec.describe PropagateIntegrationGroupWorker do let_it_be(:subgroup1) { create(:group, parent: group) } let_it_be(:subgroup2) { create(:group, parent: group) } let_it_be(:integration) { create(:redmine_service, :instance) } + let(:job_args) { [integration.id, group.id, subgroup2.id] } it_behaves_like 'an idempotent worker' do diff --git a/spec/workers/propagate_integration_project_worker_spec.rb b/spec/workers/propagate_integration_project_worker_spec.rb index 0302af2acc9..c8293744bec 100644 --- a/spec/workers/propagate_integration_project_worker_spec.rb +++ b/spec/workers/propagate_integration_project_worker_spec.rb @@ -9,6 +9,7 @@ RSpec.describe PropagateIntegrationProjectWorker do let_it_be(:project2) { create(:project, group: group) } let_it_be(:project3) { create(:project, group: group) } let_it_be(:integration) { create(:redmine_service, :instance) } + let(:job_args) { [integration.id, project1.id, project3.id] } it_behaves_like 'an idempotent worker' do diff --git a/spec/workers/run_pipeline_schedule_worker_spec.rb b/spec/workers/run_pipeline_schedule_worker_spec.rb index 0b9f95e09fe..fc572c0d9c3 100644 --- a/spec/workers/run_pipeline_schedule_worker_spec.rb +++ b/spec/workers/run_pipeline_schedule_worker_spec.rb @@ -7,6 +7,7 @@ RSpec.describe RunPipelineScheduleWorker do let_it_be(:project) { create(:project) } let_it_be(:user) { create(:user) } let_it_be(:pipeline_schedule) { create(:ci_pipeline_schedule, :nightly, project: project ) } + let(:worker) { described_class.new } context 'when a project not found' do diff --git a/spec/workers/update_external_pull_requests_worker_spec.rb b/spec/workers/update_external_pull_requests_worker_spec.rb index 80f22470977..cb6a4e2ebf8 100644 --- a/spec/workers/update_external_pull_requests_worker_spec.rb +++ b/spec/workers/update_external_pull_requests_worker_spec.rb @@ -6,6 +6,7 @@ RSpec.describe UpdateExternalPullRequestsWorker do describe '#perform' do let_it_be(:project) { create(:project, import_source: 'tanuki/repository') } let_it_be(:user) { create(:user) } + let(:worker) { described_class.new } before do -- cgit v1.2.3