diff --git a/Gemfile b/Gemfile index 97b1fe2696d..899b7525319 100644 --- a/Gemfile +++ b/Gemfile @@ -153,7 +153,7 @@ gem 'faraday_middleware-aws-sigv4', '~>0.3.0' # Markdown and HTML processing gem 'html-pipeline', '~> 2.13.2' gem 'deckar01-task_list', '2.3.1' -gem 'gitlab-markup', '~> 1.7.1' +gem 'gitlab-markup', '~> 1.8.0' gem 'github-markup', '~> 1.7.0', require: 'github/markup' gem 'commonmarker', '~> 0.23.2' gem 'kramdown', '~> 2.3.1' diff --git a/Gemfile.lock b/Gemfile.lock index 185e018736a..00205c4b827 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -489,7 +489,7 @@ GEM with_env (= 1.1.0) xml-simple (~> 1.1.5) gitlab-mail_room (0.0.9) - gitlab-markup (1.7.1) + gitlab-markup (1.8.0) gitlab-net-dns (0.9.1) gitlab-omniauth-openid-connect (0.8.0) addressable (~> 2.7) @@ -1482,7 +1482,7 @@ DEPENDENCIES gitlab-license (~> 2.0) gitlab-license_finder (~> 6.0) gitlab-mail_room (~> 0.0.9) - gitlab-markup (~> 1.7.1) + gitlab-markup (~> 1.8.0) gitlab-net-dns (~> 0.9.1) gitlab-omniauth-openid-connect (~> 0.8.0) gitlab-sidekiq-fetcher (= 0.8.0) diff --git a/app/assets/stylesheets/startup/startup-dark.scss b/app/assets/stylesheets/startup/startup-dark.scss index 63305bc592d..c9ff8205142 100644 --- a/app/assets/stylesheets/startup/startup-dark.scss +++ b/app/assets/stylesheets/startup/startup-dark.scss @@ -1832,6 +1832,7 @@ body.gl-dark .header-search svg { body.gl-dark .header-search input { background-color: transparent; color: rgba(250, 250, 250, 0.8); + box-shadow: inset 0 0 0 1px rgba(250, 250, 250, 0.4); } body.gl-dark .header-search input::placeholder { color: rgba(250, 250, 250, 0.8); diff --git a/app/assets/stylesheets/themes/theme_helper.scss b/app/assets/stylesheets/themes/theme_helper.scss index 1332686a906..e119af716a6 100644 --- a/app/assets/stylesheets/themes/theme_helper.scss +++ b/app/assets/stylesheets/themes/theme_helper.scss @@ -154,6 +154,7 @@ input { background-color: transparent; color: rgba($search-and-nav-links, 0.8); + box-shadow: inset 0 0 0 1px rgba($search-and-nav-links, 0.4); &::placeholder { color: rgba($search-and-nav-links, 0.8); diff --git a/app/services/verify_pages_domain_service.rb b/app/services/verify_pages_domain_service.rb index eab1e91dc89..408ee429a74 100644 --- a/app/services/verify_pages_domain_service.rb +++ b/app/services/verify_pages_domain_service.rb @@ -85,7 +85,8 @@ class VerifyPagesDomainService < BaseService end def check(domain_name, resolver) - records = parse(txt_records(domain_name, resolver)) + # Append '.' to domain_name, indicating absolute FQDN + records = parse(txt_records(domain_name + '.', resolver)) records.any? do |record| record == domain.keyed_verification_code || record == domain.verification_code diff --git a/app/views/admin/hooks/edit.html.haml b/app/views/admin/hooks/edit.html.haml index 93038e63a2e..9c258e10008 100644 --- a/app/views/admin/hooks/edit.html.haml +++ b/app/views/admin/hooks/edit.html.haml @@ -1,6 +1,8 @@ - add_to_breadcrumbs @hook.pluralized_name, admin_hooks_path - page_title _('Edit System Hook') += render 'shared/web_hooks/hook_errors', hook: @hook + .row.gl-mt-3 .col-lg-3 = render 'shared/web_hooks/title_and_docs', hook: @hook diff --git a/app/views/profiles/notifications/_group_settings.html.haml b/app/views/profiles/notifications/_group_settings.html.haml index 82083af9ff1..23fce8e04b6 100644 --- a/app/views/profiles/notifications/_group_settings.html.haml +++ b/app/views/profiles/notifications/_group_settings.html.haml @@ -13,5 +13,5 @@ .js-vue-notification-dropdown{ data: { disabled: emails_disabled.to_s, dropdown_items: notification_dropdown_items(setting).to_json, notification_level: setting.level, group_id: group.id, container_class: 'gl-mr-3', show_label: "true" } } .table-section.section-30 - = form_for setting, url: profile_notifications_group_path(group), method: :put, html: { class: 'update-notifications gl-display-flex' } do |f| + = form_for setting, url: profile_group_notifications_path(group), method: :put, html: { class: 'update-notifications gl-display-flex' } do |f| = f.select :notification_email, @user.public_verified_emails, { include_blank: 'Global notification email' }, class: 'select2 js-group-notification-email' diff --git a/app/views/projects/hooks/edit.html.haml b/app/views/projects/hooks/edit.html.haml index 3358025b237..7d696a988d4 100644 --- a/app/views/projects/hooks/edit.html.haml +++ b/app/views/projects/hooks/edit.html.haml @@ -2,19 +2,7 @@ - add_to_breadcrumbs _('Webhook Settings'), project_hooks_path(@project) - page_title _('Webhook') -- if @hook.rate_limited? - - placeholders = { strong_start: ''.html_safe, - strong_end: ''.html_safe, - limit: @hook.rate_limit, - support_link_start: ''.html_safe, - support_link_end: ''.html_safe } - = render 'shared/global_alert', - title: s_('Webhooks|Webhook was automatically disabled'), - variant: :danger, - is_contained: true, - close_button_class: 'js-close' do - .gl-alert-body - = s_('Webhooks|The webhook was triggered more than %{limit} times per minute and is now disabled. To re-enable this webhook, fix the problems shown in %{strong_start}Recent events%{strong_end}, then re-test your settings. %{support_link_start}Contact Support%{support_link_end} if you need help re-enabling your webhook.').html_safe % placeholders += render 'shared/web_hooks/hook_errors', hook: @hook .row.gl-mt-3 .col-lg-3 diff --git a/app/views/projects/merge_requests/_mr_title.html.haml b/app/views/projects/merge_requests/_mr_title.html.haml index 0e8de3c2bb8..9d5d1de1005 100644 --- a/app/views/projects/merge_requests/_mr_title.html.haml +++ b/app/views/projects/merge_requests/_mr_title.html.haml @@ -4,7 +4,7 @@ - are_close_and_open_buttons_hidden = merge_request_button_hidden?(@merge_request, true) && merge_request_button_hidden?(@merge_request, false) - cache_key = [@project, @merge_request, can_update_merge_request, can_reopen_merge_request, are_close_and_open_buttons_hidden] -= cache_if(Feature.enabled?(:cached_mr_title, @project, default_enabled: :yaml), cache_key, expires_in: 1.day) do += cache(cache_key, expires_in: 1.day) do - if @merge_request.closed_or_merged_without_fork? .gl-alert.gl-alert-danger.gl-mb-5 .gl-alert-container diff --git a/app/views/shared/web_hooks/_hook.html.haml b/app/views/shared/web_hooks/_hook.html.haml index ef1eb6b4e45..45baa7e2184 100644 --- a/app/views/shared/web_hooks/_hook.html.haml +++ b/app/views/shared/web_hooks/_hook.html.haml @@ -5,6 +5,10 @@ = hook.url - if hook.rate_limited? %span.gl-badge.badge-danger.badge-pill.sm= _('Disabled') + - elsif hook.permanently_disabled? + %span.gl-badge.badge-danger.badge-pill.sm= s_('Webhooks|Failed to connect') + - elsif hook.temporarily_disabled? + %span.gl-badge.badge-warning.badge-pill.sm= s_('Webhooks|Fails to connect') %div - hook.class.triggers.each_value do |trigger| diff --git a/app/views/shared/web_hooks/_hook_errors.html.haml b/app/views/shared/web_hooks/_hook_errors.html.haml new file mode 100644 index 00000000000..23010b8349c --- /dev/null +++ b/app/views/shared/web_hooks/_hook_errors.html.haml @@ -0,0 +1,41 @@ +- strong_start = ''.html_safe +- strong_end = ''.html_safe +- link_start = ''.html_safe +- link_end = ''.html_safe + +- if hook.rate_limited? + - support_path = 'https://support.gitlab.com/hc/en-us/requests/new' + - placeholders = { strong_start: strong_start, + strong_end: strong_end, + limit: hook.rate_limit, + support_link_start: link_start % { url: support_path }, + support_link_end: link_end } + = render 'shared/global_alert', + title: s_('Webhooks|Webhook was automatically disabled'), + variant: :danger, + is_contained: true, + close_button_class: 'js-close' do + .gl-alert-body + = s_('Webhooks|The webhook was triggered more than %{limit} times per minute and is now disabled. To re-enable this webhook, fix the problems shown in %{strong_start}Recent events%{strong_end}, then re-test your settings. %{support_link_start}Contact Support%{support_link_end} if you need help re-enabling your webhook.').html_safe % placeholders +- elsif hook.permanently_disabled? + = render 'shared/global_alert', + title: s_('Webhooks|Webhook failed to connect'), + variant: :danger, + is_contained: true, + close_button_class: 'js-close' do + .gl-alert-body + = s_('Webhooks|The webhook failed to connect, and is disabled. To re-enable it, check %{strong_start}Recent events%{strong_end} for error details, then test your settings below.').html_safe % { strong_start: strong_start, strong_end: strong_end } +- elsif hook.temporarily_disabled? + - help_path = help_page_path('user/project/integrations/webhooks', anchor: 'webhook-fails-or-multiple-webhook-requests-are-triggered') + - placeholders = { strong_start: strong_start, + strong_end: strong_end, + retry_time: time_interval_in_words(hook.disabled_until - Time.now), + help_link_start: link_start % { url: help_path }, + help_link_end: link_end } + = render 'shared/global_alert', + title: s_('Webhooks|Webhook fails to connect'), + variant: :warning, + is_contained: true, + close_button_class: 'js-close' do + .gl-alert-body + = s_('Webhooks|The webhook %{help_link_start}failed to connect%{help_link_end}, and will retry in %{retry_time}. To re-enable it, check %{strong_start}Recent events%{strong_end} for error details, then test your settings below.').html_safe % placeholders diff --git a/config/feature_flags/development/cached_mr_title.yml b/config/feature_flags/development/sbom_survey.yml similarity index 65% rename from config/feature_flags/development/cached_mr_title.yml rename to config/feature_flags/development/sbom_survey.yml index 0284663f441..aac523ee846 100644 --- a/config/feature_flags/development/cached_mr_title.yml +++ b/config/feature_flags/development/sbom_survey.yml @@ -1,8 +1,8 @@ --- -name: cached_mr_title -introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/61605 -rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/330907 -milestone: '13.12' +name: sbom_survey +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/76446 +rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/348181 +milestone: '14.6' type: development -group: group::source code +group: group::secure default_enabled: false diff --git a/config/routes/profile.rb b/config/routes/profile.rb index 3eda53318e3..b8d4a0c49c2 100644 --- a/config/routes/profile.rb +++ b/config/routes/profile.rb @@ -22,7 +22,14 @@ resource :profile, only: [:show, :update] do end resource :notifications, only: [:show, :update] do - resources :groups, only: :update, constraints: { id: Gitlab::PathRegex.full_namespace_route_regex } + scope(path: 'groups/*id', + id: Gitlab::PathRegex.full_namespace_route_regex, + as: :group, + controller: :groups, + constraints: { format: /(html|json)/ }) do + patch '/', action: :update + put '/', action: :update + end end resource :password, only: [:new, :create, :edit, :update] do diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md index 18f57965f21..89b402b7b4c 100644 --- a/doc/api/graphql/reference/index.md +++ b/doc/api/graphql/reference/index.md @@ -511,6 +511,7 @@ four standard [pagination arguments](#connection-pagination-arguments): | Name | Type | Description | | ---- | ---- | ----------- | +| `clusterAgentId` | [`[ClustersAgentID!]`](#clustersagentid) | Filter vulnerabilities by `cluster_agent_id`. Vulnerabilities with a `reportType` of `cluster_image_scanning` are only included with this filter. | | `clusterId` | [`[ClustersClusterID!]`](#clustersclusterid) | Filter vulnerabilities by `cluster_id`. Vulnerabilities with a `reportType` of `cluster_image_scanning` are only included with this filter. | | `hasIssues` | [`Boolean`](#boolean) | Returns only the vulnerabilities which have linked issues. | | `hasResolution` | [`Boolean`](#boolean) | Returns only the vulnerabilities which have been resolved on default branch. | @@ -10995,6 +10996,7 @@ four standard [pagination arguments](#connection-pagination-arguments): | Name | Type | Description | | ---- | ---- | ----------- | +| `clusterAgentId` | [`[ClustersAgentID!]`](#clustersagentid) | Filter vulnerabilities by `cluster_agent_id`. Vulnerabilities with a `reportType` of `cluster_image_scanning` are only included with this filter. | | `clusterId` | [`[ClustersClusterID!]`](#clustersclusterid) | Filter vulnerabilities by `cluster_id`. Vulnerabilities with a `reportType` of `cluster_image_scanning` are only included with this filter. | | `hasIssues` | [`Boolean`](#boolean) | Returns only the vulnerabilities which have linked issues. | | `hasResolution` | [`Boolean`](#boolean) | Returns only the vulnerabilities which have been resolved on default branch. | @@ -13808,6 +13810,7 @@ four standard [pagination arguments](#connection-pagination-arguments): | Name | Type | Description | | ---- | ---- | ----------- | +| `clusterAgentId` | [`[ClustersAgentID!]`](#clustersagentid) | Filter vulnerabilities by `cluster_agent_id`. Vulnerabilities with a `reportType` of `cluster_image_scanning` are only included with this filter. | | `clusterId` | [`[ClustersClusterID!]`](#clustersclusterid) | Filter vulnerabilities by `cluster_id`. Vulnerabilities with a `reportType` of `cluster_image_scanning` are only included with this filter. | | `hasIssues` | [`Boolean`](#boolean) | Returns only the vulnerabilities which have linked issues. | | `hasResolution` | [`Boolean`](#boolean) | Returns only the vulnerabilities which have been resolved on default branch. | diff --git a/doc/user/admin_area/index.md b/doc/user/admin_area/index.md index d25caf1d7b4..b0f38e8cfb9 100644 --- a/doc/user/admin_area/index.md +++ b/doc/user/admin_area/index.md @@ -107,15 +107,16 @@ You can combine the filter options. For example, to list only public projects wi 1. Click the **Public** tab. 1. Enter `score` in the **Filter by name...** input box. -#### Deleted projects **(PREMIUM SELF)** +#### Projects pending deletion **(PREMIUM SELF)** -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/37014) in GitLab 13.3. +> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/37014) in GitLab 13.3. +> - [Tab renamed](https://gitlab.com/gitlab-org/gitlab/-/issues/347468) from **Deleted projects** in GitLab 14.7. When delayed project deletion is [enabled for a group](../group/index.md#enable-delayed-project-deletion), projects within that group are not deleted immediately, but only after a delay. To access a list of all projects that are pending deletion: 1. On the top bar, select **Menu > Projects > Explore projects**. -1. Select the **Deleted projects** tab. +1. Select the **Pending deletion** tab (in GitLab 14.7 and later) or the **Deleted projects** tab (GitLab 14.6 and earlier). Listed for each project is: diff --git a/doc/user/application_security/cluster_image_scanning/index.md b/doc/user/application_security/cluster_image_scanning/index.md index 8ad938a0469..c3a2c179590 100644 --- a/doc/user/application_security/cluster_image_scanning/index.md +++ b/doc/user/application_security/cluster_image_scanning/index.md @@ -177,6 +177,7 @@ You can [configure](#customize-the-cluster-image-scanning-settings) analyzers by | `CIS_RESOURCE_NAMESPACE` | `""` | Namespace of the Kubernetes resource you want to filter vulnerabilities for. For example, `production`. | | `CIS_RESOURCE_KIND` | `""` | Kind of the Kubernetes resource you want to filter vulnerabilities for. For example, `deployment`. | | `CIS_CLUSTER_IDENTIFIER` | `""` | ID of the Kubernetes cluster integrated with GitLab. This is used to map vulnerabilities to the cluster so they can be filtered in the Vulnerability Report page. | +| `CIS_CLUSTER_AGENT_IDENTIFIER` | `""` | ID of the Kubernetes cluster agent integrated with GitLab. This maps vulnerabilities to the agent so they can be filtered in the Vulnerability Report page. | #### Override the cluster image scanning template diff --git a/doc/user/markdown.md b/doc/user/markdown.md index ce1a8146f1b..1b3cd5d4478 100644 --- a/doc/user/markdown.md +++ b/doc/user/markdown.md @@ -998,6 +998,8 @@ Here's a sample audio clip: ### Inline HTML +> Allowing `rel="license"` [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/20857) in GitLab 14.6. + To see the second example of Markdown rendered in HTML, [view it in GitLab](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/user/markdown.md#inline-html). @@ -1006,6 +1008,7 @@ You can also use raw HTML in your Markdown, and it usually works pretty well. See the documentation for HTML::Pipeline's [SanitizationFilter](https://github.com/jch/html-pipeline/blob/v2.12.3/lib/html/pipeline/sanitization_filter.rb#L42) class for the list of allowed HTML tags and attributes. In addition to the default `SanitizationFilter` allowlist, GitLab allows `span`, `abbr`, `details` and `summary` elements. +`rel="license"` is allowed on links to support the [Rel-License microformat](https://microformats.org/wiki/rel-license) and license attribution. ```html
diff --git a/lib/banzai/filter/base_sanitization_filter.rb b/lib/banzai/filter/base_sanitization_filter.rb index c63453f94ca..7ea32c4b1e7 100644 --- a/lib/banzai/filter/base_sanitization_filter.rb +++ b/lib/banzai/filter/base_sanitization_filter.rb @@ -59,7 +59,11 @@ module Banzai def remove_rel lambda do |env| if env[:node_name] == 'a' - env[:node].remove_attribute('rel') + # we allow rel="license" to support the Rel-license microformat + # http://microformats.org/wiki/rel-license + unless env[:node].attribute('rel')&.value == 'license' + env[:node].remove_attribute('rel') + end end end end diff --git a/lib/banzai/filter/external_link_filter.rb b/lib/banzai/filter/external_link_filter.rb index 67019454e44..dc65e2abb46 100644 --- a/lib/banzai/filter/external_link_filter.rb +++ b/lib/banzai/filter/external_link_filter.rb @@ -112,7 +112,9 @@ module Banzai def add_nofollow!(uri, node) if SCHEMES.include?(uri&.scheme) + license = true if node.attribute('rel')&.value == 'license' node.set_attribute('rel', 'nofollow noreferrer noopener') + node.kwattr_append('rel', 'license') if license node.set_attribute('target', '_blank') end end diff --git a/lib/gitlab/spamcheck/client.rb b/lib/gitlab/spamcheck/client.rb index e7dce91ae08..40b01552244 100644 --- a/lib/gitlab/spamcheck/client.rb +++ b/lib/gitlab/spamcheck/client.rb @@ -99,7 +99,7 @@ module Gitlab end def client_creds(url) - if URI(url).scheme == 'tls' || Rails.env.production? + if URI(url).scheme == 'tls' GRPC::Core::ChannelCredentials.new(::Gitlab::X509::Certificate.ca_certs_bundle) else :this_channel_is_insecure diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 7349b90e68c..b261d58b6b8 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -11491,15 +11491,9 @@ msgstr "" msgid "Deleted" msgstr "" -msgid "Deleted Projects" -msgstr "" - msgid "Deleted chat nickname: %{chat_name}!" msgstr "" -msgid "Deleted projects" -msgstr "" - msgid "Deleted projects cannot be restored!" msgstr "" @@ -25489,9 +25483,15 @@ msgstr "" msgid "Pending" msgstr "" +msgid "Pending Deletion" +msgstr "" + msgid "Pending comments" msgstr "" +msgid "Pending deletion" +msgstr "" + msgid "Pending owner approval" msgstr "" @@ -29399,10 +29399,10 @@ msgstr "" msgid "Removed upload with id %{id}" msgstr "" -msgid "RemovedProjects|Projects which are removed and are yet to be permanently removed are visible here." +msgid "RemovedProjects|No projects pending deletion found" msgstr "" -msgid "RemovedProjects|You haven’t removed any projects." +msgid "RemovedProjects|Projects that are pending deletion that you have access to are listed here." msgstr "" msgid "Removes %{assignee_text} %{assignee_references}." @@ -31591,6 +31591,9 @@ msgstr "" msgid "SecurityReports|Take survey" msgstr "" +msgid "SecurityReports|The Composition Analysis group is planning significant updates to how we make available the list of software and container dependency information in your projects. Therefore, we ask that you assist us by taking a short -no longer than 5 minute- survey to help align our direction with your needs." +msgstr "" + msgid "SecurityReports|The Vulnerability Report shows the results of the latest successful pipeline on your project's default branch, as well as vulnerabilities from your latest container scan. %{linkStart}Learn more.%{linkEnd}" msgstr "" @@ -31666,6 +31669,9 @@ msgstr "" msgid "SecurityReports|You must sign in as an authorized user to see this report" msgstr "" +msgid "SecurityReports|Your feedback is important to us! We will ask again in 7 days." +msgstr "" + msgid "SecurityReports|Your feedback is important to us! We will ask again in a week." msgstr "" @@ -39433,6 +39439,12 @@ msgstr "" msgid "Webhooks|Enable SSL verification" msgstr "" +msgid "Webhooks|Failed to connect" +msgstr "" + +msgid "Webhooks|Fails to connect" +msgstr "" + msgid "Webhooks|Feature flag events" msgstr "" @@ -39469,6 +39481,12 @@ msgstr "" msgid "Webhooks|Tag push events" msgstr "" +msgid "Webhooks|The webhook %{help_link_start}failed to connect%{help_link_end}, and will retry in %{retry_time}. To re-enable it, check %{strong_start}Recent events%{strong_end} for error details, then test your settings below." +msgstr "" + +msgid "Webhooks|The webhook failed to connect, and is disabled. To re-enable it, check %{strong_start}Recent events%{strong_end} for error details, then test your settings below." +msgstr "" + msgid "Webhooks|The webhook was triggered more than %{limit} times per minute and is now disabled. To re-enable this webhook, fix the problems shown in %{strong_start}Recent events%{strong_end}, then re-test your settings. %{support_link_start}Contact Support%{support_link_end} if you need help re-enabling your webhook." msgstr "" @@ -39529,6 +39547,12 @@ msgstr "" msgid "Webhooks|Use this token to validate received payloads. It is sent with the request in the X-Gitlab-Token HTTP header." msgstr "" +msgid "Webhooks|Webhook failed to connect" +msgstr "" + +msgid "Webhooks|Webhook fails to connect" +msgstr "" + msgid "Webhooks|Webhook was automatically disabled" msgstr "" diff --git a/spec/frontend/admin/statistics_panel/components/app_spec.js b/spec/frontend/admin/statistics_panel/components/app_spec.js index 9c424491d04..3cfb6feeb86 100644 --- a/spec/frontend/admin/statistics_panel/components/app_spec.js +++ b/spec/frontend/admin/statistics_panel/components/app_spec.js @@ -1,6 +1,7 @@ import { GlLoadingIcon } from '@gitlab/ui'; -import { createLocalVue, shallowMount } from '@vue/test-utils'; +import { shallowMount } from '@vue/test-utils'; import AxiosMockAdapter from 'axios-mock-adapter'; +import Vue from 'vue'; import Vuex from 'vuex'; import StatisticsPanelApp from '~/admin/statistics_panel/components/app.vue'; import statisticsLabels from '~/admin/statistics_panel/constants'; @@ -9,8 +10,7 @@ import axios from '~/lib/utils/axios_utils'; import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; import mockStatistics from '../mock_data'; -const localVue = createLocalVue(); -localVue.use(Vuex); +Vue.use(Vuex); describe('Admin statistics app', () => { let wrapper; @@ -19,7 +19,6 @@ describe('Admin statistics app', () => { const createComponent = () => { wrapper = shallowMount(StatisticsPanelApp, { - localVue, store, }); }; diff --git a/spec/frontend/admin/users/components/users_table_spec.js b/spec/frontend/admin/users/components/users_table_spec.js index 708c9e1979e..9ff5961c7ec 100644 --- a/spec/frontend/admin/users/components/users_table_spec.js +++ b/spec/frontend/admin/users/components/users_table_spec.js @@ -1,5 +1,5 @@ import { GlTable, GlSkeletonLoader } from '@gitlab/ui'; -import { createLocalVue } from '@vue/test-utils'; +import Vue from 'vue'; import VueApollo from 'vue-apollo'; import createMockApollo from 'helpers/mock_apollo_helper'; @@ -16,8 +16,7 @@ import { users, paths, createGroupCountResponse } from '../mock_data'; jest.mock('~/flash'); -const localVue = createLocalVue(); -localVue.use(VueApollo); +Vue.use(VueApollo); describe('AdminUsersTable component', () => { let wrapper; @@ -48,7 +47,6 @@ describe('AdminUsersTable component', () => { const initComponent = (props = {}, resolverMock = fetchGroupCountsResponse) => { wrapper = mountExtended(AdminUsersTable, { - localVue, apolloProvider: createMockApolloProvider(resolverMock), propsData: { users, diff --git a/spec/frontend/analytics/usage_trends/components/usage_trends_count_chart_spec.js b/spec/frontend/analytics/usage_trends/components/usage_trends_count_chart_spec.js index 7c2df3fe8c4..1a331100bb8 100644 --- a/spec/frontend/analytics/usage_trends/components/usage_trends_count_chart_spec.js +++ b/spec/frontend/analytics/usage_trends/components/usage_trends_count_chart_spec.js @@ -1,6 +1,7 @@ import { GlAlert } from '@gitlab/ui'; import { GlLineChart } from '@gitlab/ui/dist/charts'; -import { createLocalVue, shallowMount } from '@vue/test-utils'; +import { shallowMount } from '@vue/test-utils'; +import Vue from 'vue'; import VueApollo from 'vue-apollo'; import createMockApollo from 'helpers/mock_apollo_helper'; import UsageTrendsCountChart from '~/analytics/usage_trends/components/usage_trends_count_chart.vue'; @@ -9,8 +10,7 @@ import ChartSkeletonLoader from '~/vue_shared/components/resizable_chart/skeleto import { mockQueryResponse, mockApolloResponse } from '../apollo_mock_data'; import { mockCountsData1 } from '../mock_data'; -const localVue = createLocalVue(); -localVue.use(VueApollo); +Vue.use(VueApollo); const loadChartErrorMessage = 'My load error message'; const noDataMessage = 'My no data message'; @@ -39,7 +39,6 @@ describe('UsageTrendsCountChart', () => { const createComponent = ({ responseHandler }) => { return shallowMount(UsageTrendsCountChart, { - localVue, apolloProvider: createMockApollo([[statsQuery, responseHandler]]), propsData: { ...mockChartConfig }, }); diff --git a/spec/frontend/analytics/usage_trends/components/users_chart_spec.js b/spec/frontend/analytics/usage_trends/components/users_chart_spec.js index 6adfcca11ac..04ea25a02d5 100644 --- a/spec/frontend/analytics/usage_trends/components/users_chart_spec.js +++ b/spec/frontend/analytics/usage_trends/components/users_chart_spec.js @@ -1,6 +1,7 @@ import { GlAlert } from '@gitlab/ui'; import { GlAreaChart } from '@gitlab/ui/dist/charts'; -import { createLocalVue, shallowMount } from '@vue/test-utils'; +import { shallowMount } from '@vue/test-utils'; +import Vue from 'vue'; import VueApollo from 'vue-apollo'; import createMockApollo from 'helpers/mock_apollo_helper'; import UsersChart from '~/analytics/usage_trends/components/users_chart.vue'; @@ -13,8 +14,7 @@ import { roundedSortedCountsMonthlyChartData2, } from '../mock_data'; -const localVue = createLocalVue(); -localVue.use(VueApollo); +Vue.use(VueApollo); describe('UsersChart', () => { let wrapper; @@ -34,7 +34,6 @@ describe('UsersChart', () => { endDate: new Date(2020, 10, 1), totalDataPoints: mockCountsData2.length, }, - localVue, apolloProvider: createMockApollo([[usersQuery, queryHandler]]), data() { return { loadingError }; diff --git a/spec/lib/banzai/filter/external_link_filter_spec.rb b/spec/lib/banzai/filter/external_link_filter_spec.rb index 630730dfc1a..24d13bdb42c 100644 --- a/spec/lib/banzai/filter/external_link_filter_spec.rb +++ b/spec/lib/banzai/filter/external_link_filter_spec.rb @@ -191,4 +191,15 @@ RSpec.describe Banzai::Filter::ExternalLinkFilter do end end end + + context 'for links that have `rel=license`' do + let(:doc) { filter %q(rel-license) } + + it_behaves_like 'an external link with rel attribute' + + it 'maintains rel license' do + expect(doc.at_css('a')).to have_attribute('rel') + expect(doc.at_css('a')['rel']).to include 'license' + end + end end diff --git a/spec/lib/banzai/filter/sanitization_filter_spec.rb b/spec/lib/banzai/filter/sanitization_filter_spec.rb index 8eb8e5cf800..24e787bddd5 100644 --- a/spec/lib/banzai/filter/sanitization_filter_spec.rb +++ b/spec/lib/banzai/filter/sanitization_filter_spec.rb @@ -115,6 +115,11 @@ RSpec.describe Banzai::Filter::SanitizationFilter do expect(filter(act).to_html).to eq exp end + it 'allows `rel=license` in links' do + exp = act = 'rel-license' + expect(filter(act).to_html).to eq exp + end + it 'allows `data-math-style` attribute on `code` and `pre` elements' do html = <<-HTML
something
diff --git a/spec/lib/gitlab/spamcheck/client_spec.rb b/spec/lib/gitlab/spamcheck/client_spec.rb index 0c392bf0b9d..a6e7665569c 100644 --- a/spec/lib/gitlab/spamcheck/client_spec.rb +++ b/spec/lib/gitlab/spamcheck/client_spec.rb @@ -56,36 +56,6 @@ RSpec.describe Gitlab::Spamcheck::Client do end end - describe "Rails environment" do - let(:stub) { double(:spamcheck_stub, check_for_spam_issue: response) } - - context "production" do - before do - allow(Rails.env).to receive(:production?).and_return(true) - end - - it 'uses secure connection' do - expect(Spamcheck::SpamcheckService::Stub).to receive(:new).with(endpoint.sub(%r{^grpc://}, ''), - instance_of(GRPC::Core::ChannelCredentials), - anything).and_return(stub) - subject - end - end - - context "not production" do - before do - allow(Rails.env).to receive(:production?).and_return(false) - end - - it 'uses insecure connection' do - expect(Spamcheck::SpamcheckService::Stub).to receive(:new).with(endpoint.sub(%r{^grpc://}, ''), - :this_channel_is_insecure, - anything).and_return(stub) - subject - end - end - end - describe '#issue_spam?' do before do allow_next_instance_of(::Spamcheck::SpamcheckService::Stub) do |instance| diff --git a/spec/routing/notifications_routing_spec.rb b/spec/routing/notifications_routing_spec.rb index d66aa7f219f..303281c763e 100644 --- a/spec/routing/notifications_routing_spec.rb +++ b/spec/routing/notifications_routing_spec.rb @@ -12,7 +12,8 @@ RSpec.describe "notifications routing" do end it 'routes to group #update' do - expect(put("/-/profile/notifications/groups/gitlab-org")).to route_to("profiles/groups#update", id: 'gitlab-org') - expect(put("/-/profile/notifications/groups/gitlab.org")).to route_to("profiles/groups#update", id: 'gitlab.org') + expect(put("/-/profile/groups/gitlab-org/notifications")).to route_to("profiles/groups#update", id: 'gitlab-org') + expect(put("/-/profile/groups/gitlab.org/notifications/")).to route_to("profiles/groups#update", id: 'gitlab.org') + expect(put("/-/profile/groups/gitlab.org/gitlab/notifications")).to route_to("profiles/groups#update", id: 'gitlab.org/gitlab') end end diff --git a/spec/services/verify_pages_domain_service_spec.rb b/spec/services/verify_pages_domain_service_spec.rb index ae079229891..2a3b3814065 100644 --- a/spec/services/verify_pages_domain_service_spec.rb +++ b/spec/services/verify_pages_domain_service_spec.rb @@ -372,7 +372,8 @@ RSpec.describe VerifyPagesDomainService do allow(resolver).to receive(:getresources) { [] } stubbed_lookups.each do |domain, records| records = Array(records).map { |txt| Resolv::DNS::Resource::IN::TXT.new(txt) } - allow(resolver).to receive(:getresources).with(domain, Resolv::DNS::Resource::IN::TXT) { records } + # Append '.' to domain_name, indicating absolute FQDN + allow(resolver).to receive(:getresources).with(domain + '.', Resolv::DNS::Resource::IN::TXT) { records } end resolver diff --git a/spec/views/projects/hooks/edit.html.haml_spec.rb b/spec/views/projects/hooks/edit.html.haml_spec.rb index 1265334a572..c4ec2149794 100644 --- a/spec/views/projects/hooks/edit.html.haml_spec.rb +++ b/spec/views/projects/hooks/edit.html.haml_spec.rb @@ -30,4 +30,29 @@ RSpec.describe 'projects/hooks/edit' do expect(rendered).to have_text(s_('Webhooks|Webhook was automatically disabled')) end end + + context 'webhook is permanently disabled' do + before do + allow(hook).to receive(:permanently_disabled?).and_return(true) + end + + it 'renders alert' do + render + + expect(rendered).to have_text(s_('Webhooks|Webhook failed to connect')) + end + end + + context 'webhook is temporarily disabled' do + before do + allow(hook).to receive(:temporarily_disabled?).and_return(true) + allow(hook).to receive(:disabled_until).and_return(Time.now + 10.minutes) + end + + it 'renders alert' do + render + + expect(rendered).to have_text(s_('Webhooks|Webhook fails to connect')) + end + end end diff --git a/spec/views/projects/hooks/index.html.haml_spec.rb b/spec/views/projects/hooks/index.html.haml_spec.rb index eb2b7334b98..0cdc3bcecb2 100644 --- a/spec/views/projects/hooks/index.html.haml_spec.rb +++ b/spec/views/projects/hooks/index.html.haml_spec.rb @@ -20,6 +20,8 @@ RSpec.describe 'projects/hooks/index' do expect(rendered).to have_css('h4', text: _('Webhooks')) expect(rendered).to have_text('Project Hooks') expect(rendered).not_to have_css('.gl-badge', text: _('Disabled')) + expect(rendered).not_to have_css('.gl-badge', text: s_('Webhooks|Failed to connect')) + expect(rendered).not_to have_css('.gl-badge', text: s_('Webhooks|Fails to connect')) end context 'webhook is rate limited' do @@ -33,4 +35,28 @@ RSpec.describe 'projects/hooks/index' do expect(rendered).to have_css('.gl-badge', text: _('Disabled')) end end + + context 'webhook is permanently disabled' do + before do + allow(existing_hook).to receive(:permanently_disabled?).and_return(true) + end + + it 'renders "Failed to connect" badge' do + render + + expect(rendered).to have_css('.gl-badge', text: s_('Webhooks|Failed to connect')) + end + end + + context 'webhook is temporarily disabled' do + before do + allow(existing_hook).to receive(:temporarily_disabled?).and_return(true) + end + + it 'renders "Fails to connect" badge' do + render + + expect(rendered).to have_css('.gl-badge', text: s_('Webhooks|Fails to connect')) + end + end end