diff options
66 files changed, 1085 insertions, 864 deletions
diff --git a/.rubocop.yml b/.rubocop.yml index d2cca0295ee..514e4271272 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -345,6 +345,8 @@ RSpec/HaveGitlabHttpStatus: - 'ee/spec/controllers/**/*' - 'spec/requests/*.rb' - 'ee/spec/requests/*.rb' + - 'spec/requests/api/*/**/*.rb' + - 'ee/spec/requests/api/*/**/*.rb' Style/MultilineWhenThen: Enabled: false diff --git a/app/assets/javascripts/error_tracking/components/error_tracking_list.vue b/app/assets/javascripts/error_tracking/components/error_tracking_list.vue index a90f446159d..70f257180c6 100644 --- a/app/assets/javascripts/error_tracking/components/error_tracking_list.vue +++ b/app/assets/javascripts/error_tracking/components/error_tracking_list.vue @@ -19,7 +19,7 @@ import AccessorUtils from '~/lib/utils/accessor'; import Icon from '~/vue_shared/components/icon.vue'; import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue'; import { __ } from '~/locale'; -import _ from 'underscore'; +import { isEmpty } from 'lodash'; export const tableDataClass = 'table-col d-flex d-sm-table-cell align-items-center'; @@ -139,7 +139,7 @@ export default { 'cursor', ]), paginationRequired() { - return !_.isEmpty(this.pagination); + return !isEmpty(this.pagination); }, }, watch: { diff --git a/app/assets/javascripts/error_tracking/components/stacktrace_entry.vue b/app/assets/javascripts/error_tracking/components/stacktrace_entry.vue index 4e63e167260..8db0b1c5da0 100644 --- a/app/assets/javascripts/error_tracking/components/stacktrace_entry.vue +++ b/app/assets/javascripts/error_tracking/components/stacktrace_entry.vue @@ -1,5 +1,5 @@ <script> -import _ from 'underscore'; +import { escape as esc } from 'lodash'; import { GlTooltip } from '@gitlab/ui'; import { __, sprintf } from '~/locale'; import ClipboardButton from '~/vue_shared/components/clipboard_button.vue'; @@ -62,7 +62,7 @@ export default { ? sprintf( __(`%{spanStart}in%{spanEnd} %{errorFn}`), { - errorFn: `<strong>${_.escape(this.errorFn)}</strong>`, + errorFn: `<strong>${esc(this.errorFn)}</strong>`, spanStart: `<span class="text-tertiary">`, spanEnd: `</span>`, }, diff --git a/app/assets/javascripts/mirrors/mirror_repos.js b/app/assets/javascripts/mirrors/mirror_repos.js index 33e9b1c4e46..e5acaaf9366 100644 --- a/app/assets/javascripts/mirrors/mirror_repos.js +++ b/app/assets/javascripts/mirrors/mirror_repos.js @@ -1,5 +1,5 @@ import $ from 'jquery'; -import _ from 'underscore'; +import { debounce } from 'lodash'; import { __ } from '~/locale'; import Flash from '~/flash'; import axios from '~/lib/utils/axios_utils'; @@ -62,7 +62,7 @@ export default class MirrorRepos { } registerUpdateListeners() { - this.debouncedUpdateUrl = _.debounce(() => this.updateUrl(), 200); + this.debouncedUpdateUrl = debounce(() => this.updateUrl(), 200); this.$urlInput.on('input', () => this.debouncedUpdateUrl()); this.$protectedBranchesInput.on('change', () => this.updateProtectedBranches()); this.$table.on('click', '.js-delete-mirror', event => this.deleteMirror(event)); diff --git a/app/assets/javascripts/mirrors/ssh_mirror.js b/app/assets/javascripts/mirrors/ssh_mirror.js index bb5ae6ce2d1..550e1aeeb9c 100644 --- a/app/assets/javascripts/mirrors/ssh_mirror.js +++ b/app/assets/javascripts/mirrors/ssh_mirror.js @@ -1,5 +1,5 @@ import $ from 'jquery'; -import _ from 'underscore'; +import { escape as esc } from 'lodash'; import { __ } from '~/locale'; import axios from '~/lib/utils/axios_utils'; import Flash from '~/flash'; @@ -162,7 +162,7 @@ export default class SSHMirror { const $fingerprintsList = this.$hostKeysInformation.find('.js-fingerprints-list'); let fingerprints = ''; sshHostKeys.fingerprints.forEach(fingerprint => { - const escFingerprints = _.escape(fingerprint.fingerprint); + const escFingerprints = esc(fingerprint.fingerprint); fingerprints += `<code>${escFingerprints}</code>`; }); diff --git a/app/assets/javascripts/registry/settings/components/registry_settings_app.vue b/app/assets/javascripts/registry/settings/components/registry_settings_app.vue index 2156c4469da..87e65d354bb 100644 --- a/app/assets/javascripts/registry/settings/components/registry_settings_app.vue +++ b/app/assets/javascripts/registry/settings/components/registry_settings_app.vue @@ -1,7 +1,7 @@ <script> import { mapActions, mapState } from 'vuex'; -import { GlAlert } from '@gitlab/ui'; -import { sprintf, s__ } from '~/locale'; +import { GlAlert, GlSprintf, GlLink } from '@gitlab/ui'; +import { s__ } from '~/locale'; import { FETCH_SETTINGS_ERROR_MESSAGE } from '../../shared/constants'; @@ -11,22 +11,16 @@ export default { components: { SettingsForm, GlAlert, + GlSprintf, + GlLink, + }, + i18n: { + unavailableFeatureText: s__( + 'ContainerRegistry|Currently, the Container Registry tag expiration feature is not available for projects created before GitLab version 12.8. For updates and more information, visit Issue %{linkStart}#196124%{linkEnd}', + ), }, computed: { ...mapState(['isDisabled']), - notAvailableMessage() { - return sprintf( - s__( - 'ContainerRegistry|Currently, the Container Registry tag expiration feature is not available for projects created before GitLab version 12.8. For updates and more information, visit Issue %{linkStart}#196124%{linkEnd}', - ), - { - linkStart: - '<a href="https://gitlab.com/gitlab-org/gitlab/issues/196124" target="_blank" rel="noopener noreferrer">', - linkEnd: '</a>', - }, - false, - ); - }, }, mounted() { this.fetchSettings().catch(() => @@ -56,7 +50,15 @@ export default { </ul> <settings-form v-if="!isDisabled" /> <gl-alert v-else :dismissible="false"> - <p v-html="notAvailableMessage"></p> + <p> + <gl-sprintf :message="$options.i18n.unavailableFeatureText"> + <template #link="{content}"> + <gl-link href="https://gitlab.com/gitlab-org/gitlab/issues/196124" target="_blank"> + {{ content }} + </gl-link> + </template> + </gl-sprintf> + </p> </gl-alert> </div> </template> diff --git a/app/assets/javascripts/registry/shared/components/expiration_policy_fields.vue b/app/assets/javascripts/registry/shared/components/expiration_policy_fields.vue index a15b854cb9b..3e212f09e35 100644 --- a/app/assets/javascripts/registry/shared/components/expiration_policy_fields.vue +++ b/app/assets/javascripts/registry/shared/components/expiration_policy_fields.vue @@ -1,7 +1,7 @@ <script> import { uniqueId } from 'lodash'; -import { GlFormGroup, GlToggle, GlFormSelect, GlFormTextarea } from '@gitlab/ui'; -import { s__, __, sprintf } from '~/locale'; +import { GlFormGroup, GlToggle, GlFormSelect, GlFormTextarea, GlSprintf } from '@gitlab/ui'; +import { s__, __ } from '~/locale'; import { NAME_REGEX_LENGTH } from '../constants'; import { mapComputedToEvent } from '../utils'; @@ -11,6 +11,7 @@ export default { GlToggle, GlFormSelect, GlFormTextarea, + GlSprintf, }, props: { formOptions: { @@ -70,27 +71,6 @@ export default { policyEnabledText() { return this.enabled ? __('enabled') : __('disabled'); }, - toggleDescriptionText() { - return sprintf( - s__('ContainerRegistry|Docker tag expiration policy is %{toggleStatus}'), - { - toggleStatus: `<strong>${this.policyEnabledText}</strong>`, - }, - false, - ); - }, - regexHelpText() { - return sprintf( - s__( - 'ContainerRegistry|Wildcards such as %{codeStart}.*-stable%{codeEnd} or %{codeStart}production/.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}', - ), - { - codeStart: '<code>', - codeEnd: '</code>', - }, - false, - ); - }, nameRegexState() { return this.name_regex ? this.name_regex.length <= NAME_REGEX_LENGTH : null; }, @@ -139,7 +119,15 @@ export default { v-model="enabled" :disabled="isLoading" /> - <span class="mb-2 ml-1 lh-2" v-html="toggleDescriptionText"></span> + <span class="mb-2 ml-1 lh-2"> + <gl-sprintf + :message="s__('ContainerRegistry|Docker tag expiration policy is %{toggleStatus}')" + > + <template #toggleStatus> + <strong>{{ policyEnabledText }}</strong> + </template> + </gl-sprintf> + </span> </div> </gl-form-group> @@ -190,7 +178,19 @@ export default { trim /> <template #description> - <span ref="regex-description" v-html="regexHelpText"></span> + <span ref="regex-description"> + <gl-sprintf + :message=" + s__( + 'ContainerRegistry|Wildcards such as %{codeStart}.*-stable%{codeEnd} or %{codeStart}production/.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}', + ) + " + > + <template #code="{content}"> + <code>{{ content }}</code> + </template> + </gl-sprintf> + </span> </template> </gl-form-group> </div> diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb index 35f803302eb..b14a1179d46 100644 --- a/app/controllers/projects/issues_controller.rb +++ b/app/controllers/projects/issues_controller.rb @@ -44,7 +44,6 @@ class Projects::IssuesController < Projects::ApplicationController before_action do push_frontend_feature_flag(:vue_issuable_sidebar, project.group) - push_frontend_feature_flag(:issue_link_types, project) end around_action :allow_gitaly_ref_name_caching, only: [:discussions] diff --git a/app/models/diff_note.rb b/app/models/diff_note.rb index 939d8bc4bef..e3df61dadae 100644 --- a/app/models/diff_note.rb +++ b/app/models/diff_note.rb @@ -161,7 +161,7 @@ class DiffNote < Note def positions_complete return if self.original_position.complete? && self.position.complete? - errors.add(:position, "is invalid") + errors.add(:position, "is incomplete") end def keep_around_commits diff --git a/app/models/project_services/chat_message/base_message.rb b/app/models/project_services/chat_message/base_message.rb index 529af1277b0..5c39a80b32d 100644 --- a/app/models/project_services/chat_message/base_message.rb +++ b/app/models/project_services/chat_message/base_message.rb @@ -16,7 +16,7 @@ module ChatMessage def initialize(params) @markdown = params[:markdown] || false - @project_name = params.dig(:project, :path_with_namespace) || params[:project_name] + @project_name = params[:project_name] || params.dig(:project, :path_with_namespace) @project_url = params.dig(:project, :web_url) || params[:project_url] @user_full_name = params.dig(:user, :name) || params[:user_full_name] @user_name = params.dig(:user, :username) || params[:user_name] diff --git a/app/models/project_services/chat_notification_service.rb b/app/models/project_services/chat_notification_service.rb index b84a79453c1..46c8260ab48 100644 --- a/app/models/project_services/chat_notification_service.rb +++ b/app/models/project_services/chat_notification_service.rb @@ -157,7 +157,7 @@ class ChatNotificationService < Service end def project_name - project.full_name.gsub(/\s/, '') + project.full_name end def project_url diff --git a/app/views/projects/settings/operations/_incidents.html.haml b/app/views/projects/settings/operations/_incidents.html.haml index fa2f3d7dc08..756d4042613 100644 --- a/app/views/projects/settings/operations/_incidents.html.haml +++ b/app/views/projects/settings/operations/_incidents.html.haml @@ -2,7 +2,7 @@ - setting = project_incident_management_setting - templates = setting.available_issue_templates.map { |t| [t.name, t.key] } -%section.settings.no-animate.js-incident-management-settings +%section.settings.no-animate.qa-incident-management-settings .settings-header %h4= _('Incidents') %button.btn.js-settings-toggle{ type: 'button' } diff --git a/changelogs/unreleased/14544-slack-service-hook-discards-spaces.yml b/changelogs/unreleased/14544-slack-service-hook-discards-spaces.yml new file mode 100644 index 00000000000..7e02da5bc0b --- /dev/null +++ b/changelogs/unreleased/14544-slack-service-hook-discards-spaces.yml @@ -0,0 +1,5 @@ +--- +title: Do not remove space from project name in Slack +merge_request: 24851 +author: +type: fixed diff --git a/changelogs/unreleased/14707-filebeat-parse-modsec-logs-as-json.yml b/changelogs/unreleased/14707-filebeat-parse-modsec-logs-as-json.yml new file mode 100644 index 00000000000..bd6b39dd2b4 --- /dev/null +++ b/changelogs/unreleased/14707-filebeat-parse-modsec-logs-as-json.yml @@ -0,0 +1,5 @@ +--- +title: Parse filebeat modsec logs as JSON +merge_request: 24836 +author: +type: changed diff --git a/changelogs/unreleased/193075-usage-ping-timing-out-for-larger-instances-batch.yml b/changelogs/unreleased/193075-usage-ping-timing-out-for-larger-instances-batch.yml new file mode 100644 index 00000000000..83637d7f7cc --- /dev/null +++ b/changelogs/unreleased/193075-usage-ping-timing-out-for-larger-instances-batch.yml @@ -0,0 +1,5 @@ +--- +title: Fix usage ping timeouts with batch counters +merge_request: 22705 +author: +type: performance diff --git a/changelogs/unreleased/196660-replace-underscore-with-lodash-for-app-assets-javascripts-mirrors.yml b/changelogs/unreleased/196660-replace-underscore-with-lodash-for-app-assets-javascripts-mirrors.yml new file mode 100644 index 00000000000..3a3e22eefa9 --- /dev/null +++ b/changelogs/unreleased/196660-replace-underscore-with-lodash-for-app-assets-javascripts-mirrors.yml @@ -0,0 +1,5 @@ +--- +title: Replace underscore with lodash for ./app/assets/javascripts/mirrors +merge_request: 24967 +author: Jacopo Beschi @jacopo-beschi +type: changed diff --git a/changelogs/unreleased/2035-frontend-remove-feature-flag-code.yml b/changelogs/unreleased/2035-frontend-remove-feature-flag-code.yml new file mode 100644 index 00000000000..6c459708eb4 --- /dev/null +++ b/changelogs/unreleased/2035-frontend-remove-feature-flag-code.yml @@ -0,0 +1,5 @@ +--- +title: Add blocking issues feature +merge_request: 24460 +author: +type: added diff --git a/changelogs/unreleased/bump-ado-image-for-helm-values-fix.yml b/changelogs/unreleased/bump-ado-image-for-helm-values-fix.yml new file mode 100644 index 00000000000..a9825b61228 --- /dev/null +++ b/changelogs/unreleased/bump-ado-image-for-helm-values-fix.yml @@ -0,0 +1,5 @@ +--- +title: Fix overriding the image pull policy from a values file for Auto Deploy +merge_request: 25271 +author: robcalcroft +type: fixed diff --git a/changelogs/unreleased/docs-fix_default_branches_link.yml b/changelogs/unreleased/docs-fix_default_branches_link.yml new file mode 100644 index 00000000000..35350bb7351 --- /dev/null +++ b/changelogs/unreleased/docs-fix_default_branches_link.yml @@ -0,0 +1,5 @@ +--- +title: Fixed default-branch link under Pipeline Subscription settings +merge_request: 24834 +author: James Johnson +type: fixed diff --git a/changelogs/unreleased/resolve_gitlab_issue_196658.yml b/changelogs/unreleased/resolve_gitlab_issue_196658.yml new file mode 100644 index 00000000000..4c2e8f34c3f --- /dev/null +++ b/changelogs/unreleased/resolve_gitlab_issue_196658.yml @@ -0,0 +1,5 @@ +--- +title: Replace underscore with lodash for ./app/assets/javascripts/error_tracking +merge_request: 25143 +author: Tobias Spagert +type: other diff --git a/changelogs/unreleased/sh-fix-current-settings.yml b/changelogs/unreleased/sh-fix-current-settings.yml new file mode 100644 index 00000000000..001c3079a4d --- /dev/null +++ b/changelogs/unreleased/sh-fix-current-settings.yml @@ -0,0 +1,5 @@ +--- +title: Fix application settings not working with pending migrations +merge_request: +author: +type: fixed diff --git a/config/initializers/rspec_profiling.rb b/config/initializers/rspec_profiling.rb index eb0e239c18c..2473dc1ff6c 100644 --- a/config/initializers/rspec_profiling.rb +++ b/config/initializers/rspec_profiling.rb @@ -61,7 +61,7 @@ RspecProfiling.configure do |config| RspecProfiling::Run.prepend(RspecProfilingExt::Run) config.collector = RspecProfilingExt::Collectors::CSVWithTimestamps config.csv_path = -> do - prefix = "#{ENV['CI_JOB_NAME']}-".tr(' ', '-') if ENV['CI_JOB_NAME'] + prefix = "#{ENV['CI_JOB_NAME']}-".gsub(/[ \/]/, '-') if ENV['CI_JOB_NAME'] "rspec_profiling/#{prefix}#{Time.now.to_i}-#{SecureRandom.hex(8)}-rspec-data.csv" end end diff --git a/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml index f5dc83ef472..47cc6caa192 100644 --- a/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml @@ -1,5 +1,5 @@ .auto-deploy: - image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-deploy-image:v0.9.1" + image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-deploy-image:v0.9.3" review: extends: .auto-deploy diff --git a/lib/gitlab/current_settings.rb b/lib/gitlab/current_settings.rb index 6ce47650562..891fd8c1bb5 100644 --- a/lib/gitlab/current_settings.rb +++ b/lib/gitlab/current_settings.rb @@ -50,7 +50,7 @@ module Gitlab # need to be added to the application settings. To prevent Rake tasks # and other callers from failing, use any loaded settings and return # defaults for missing columns. - if ActiveRecord::Base.connection.migration_context.needs_migration? + if Gitlab::Runtime.rake? && ActiveRecord::Base.connection.migration_context.needs_migration? db_attributes = current_settings&.attributes || {} fake_application_settings(db_attributes) elsif current_settings.present? diff --git a/lib/gitlab/database/batch_count.rb b/lib/gitlab/database/batch_count.rb new file mode 100644 index 00000000000..a9d4665bc5f --- /dev/null +++ b/lib/gitlab/database/batch_count.rb @@ -0,0 +1,89 @@ +# frozen_string_literal: true + +# For large tables, PostgreSQL can take a long time to count rows due to MVCC. +# Implements a distinct and ordinary batch counter +# Needs indexes on the column below to calculate max, min and range queries +# For larger tables just set use higher batch_size with index optimization +# See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/22705 +# Examples: +# extend ::Gitlab::Database::BatchCount +# batch_count(User.active) +# batch_count(::Clusters::Cluster.aws_installed.enabled, :cluster_id) +# batch_distinct_count(::Project, :creator_id) +module Gitlab + module Database + module BatchCount + def batch_count(relation, column = nil, batch_size: nil) + BatchCounter.new(relation, column: column).count(batch_size: batch_size) + end + + def batch_distinct_count(relation, column = nil, batch_size: nil) + BatchCounter.new(relation, column: column).count(mode: :distinct, batch_size: batch_size) + end + + class << self + include BatchCount + end + end + + class BatchCounter + FALLBACK = -1 + MIN_REQUIRED_BATCH_SIZE = 2_000 + MAX_ALLOWED_LOOPS = 10_000 + SLEEP_TIME_IN_SECONDS = 0.01 # 10 msec sleep + # Each query should take <<500ms https://gitlab.com/gitlab-org/gitlab/-/merge_requests/22705 + DEFAULT_DISTINCT_BATCH_SIZE = 100_000 + DEFAULT_BATCH_SIZE = 10_000 + + def initialize(relation, column: nil) + @relation = relation + @column = column || relation.primary_key + end + + def unwanted_configuration?(finish, batch_size, start) + batch_size <= MIN_REQUIRED_BATCH_SIZE || + (finish - start) / batch_size >= MAX_ALLOWED_LOOPS || + start > finish + end + + def count(batch_size: nil, mode: :itself) + raise 'BatchCount can not be run inside a transaction' if ActiveRecord::Base.connection.transaction_open? + raise "The mode #{mode.inspect} is not supported" unless [:itself, :distinct].include?(mode) + + # non-distinct have better performance + batch_size ||= mode == :distinct ? DEFAULT_BATCH_SIZE : DEFAULT_DISTINCT_BATCH_SIZE + + start = @relation.minimum(@column) || 0 + finish = @relation.maximum(@column) || 0 + + raise "Batch counting expects positive values only for #{@column}" if start < 0 || finish < 0 + return FALLBACK if unwanted_configuration?(finish, batch_size, start) + + counter = 0 + batch_start = start + + while batch_start <= finish + begin + counter += batch_fetch(batch_start, batch_start + batch_size, mode) + batch_start += batch_size + rescue ActiveRecord::QueryCanceled + # retry with a safe batch size & warmer cache + if batch_size >= 2 * MIN_REQUIRED_BATCH_SIZE + batch_size /= 2 + else + return FALLBACK + end + end + sleep(SLEEP_TIME_IN_SECONDS) + end + + counter + end + + def batch_fetch(start, finish, mode) + # rubocop:disable GitlabSecurity/PublicSend + @relation.select(@column).public_send(mode).where(@column => start..(finish - 1)).count + end + end + end +end diff --git a/lib/gitlab/diff/diff_refs.rb b/lib/gitlab/diff/diff_refs.rb index dc245377ccc..12b93af3f26 100644 --- a/lib/gitlab/diff/diff_refs.rb +++ b/lib/gitlab/diff/diff_refs.rb @@ -37,7 +37,7 @@ module Gitlab # We have `base_sha` directly available on `DiffRefs` because it's faster# # than having to look it up in the repo every time. def complete? - start_sha && head_sha + start_sha.present? && head_sha.present? end def compare_in(project) diff --git a/lib/gitlab/diff/formatters/image_formatter.rb b/lib/gitlab/diff/formatters/image_formatter.rb index 90cd74c84bb..d0c13dee1aa 100644 --- a/lib/gitlab/diff/formatters/image_formatter.rb +++ b/lib/gitlab/diff/formatters/image_formatter.rb @@ -23,7 +23,7 @@ module Gitlab end def complete? - x && y && width && height + [x, y, width, height].all?(&:present?) end def to_h diff --git a/lib/gitlab/diff/formatters/text_formatter.rb b/lib/gitlab/diff/formatters/text_formatter.rb index f6e247ef665..5b670b1f83b 100644 --- a/lib/gitlab/diff/formatters/text_formatter.rb +++ b/lib/gitlab/diff/formatters/text_formatter.rb @@ -19,7 +19,7 @@ module Gitlab end def complete? - old_line || new_line + old_line.present? || new_line.present? end def to_h diff --git a/lib/gitlab/usage_data.rb b/lib/gitlab/usage_data.rb index 23c3259b828..6e29a3e4cc4 100644 --- a/lib/gitlab/usage_data.rb +++ b/lib/gitlab/usage_data.rb @@ -67,8 +67,8 @@ module Gitlab clusters_disabled: count(::Clusters::Cluster.disabled), project_clusters_disabled: count(::Clusters::Cluster.disabled.project_type), group_clusters_disabled: count(::Clusters::Cluster.disabled.group_type), - clusters_platforms_eks: count(::Clusters::Cluster.aws_installed.enabled), - clusters_platforms_gke: count(::Clusters::Cluster.gcp_installed.enabled), + clusters_platforms_eks: count(::Clusters::Cluster.aws_installed.enabled, batch: false), + clusters_platforms_gke: count(::Clusters::Cluster.gcp_installed.enabled, batch: false), clusters_platforms_user: count(::Clusters::Cluster.user_provided.enabled), clusters_applications_helm: count(::Clusters::Applications::Helm.available), clusters_applications_ingress: count(::Clusters::Applications::Ingress.available), @@ -85,7 +85,7 @@ module Gitlab issues: count(Issue), issues_created_from_gitlab_error_tracking_ui: count(SentryIssue), issues_with_associated_zoom_link: count(ZoomMeeting.added_to_issue), - issues_using_zoom_quick_actions: count(ZoomMeeting.select(:issue_id).distinct), + issues_using_zoom_quick_actions: count(ZoomMeeting.select(:issue_id).distinct, batch: false), issues_with_embedded_grafana_charts_approx: ::Gitlab::GrafanaEmbedUsageData.issue_count, incident_issues: count(::Issue.authored(::User.alert_bot)), keys: count(Key), @@ -99,7 +99,7 @@ module Gitlab projects_imported_from_github: count(Project.where(import_type: 'github')), projects_with_repositories_enabled: count(ProjectFeature.where('repository_access_level > ?', ProjectFeature::DISABLED)), projects_with_error_tracking_enabled: count(::ErrorTracking::ProjectErrorTrackingSetting.where(enabled: true)), - projects_with_alerts_service_enabled: count(AlertsService.active), + projects_with_alerts_service_enabled: count(AlertsService.active, batch: false), protected_branches: count(ProtectedBranch), releases: count(Release), remote_mirrors: count(RemoteMirror), @@ -181,7 +181,7 @@ module Gitlab # rubocop: disable CodeReuse/ActiveRecord def services_usage - service_counts = count(Service.active.where(template: false).where.not(type: 'JiraService').group(:type), fallback: Hash.new(-1)) + service_counts = count(Service.active.where(template: false).where.not(type: 'JiraService').group(:type), fallback: Hash.new(-1), batch: false) results = Service.available_services_names.each_with_object({}) do |service_name, response| response["projects_#{service_name}_active".to_sym] = service_counts["#{service_name}_service".camelize] || 0 @@ -217,9 +217,9 @@ module Gitlab results[:projects_jira_server_active] += counts[:server].count if counts[:server] results[:projects_jira_cloud_active] += counts[:cloud].count if counts[:cloud] if results[:projects_jira_active] == -1 - results[:projects_jira_active] = count(services) + results[:projects_jira_active] = count(services, batch: false) else - results[:projects_jira_active] += count(services) + results[:projects_jira_active] += count(services, batch: false) end end @@ -231,8 +231,22 @@ module Gitlab {} # augmented in EE end - def count(relation, fallback: -1) - relation.count + def count(relation, column = nil, fallback: -1, batch: true) + if batch && Feature.enabled?(:usage_ping_batch_counter) + Gitlab::Database::BatchCount.batch_count(relation, column) + else + relation.count + end + rescue ActiveRecord::StatementInvalid + fallback + end + + def distinct_count(relation, column = nil, fallback: -1, batch: true) + if batch && Feature.enabled?(:usage_ping_batch_counter) + Gitlab::Database::BatchCount.batch_distinct_count(relation, column) + else + relation.distinct_count_by(column) + end rescue ActiveRecord::StatementInvalid fallback end diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 187e7f2e7f7..ea0a773a525 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -15795,9 +15795,6 @@ msgstr "" msgid "Related Merged Requests" msgstr "" -msgid "Related issues" -msgstr "" - msgid "Related merge requests" msgstr "" diff --git a/spec/controllers/admin/application_settings_controller_spec.rb b/spec/controllers/admin/application_settings_controller_spec.rb index 66deb2359db..05c4743ed7f 100644 --- a/spec/controllers/admin/application_settings_controller_spec.rb +++ b/spec/controllers/admin/application_settings_controller_spec.rb @@ -16,6 +16,7 @@ describe Admin::ApplicationSettingsController do describe 'GET #usage_data with no access' do before do + allow(ActiveRecord::Base.connection).to receive(:transaction_open?).and_return(false) sign_in(user) end @@ -28,6 +29,7 @@ describe Admin::ApplicationSettingsController do describe 'GET #usage_data' do before do + allow(ActiveRecord::Base.connection).to receive(:transaction_open?).and_return(false) sign_in(admin) end diff --git a/spec/factories/diff_position.rb b/spec/factories/diff_position.rb new file mode 100644 index 00000000000..a43c5afdff4 --- /dev/null +++ b/spec/factories/diff_position.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :diff_position, class: 'Gitlab::Diff::Position' do + skip_create # non-model factories (i.e. without #save) + + transient do + file { 'path/to/file' } + + # Allow diff to be passed as a single object. + diff_refs do + ::Gitlab::Diff::DiffRefs.new( + base_sha: Digest::SHA1.hexdigest(SecureRandom.hex), + head_sha: Digest::SHA1.hexdigest(SecureRandom.hex), + start_sha: Digest::SHA1.hexdigest(SecureRandom.hex) + ) + end + end + + old_path { file } + new_path { file } + + base_sha { diff_refs&.base_sha } + head_sha { diff_refs&.head_sha } + start_sha { diff_refs&.start_sha } + + initialize_with { new(attributes) } + + trait :moved do + new_path { 'path/to/new.file' } + end + + factory :text_diff_position do + position_type { 'text' } + old_line { 10 } + new_line { 10 } + + trait :added do + old_line { nil } + end + end + + factory :image_diff_position do + position_type { 'image' } + x { 1 } + y { 1 } + width { 10 } + height { 10 } + end + end +end diff --git a/spec/factories/notes.rb b/spec/factories/notes.rb index ec89a5904f5..848590efabc 100644 --- a/spec/factories/notes.rb +++ b/spec/factories/notes.rb @@ -58,24 +58,20 @@ FactoryBot.define do end position do - Gitlab::Diff::Position.new( - old_path: "files/ruby/popen.rb", - new_path: "files/ruby/popen.rb", - old_line: nil, - new_line: line_number, - diff_refs: diff_refs - ) + build(:text_diff_position, + file: "files/ruby/popen.rb", + old_line: nil, + new_line: line_number, + diff_refs: diff_refs) end trait :folded_position do position do - Gitlab::Diff::Position.new( - old_path: "files/ruby/popen.rb", - new_path: "files/ruby/popen.rb", - old_line: 1, - new_line: 1, - diff_refs: diff_refs - ) + build(:text_diff_position, + file: "files/ruby/popen.rb", + old_line: 1, + new_line: 1, + diff_refs: diff_refs) end end @@ -86,16 +82,9 @@ FactoryBot.define do factory :image_diff_note_on_merge_request do position do - Gitlab::Diff::Position.new( - old_path: "files/images/any_image.png", - new_path: "files/images/any_image.png", - width: 10, - height: 10, - x: 1, - y: 1, - diff_refs: diff_refs, - position_type: "image" - ) + build(:image_diff_position, + file: "files/images/any_image.png", + diff_refs: diff_refs) end end end @@ -109,9 +98,8 @@ FactoryBot.define do end position do - Gitlab::Diff::Position.new( - old_path: "files/ruby/popen.rb", - new_path: "files/ruby/popen.rb", + build(:text_diff_position, + file: "files/ruby/popen.rb", old_line: nil, new_line: line_number, diff_refs: diff_refs diff --git a/spec/features/admin/admin_settings_spec.rb b/spec/features/admin/admin_settings_spec.rb index 7bc904be69d..9b275a8897b 100644 --- a/spec/features/admin/admin_settings_spec.rb +++ b/spec/features/admin/admin_settings_spec.rb @@ -326,6 +326,8 @@ describe 'Admin updates settings', :clean_gitlab_redis_shared_state, :do_not_moc end it 'loads usage ping payload on click', :js do + allow(ActiveRecord::Base.connection).to receive(:transaction_open?).and_return(false) + expect(page).to have_button 'Preview payload' find('.js-usage-ping-payload-trigger').click diff --git a/spec/features/merge_request/user_creates_image_diff_notes_spec.rb b/spec/features/merge_request/user_creates_image_diff_notes_spec.rb index e0724a04ea3..e1b139c1b3b 100644 --- a/spec/features/merge_request/user_creates_image_diff_notes_spec.rb +++ b/spec/features/merge_request/user_creates_image_diff_notes_spec.rb @@ -48,29 +48,11 @@ describe 'Merge request > User creates image diff notes', :js do let(:commit) { project.commit('2f63565e7aac07bcdadb654e253078b727143ec4') } let(:note1_position) do - Gitlab::Diff::Position.new( - old_path: path, - new_path: path, - width: 100, - height: 100, - x: 10, - y: 10, - position_type: "image", - diff_refs: commit.diff_refs - ) + build(:image_diff_position, file: path, diff_refs: commit.diff_refs) end let(:note2_position) do - Gitlab::Diff::Position.new( - old_path: path, - new_path: path, - width: 100, - height: 100, - x: 20, - y: 20, - position_type: "image", - diff_refs: commit.diff_refs - ) + build(:image_diff_position, file: path, diff_refs: commit.diff_refs) end let!(:note1) { create(:diff_note_on_commit, commit_id: commit.id, project: project, position: note1_position, note: 'my note 1') } @@ -93,16 +75,7 @@ describe 'Merge request > User creates image diff notes', :js do %w(inline parallel).each do |view| context "#{view} view" do let(:position) do - Gitlab::Diff::Position.new( - old_path: path, - new_path: path, - width: 100, - height: 100, - x: 1, - y: 1, - position_type: "image", - diff_refs: merge_request.diff_refs - ) + build(:image_diff_position, file: path, diff_refs: merge_request.diff_refs) end let!(:note) { create(:diff_note_on_merge_request, project: project, noteable: merge_request, position: position) } @@ -167,16 +140,7 @@ describe 'Merge request > User creates image diff notes', :js do let(:path) { "files/images/ee_repo_logo.png" } let(:position) do - Gitlab::Diff::Position.new( - old_path: path, - new_path: path, - width: 100, - height: 100, - x: 50, - y: 50, - position_type: "image", - diff_refs: merge_request.diff_refs - ) + build(:image_diff_position, file: path, diff_refs: merge_request.diff_refs) end before do diff --git a/spec/features/merge_request/user_resolves_diff_notes_and_discussions_resolve_spec.rb b/spec/features/merge_request/user_resolves_diff_notes_and_discussions_resolve_spec.rb index 5a7edd37182..38a31d3bbd9 100644 --- a/spec/features/merge_request/user_resolves_diff_notes_and_discussions_resolve_spec.rb +++ b/spec/features/merge_request/user_resolves_diff_notes_and_discussions_resolve_spec.rb @@ -10,13 +10,9 @@ describe 'Merge request > User resolves diff notes and threads', :js do let!(:note) { create(:diff_note_on_merge_request, project: project, noteable: merge_request, note: "| Markdown | Table |\n|-------|---------|\n| first | second |") } let(:path) { "files/ruby/popen.rb" } let(:position) do - Gitlab::Diff::Position.new( - old_path: path, - new_path: path, - old_line: nil, - new_line: 9, - diff_refs: merge_request.diff_refs - ) + build(:text_diff_position, + file: path, old_line: nil, new_line: 9, + diff_refs: merge_request.diff_refs) end before do diff --git a/spec/features/merge_request/user_resolves_outdated_diff_discussions_spec.rb b/spec/features/merge_request/user_resolves_outdated_diff_discussions_spec.rb index b40c11f0d47..9f7c97e510c 100644 --- a/spec/features/merge_request/user_resolves_outdated_diff_discussions_spec.rb +++ b/spec/features/merge_request/user_resolves_outdated_diff_discussions_spec.rb @@ -13,20 +13,16 @@ describe 'Merge request > User resolves outdated diff discussions', :js do let(:current_diff_refs) { merge_request.diff_refs } let(:outdated_position) do - Gitlab::Diff::Position.new( - old_path: 'files/csv/Book1.csv', - new_path: 'files/csv/Book1.csv', - old_line: nil, + build(:text_diff_position, :added, + file: 'files/csv/Book1.csv', new_line: 9, diff_refs: outdated_diff_refs ) end let(:current_position) do - Gitlab::Diff::Position.new( - old_path: 'files/csv/Book1.csv', - new_path: 'files/csv/Book1.csv', - old_line: nil, + build(:text_diff_position, :added, + file: 'files/csv/Book1.csv', new_line: 1, diff_refs: current_diff_refs ) diff --git a/spec/features/merge_request/user_sees_avatar_on_diff_notes_spec.rb b/spec/features/merge_request/user_sees_avatar_on_diff_notes_spec.rb index 3e77b9e75d6..c482d783bab 100644 --- a/spec/features/merge_request/user_sees_avatar_on_diff_notes_spec.rb +++ b/spec/features/merge_request/user_sees_avatar_on_diff_notes_spec.rb @@ -10,10 +10,8 @@ describe 'Merge request > User sees avatars on diff notes', :js do let(:merge_request) { create(:merge_request_with_diffs, source_project: project, author: user, title: 'Bug NS-04') } let(:path) { 'files/ruby/popen.rb' } let(:position) do - Gitlab::Diff::Position.new( - old_path: path, - new_path: path, - old_line: nil, + build(:text_diff_position, :added, + file: path, new_line: 9, diff_refs: merge_request.diff_refs ) diff --git a/spec/features/merge_request/user_sees_discussions_spec.rb b/spec/features/merge_request/user_sees_discussions_spec.rb index 319eee0c55a..b4afd8c6332 100644 --- a/spec/features/merge_request/user_sees_discussions_spec.rb +++ b/spec/features/merge_request/user_sees_discussions_spec.rb @@ -18,10 +18,8 @@ describe 'Merge request > User sees threads', :js do let!(:outdated_discussion) { create(:diff_note_on_merge_request, project: project, noteable: merge_request, position: outdated_position).to_discussion } let!(:active_discussion) { create(:diff_note_on_merge_request, noteable: merge_request, project: project).to_discussion } let(:outdated_position) do - Gitlab::Diff::Position.new( - old_path: "files/ruby/popen.rb", - new_path: "files/ruby/popen.rb", - old_line: nil, + build(:text_diff_position, :added, + file: "files/ruby/popen.rb", new_line: 9, diff_refs: outdated_diff_refs ) diff --git a/spec/features/merge_request/user_sees_versions_spec.rb b/spec/features/merge_request/user_sees_versions_spec.rb index cd62bab412a..5b43fe407eb 100644 --- a/spec/features/merge_request/user_sees_versions_spec.rb +++ b/spec/features/merge_request/user_sees_versions_spec.rb @@ -86,10 +86,8 @@ describe 'Merge request > User sees versions', :js do it 'shows comments that were last relevant at that version' do expect(page).to have_content '5 files' - position = Gitlab::Diff::Position.new( - old_path: ".gitmodules", - new_path: ".gitmodules", - old_line: nil, + position = build(:text_diff_position, :added, + file: ".gitmodules", new_line: 4, diff_refs: merge_request_diff1.diff_refs ) @@ -136,9 +134,8 @@ describe 'Merge request > User sees versions', :js do expect(additions_content).to eq '15' expect(deletions_content).to eq '6' - position = Gitlab::Diff::Position.new( - old_path: ".gitmodules", - new_path: ".gitmodules", + position = build(:text_diff_position, + file: ".gitmodules", old_line: 4, new_line: 4, diff_refs: merge_request_diff3.compare_with(merge_request_diff1.head_commit_sha).diff_refs diff --git a/spec/features/projects/settings/operations_settings_spec.rb b/spec/features/projects/settings/operations_settings_spec.rb index 0181ceed5b9..d57401471ff 100644 --- a/spec/features/projects/settings/operations_settings_spec.rb +++ b/spec/features/projects/settings/operations_settings_spec.rb @@ -58,7 +58,7 @@ describe 'Projects > Settings > For a forked project', :js do end def click_expand_incident_management_button - within '.js-incident-management-settings' do + within '.qa-incident-management-settings' do click_button('Expand') end end diff --git a/spec/frontend/fixtures/merge_requests.rb b/spec/frontend/fixtures/merge_requests.rb index f20c0aa3540..4f004a69265 100644 --- a/spec/frontend/fixtures/merge_requests.rb +++ b/spec/frontend/fixtures/merge_requests.rb @@ -36,10 +36,8 @@ describe Projects::MergeRequestsController, '(JavaScript fixtures)', type: :cont end let(:path) { "files/ruby/popen.rb" } let(:position) do - Gitlab::Diff::Position.new( - old_path: path, - new_path: path, - old_line: nil, + build(:text_diff_position, :added, + file: path, new_line: 14, diff_refs: merge_request.diff_refs ) @@ -112,14 +110,8 @@ describe Projects::MergeRequestsController, '(JavaScript fixtures)', type: :cont let(:merge_request2) { create(:merge_request_with_diffs, :with_image_diffs, source_project: project, title: "Added images") } let(:image_path) { "files/images/ee_repo_logo.png" } let(:image_position) do - Gitlab::Diff::Position.new( - old_path: image_path, - new_path: image_path, - width: 100, - height: 100, - x: 1, - y: 1, - position_type: "image", + build(:image_diff_position, + file: image_path, diff_refs: merge_request2.diff_refs ) end diff --git a/spec/frontend/fixtures/merge_requests_diffs.rb b/spec/frontend/fixtures/merge_requests_diffs.rb index 9493cba03bb..7997ee79a01 100644 --- a/spec/frontend/fixtures/merge_requests_diffs.rb +++ b/spec/frontend/fixtures/merge_requests_diffs.rb @@ -12,10 +12,8 @@ describe Projects::MergeRequests::DiffsController, '(JavaScript fixtures)', type let(:path) { "files/ruby/popen.rb" } let(:selected_commit) { merge_request.all_commits[0] } let(:position) do - Gitlab::Diff::Position.new( - old_path: path, - new_path: path, - old_line: nil, + build(:text_diff_position, :added, + file: path, new_line: 14, diff_refs: merge_request.diff_refs ) diff --git a/spec/frontend/registry/shared/components/__snapshots__/expiration_policy_fields_spec.js.snap b/spec/frontend/registry/shared/components/__snapshots__/expiration_policy_fields_spec.js.snap index 687ff709fd7..6e7bc0491ce 100644 --- a/spec/frontend/registry/shared/components/__snapshots__/expiration_policy_fields_spec.js.snap +++ b/spec/frontend/registry/shared/components/__snapshots__/expiration_policy_fields_spec.js.snap @@ -4,7 +4,7 @@ exports[`Expiration Policy Form renders 1`] = ` <div class="lh-2" > - <glformgroup-stub + <gl-form-group-stub id="expiration-policy-toggle-group" label="Expiration policy:" label-align="right" @@ -14,7 +14,7 @@ exports[`Expiration Policy Form renders 1`] = ` <div class="d-flex align-items-start" > - <gltoggle-stub + <gl-toggle-stub id="expiration-policy-toggle" labeloff="Toggle Status: OFF" labelon="Toggle Status: ON" @@ -30,16 +30,16 @@ exports[`Expiration Policy Form renders 1`] = ` </strong> </span> </div> - </glformgroup-stub> + </gl-form-group-stub> - <glformgroup-stub + <gl-form-group-stub id="expiration-policy-interval-group" label="Expiration interval:" label-align="right" label-cols="3" label-for="expiration-policy-interval" > - <glformselect-stub + <gl-form-select-stub disabled="true" id="expiration-policy-interval" > @@ -57,16 +57,16 @@ exports[`Expiration Policy Form renders 1`] = ` Bar </option> - </glformselect-stub> - </glformgroup-stub> - <glformgroup-stub + </gl-form-select-stub> + </gl-form-group-stub> + <gl-form-group-stub id="expiration-policy-schedule-group" label="Expiration schedule:" label-align="right" label-cols="3" label-for="expiration-policy-schedule" > - <glformselect-stub + <gl-form-select-stub disabled="true" id="expiration-policy-schedule" > @@ -84,16 +84,16 @@ exports[`Expiration Policy Form renders 1`] = ` Bar </option> - </glformselect-stub> - </glformgroup-stub> - <glformgroup-stub + </gl-form-select-stub> + </gl-form-group-stub> + <gl-form-group-stub id="expiration-policy-latest-group" label="Number of tags to retain:" label-align="right" label-cols="3" label-for="expiration-policy-latest" > - <glformselect-stub + <gl-form-select-stub disabled="true" id="expiration-policy-latest" > @@ -111,10 +111,10 @@ exports[`Expiration Policy Form renders 1`] = ` Bar </option> - </glformselect-stub> - </glformgroup-stub> + </gl-form-select-stub> + </gl-form-group-stub> - <glformgroup-stub + <gl-form-group-stub id="expiration-policy-name-matching-group" invalid-feedback="The value of this input should be less than 255 characters" label="Docker tags with names matching this regex pattern will expire:" @@ -122,13 +122,13 @@ exports[`Expiration Policy Form renders 1`] = ` label-cols="3" label-for="expiration-policy-name-matching" > - <glformtextarea-stub + <gl-form-textarea-stub disabled="true" id="expiration-policy-name-matching" placeholder=".*" trim="" value="" /> - </glformgroup-stub> + </gl-form-group-stub> </div> `; diff --git a/spec/frontend/registry/shared/components/expiration_policy_fields_spec.js b/spec/frontend/registry/shared/components/expiration_policy_fields_spec.js index b384fd62406..3782bfeaac4 100644 --- a/spec/frontend/registry/shared/components/expiration_policy_fields_spec.js +++ b/spec/frontend/registry/shared/components/expiration_policy_fields_spec.js @@ -1,5 +1,5 @@ -import { mount } from '@vue/test-utils'; -import stubChildren from 'helpers/stub_children'; +import { shallowMount } from '@vue/test-utils'; +import { GlSprintf } from '@gitlab/ui'; import component from '~/registry/shared/components/expiration_policy_fields.vue'; import { NAME_REGEX_LENGTH } from '~/registry/shared/constants'; @@ -15,9 +15,9 @@ describe('Expiration Policy Form', () => { parent.find(`${FORM_ELEMENTS_ID_PREFIX}-${name}`); const mountComponent = props => { - wrapper = mount(component, { + wrapper = shallowMount(component, { stubs: { - ...stubChildren(component), + GlSprintf, }, propsData: { formOptions, diff --git a/spec/helpers/notes_helper_spec.rb b/spec/helpers/notes_helper_spec.rb index 2da7717ebfc..1dc7f4e98ab 100644 --- a/spec/helpers/notes_helper_spec.rb +++ b/spec/helpers/notes_helper_spec.rb @@ -62,10 +62,8 @@ describe NotesHelper do context 'when the discussion is on an older merge request version' do let(:position) do - Gitlab::Diff::Position.new( - old_path: ".gitmodules", - new_path: ".gitmodules", - old_line: nil, + build(:text_diff_position, :added, + file: ".gitmodules", new_line: 4, diff_refs: merge_request_diff1.diff_refs ) @@ -86,9 +84,8 @@ describe NotesHelper do context 'when the discussion is on a comparison between merge request versions' do let(:position) do - Gitlab::Diff::Position.new( - old_path: ".gitmodules", - new_path: ".gitmodules", + build(:text_diff_position, + file: ".gitmodules", old_line: 4, new_line: 4, diff_refs: merge_request_diff3.compare_with(merge_request_diff1.head_commit_sha).diff_refs diff --git a/spec/lib/gitlab/current_settings_spec.rb b/spec/lib/gitlab/current_settings_spec.rb index eced96a4c77..adbd7eabd18 100644 --- a/spec/lib/gitlab/current_settings_spec.rb +++ b/spec/lib/gitlab/current_settings_spec.rb @@ -120,17 +120,13 @@ describe Gitlab::CurrentSettings do end context 'with pending migrations' do + let(:current_settings) { described_class.current_application_settings } + before do - expect_any_instance_of(ActiveRecord::MigrationContext).to receive(:needs_migration?).and_return(true) + allow(Gitlab::Runtime).to receive(:rake?).and_return(false) end shared_examples 'a non-persisted ApplicationSetting object' do - let(:current_settings) { described_class.current_application_settings } - - it 'returns a FakeApplicationSettings object' do - expect(current_settings).to be_a(Gitlab::FakeApplicationSettings) - end - it 'uses the default value from ApplicationSetting.defaults' do expect(current_settings.signup_enabled).to eq(ApplicationSetting.defaults[:signup_enabled]) end @@ -144,18 +140,16 @@ describe Gitlab::CurrentSettings do end end - context 'with no ApplicationSetting DB record' do - it_behaves_like 'a non-persisted ApplicationSetting object' - end - - context 'with an existing ApplicationSetting DB record' do - let!(:db_settings) { ApplicationSetting.build_from_defaults(home_page_url: 'http://mydomain.com').save! && ApplicationSetting.last } - let(:current_settings) { described_class.current_application_settings } + context 'in a Rake task' do + before do + allow(Gitlab::Runtime).to receive(:rake?).and_return(true) + expect_any_instance_of(ActiveRecord::MigrationContext).to receive(:needs_migration?).and_return(true) + end it_behaves_like 'a non-persisted ApplicationSetting object' - it 'uses the value from the DB attribute if present and not overridden by an accessor' do - expect(current_settings.home_page_url).to eq(db_settings.home_page_url) + it 'returns a FakeApplicationSettings object' do + expect(current_settings).to be_a(Gitlab::FakeApplicationSettings) end context 'when a new column is used before being migrated' do @@ -168,6 +162,20 @@ describe Gitlab::CurrentSettings do end end end + + context 'with no ApplicationSetting DB record' do + it_behaves_like 'a non-persisted ApplicationSetting object' + end + + context 'with an existing ApplicationSetting DB record' do + let!(:db_settings) { ApplicationSetting.build_from_defaults(home_page_url: 'http://mydomain.com').save! && ApplicationSetting.last } + + it_behaves_like 'a non-persisted ApplicationSetting object' + + it 'uses the value from the DB attribute if present and not overridden by an accessor' do + expect(current_settings.home_page_url).to eq(db_settings.home_page_url) + end + end end context 'when ApplicationSettings.current is present' do diff --git a/spec/lib/gitlab/database/batch_count_spec.rb b/spec/lib/gitlab/database/batch_count_spec.rb new file mode 100644 index 00000000000..0731791d9b0 --- /dev/null +++ b/spec/lib/gitlab/database/batch_count_spec.rb @@ -0,0 +1,94 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::Database::BatchCount do + let(:model) { Issue } + let(:column) { :author_id } + + let(:in_transaction) { false } + let(:user) { create(:user) } + let(:another_user) { create(:user) } + + before do + create_list(:issue, 3, author: user ) + create_list(:issue, 2, author: another_user ) + allow(ActiveRecord::Base.connection).to receive(:transaction_open?).and_return(in_transaction) + end + + describe '#batch_count' do + it 'counts table' do + expect(described_class.batch_count(model)).to eq(5) + end + + it 'counts with :id field' do + expect(described_class.batch_count(model, :id)).to eq(5) + end + + it 'counts with "id" field' do + expect(described_class.batch_count(model, 'id')).to eq(5) + end + + it 'counts with table.id field' do + expect(described_class.batch_count(model, "#{model.table_name}.id")).to eq(5) + end + + it 'counts table with batch_size 50K' do + expect(described_class.batch_count(model, batch_size: 50_000)).to eq(5) + end + + it 'will not count table with batch_size 1K' do + fallback = ::Gitlab::Database::BatchCounter::FALLBACK + expect(described_class.batch_count(model, batch_size: fallback / 2)).to eq(fallback) + end + + it 'counts with a small edge case batch_sizes than result' do + stub_const('Gitlab::Database::BatchCounter::MIN_REQUIRED_BATCH_SIZE', 0) + + [1, 2, 4, 5, 6].each { |i| expect(described_class.batch_count(model, batch_size: i)).to eq(5) } + end + + context 'in a transaction' do + let(:in_transaction) { true } + + it 'cannot count' do + expect do + described_class.batch_count(model) + end.to raise_error 'BatchCount can not be run inside a transaction' + end + end + end + + describe '#batch_distinct_count' do + it 'counts with :id field' do + expect(described_class.batch_distinct_count(model, :id)).to eq(5) + end + + it 'counts with column field' do + expect(described_class.batch_distinct_count(model, column)).to eq(2) + end + + it 'counts with "id" field' do + expect(described_class.batch_distinct_count(model, "#{column}")).to eq(2) + end + + it 'counts with table.column field' do + expect(described_class.batch_distinct_count(model, "#{model.table_name}.#{column}")).to eq(2) + end + + it 'counts with :column field with batch_size of 50K' do + expect(described_class.batch_distinct_count(model, column, batch_size: 50_000)).to eq(2) + end + + it 'will not count table with batch_size 1K' do + fallback = ::Gitlab::Database::BatchCounter::FALLBACK + expect(described_class.batch_distinct_count(model, column, batch_size: fallback / 2)).to eq(fallback) + end + + it 'counts with a small edge case batch_sizes than result' do + stub_const('Gitlab::Database::BatchCounter::MIN_REQUIRED_BATCH_SIZE', 0) + + [1, 2, 4, 5, 6].each { |i| expect(described_class.batch_distinct_count(model, column, batch_size: i)).to eq(2) } + end + end +end diff --git a/spec/lib/gitlab/diff/lines_unfolder_spec.rb b/spec/lib/gitlab/diff/lines_unfolder_spec.rb index 3134ff3d817..ebcbe1fb1a0 100644 --- a/spec/lib/gitlab/diff/lines_unfolder_spec.rb +++ b/spec/lib/gitlab/diff/lines_unfolder_spec.rb @@ -212,14 +212,7 @@ describe Gitlab::Diff::LinesUnfolder do context 'position requires a middle expansion and new match lines' do let(:position) do - Gitlab::Diff::Position.new(base_sha: "1c59dfa64afbea8c721bb09a06a9d326c952ea19", - start_sha: "1c59dfa64afbea8c721bb09a06a9d326c952ea19", - head_sha: "1487062132228de836236c522fe52fed4980a46c", - old_path: "build-aux/flatpak/org.gnome.Nautilus.json", - new_path: "build-aux/flatpak/org.gnome.Nautilus.json", - position_type: "text", - old_line: 43, - new_line: 40) + build(:text_diff_position, old_line: 43, new_line: 40) end context 'blob lines' do @@ -321,14 +314,7 @@ describe Gitlab::Diff::LinesUnfolder do context 'position requires a middle expansion and no top match line' do let(:position) do - Gitlab::Diff::Position.new(base_sha: "1c59dfa64afbea8c721bb09a06a9d326c952ea19", - start_sha: "1c59dfa64afbea8c721bb09a06a9d326c952ea19", - head_sha: "1487062132228de836236c522fe52fed4980a46c", - old_path: "build-aux/flatpak/org.gnome.Nautilus.json", - new_path: "build-aux/flatpak/org.gnome.Nautilus.json", - position_type: "text", - old_line: 16, - new_line: 17) + build(:text_diff_position, old_line: 16, new_line: 17) end context 'blob lines' do @@ -422,14 +408,7 @@ describe Gitlab::Diff::LinesUnfolder do context 'position requires a middle expansion and no bottom match line' do let(:position) do - Gitlab::Diff::Position.new(base_sha: "1c59dfa64afbea8c721bb09a06a9d326c952ea19", - start_sha: "1c59dfa64afbea8c721bb09a06a9d326c952ea19", - head_sha: "1487062132228de836236c522fe52fed4980a46c", - old_path: "build-aux/flatpak/org.gnome.Nautilus.json", - new_path: "build-aux/flatpak/org.gnome.Nautilus.json", - position_type: "text", - old_line: 82, - new_line: 79) + build(:text_diff_position, old_line: 82, new_line: 79) end context 'blob lines' do @@ -523,14 +502,7 @@ describe Gitlab::Diff::LinesUnfolder do context 'position requires a short top expansion' do let(:position) do - Gitlab::Diff::Position.new(base_sha: "1c59dfa64afbea8c721bb09a06a9d326c952ea19", - start_sha: "1c59dfa64afbea8c721bb09a06a9d326c952ea19", - head_sha: "1487062132228de836236c522fe52fed4980a46c", - old_path: "build-aux/flatpak/org.gnome.Nautilus.json", - new_path: "build-aux/flatpak/org.gnome.Nautilus.json", - position_type: "text", - old_line: 6, - new_line: 6) + build(:text_diff_position, old_line: 6, new_line: 6) end context 'blob lines' do @@ -621,14 +593,7 @@ describe Gitlab::Diff::LinesUnfolder do context 'position sits between two match lines (no expasion needed)' do let(:position) do - Gitlab::Diff::Position.new(base_sha: "1c59dfa64afbea8c721bb09a06a9d326c952ea19", - start_sha: "1c59dfa64afbea8c721bb09a06a9d326c952ea19", - head_sha: "1487062132228de836236c522fe52fed4980a46c", - old_path: "build-aux/flatpak/org.gnome.Nautilus.json", - new_path: "build-aux/flatpak/org.gnome.Nautilus.json", - position_type: "text", - old_line: 64, - new_line: 61) + build(:text_diff_position, old_line: 64, new_line: 61) end context 'diff lines' do @@ -640,14 +605,7 @@ describe Gitlab::Diff::LinesUnfolder do context 'position requires bottom expansion and new match lines' do let(:position) do - Gitlab::Diff::Position.new(base_sha: "1c59dfa64afbea8c721bb09a06a9d326c952ea19", - start_sha: "1c59dfa64afbea8c721bb09a06a9d326c952ea19", - head_sha: "1487062132228de836236c522fe52fed4980a46c", - old_path: "build-aux/flatpak/org.gnome.Nautilus.json", - new_path: "build-aux/flatpak/org.gnome.Nautilus.json", - position_type: "text", - old_line: 107, - new_line: 99) + build(:text_diff_position, old_line: 107, new_line: 99) end context 'blob lines' do @@ -744,14 +702,7 @@ describe Gitlab::Diff::LinesUnfolder do context 'position requires bottom expansion and no new match line' do let(:position) do - Gitlab::Diff::Position.new(base_sha: "1c59dfa64afbea8c721bb09a06a9d326c952ea19", - start_sha: "1c59dfa64afbea8c721bb09a06a9d326c952ea19", - head_sha: "1487062132228de836236c522fe52fed4980a46c", - old_path: "build-aux/flatpak/org.gnome.Nautilus.json", - new_path: "build-aux/flatpak/org.gnome.Nautilus.json", - position_type: "text", - old_line: 95, - new_line: 87) + build(:text_diff_position, old_line: 95, new_line: 87) end context 'blob lines' do @@ -844,16 +795,7 @@ describe Gitlab::Diff::LinesUnfolder do end context 'positioned on an image' do - let(:position) do - Gitlab::Diff::Position.new( - base_sha: '1c59dfa64afbea8c721bb09a06a9d326c952ea19', - start_sha: '1c59dfa64afbea8c721bb09a06a9d326c952ea19', - head_sha: '1487062132228de836236c522fe52fed4980a46c', - old_path: 'image.jpg', - new_path: 'image.jpg', - position_type: 'image' - ) - end + let(:position) { build(:image_diff_position) } before do allow(old_blob).to receive(:binary?).and_return(binary?) diff --git a/spec/lib/gitlab/diff/position_collection_spec.rb b/spec/lib/gitlab/diff/position_collection_spec.rb index f2a8312587c..dd8434ab10b 100644 --- a/spec/lib/gitlab/diff/position_collection_spec.rb +++ b/spec/lib/gitlab/diff/position_collection_spec.rb @@ -5,36 +5,17 @@ require 'spec_helper' describe Gitlab::Diff::PositionCollection do let(:merge_request) { build(:merge_request) } - def build_text_position(attrs = {}) - attributes = { - old_path: "files/ruby/popen.rb", - new_path: "files/ruby/popen.rb", - old_line: nil, - new_line: 14, - diff_refs: merge_request.diff_refs - }.merge(attrs) - - Gitlab::Diff::Position.new(attributes) + let(:text_position) do + build(:text_diff_position, :added, diff_refs: diff_refs) end - - def build_image_position(attrs = {}) - attributes = { - old_path: "files/images/any_image.png", - new_path: "files/images/any_image.png", - width: 10, - height: 10, - x: 1, - y: 1, - diff_refs: merge_request.diff_refs, - position_type: "image" - }.merge(attrs) - - Gitlab::Diff::Position.new(attributes) + let(:folded_text_position) do + build(:text_diff_position, diff_refs: diff_refs, old_line: 1, new_line: 1) + end + let(:image_position) do + build(:image_diff_position, diff_refs: diff_refs) end - let(:text_position) { build_text_position } - let(:folded_text_position) { build_text_position(old_line: 1, new_line: 1) } - let(:image_position) { build_image_position } + let(:diff_refs) { merge_request.diff_refs } let(:invalid_position) { 'a position' } let(:head_sha) { merge_request.diff_head_sha } @@ -71,7 +52,9 @@ describe Gitlab::Diff::PositionCollection do end describe '#concat' do - let(:new_text_position) { build_text_position(old_line: 1, new_line: 1) } + let(:new_text_position) do + build(:text_diff_position, diff_refs: diff_refs, old_line: 1, new_line: 1) + end it 'returns a Gitlab::Diff::Position' do expect(collection.concat([new_text_position])).to be_a(described_class) diff --git a/spec/lib/gitlab/diff/position_spec.rb b/spec/lib/gitlab/diff/position_spec.rb index 839780b53fe..4b11ff16c38 100644 --- a/spec/lib/gitlab/diff/position_spec.rb +++ b/spec/lib/gitlab/diff/position_spec.rb @@ -35,6 +35,32 @@ describe Gitlab::Diff::Position do } end + describe 'factory' do + it 'produces a complete text position' do + position = build(:text_diff_position) + + expect(position).to be_complete + expect(position).to have_attributes(position_type: 'text') + end + + it 'produces a complete image position' do + position = build(:image_diff_position) + + expect(position).to be_complete + expect(position).to have_attributes(position_type: 'image') + end + + it 'allows the diff_refs to be passed as a single object' do + head_sha = Digest::SHA1.hexdigest(SecureRandom.hex) + base_sha = Digest::SHA1.hexdigest(SecureRandom.hex) + start_sha = Digest::SHA1.hexdigest(SecureRandom.hex) + + refs = ::Gitlab::Diff::DiffRefs.new(base_sha: base_sha, start_sha: start_sha, head_sha: head_sha) + + expect(build(:diff_position, diff_refs: refs).diff_refs).to eq(refs) + end + end + describe "position for an added text file" do let(:commit) { project.commit("2ea1f3dec713d940208fb5ce4a38765ecb5d3f73") } diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb index 3f7e412e80b..b50481a85cd 100644 --- a/spec/lib/gitlab/usage_data_spec.rb +++ b/spec/lib/gitlab/usage_data_spec.rb @@ -6,381 +6,392 @@ describe Gitlab::UsageData do let(:projects) { create_list(:project, 4) } let!(:board) { create(:board, project: projects[0]) } - describe '#data' do - before do - create(:jira_service, project: projects[0]) - create(:jira_service, :without_properties_callback, project: projects[1]) - create(:jira_service, :jira_cloud_service, project: projects[2]) - create(:jira_service, :without_properties_callback, project: projects[3], - properties: { url: 'https://mysite.atlassian.net' }) - create(:prometheus_service, project: projects[1]) - create(:service, project: projects[0], type: 'SlackSlashCommandsService', active: true) - create(:service, project: projects[1], type: 'SlackService', active: true) - create(:service, project: projects[2], type: 'SlackService', active: true) - create(:service, project: projects[2], type: 'MattermostService', active: false) - create(:service, project: projects[2], type: 'MattermostService', active: true, template: true) - create(:service, project: projects[2], type: 'CustomIssueTrackerService', active: true) - create(:project_error_tracking_setting, project: projects[0]) - create(:project_error_tracking_setting, project: projects[1], enabled: false) - create(:alerts_service, project: projects[0]) - create(:alerts_service, :inactive, project: projects[1]) - create_list(:issue, 2, project: projects[0], author: User.alert_bot) - create_list(:issue, 2, project: projects[1], author: User.alert_bot) - create_list(:issue, 4, project: projects[0]) - create(:zoom_meeting, project: projects[0], issue: projects[0].issues[0], issue_status: :added) - create_list(:zoom_meeting, 2, project: projects[0], issue: projects[0].issues[1], issue_status: :removed) - create(:zoom_meeting, project: projects[0], issue: projects[0].issues[2], issue_status: :added) - create_list(:zoom_meeting, 2, project: projects[0], issue: projects[0].issues[2], issue_status: :removed) - create(:sentry_issue, issue: projects[0].issues[0]) - - # Enabled clusters - gcp_cluster = create(:cluster_provider_gcp, :created).cluster - create(:cluster_provider_aws, :created) - create(:cluster_platform_kubernetes) - create(:cluster, :group) - - # Disabled clusters - create(:cluster, :disabled) - create(:cluster, :group, :disabled) - create(:cluster, :group, :disabled) - - # Applications - create(:clusters_applications_helm, :installed, cluster: gcp_cluster) - create(:clusters_applications_ingress, :installed, cluster: gcp_cluster) - create(:clusters_applications_cert_manager, :installed, cluster: gcp_cluster) - create(:clusters_applications_prometheus, :installed, cluster: gcp_cluster) - create(:clusters_applications_crossplane, :installed, cluster: gcp_cluster) - create(:clusters_applications_runner, :installed, cluster: gcp_cluster) - create(:clusters_applications_knative, :installed, cluster: gcp_cluster) - create(:clusters_applications_elastic_stack, :installed, cluster: gcp_cluster) - create(:clusters_applications_jupyter, :installed, cluster: gcp_cluster) - - create(:grafana_integration, project: projects[0], enabled: true) - create(:grafana_integration, project: projects[1], enabled: true) - create(:grafana_integration, project: projects[2], enabled: false) - - allow(Gitlab::GrafanaEmbedUsageData).to receive(:issue_count).and_return(2) - - ProjectFeature.first.update_attribute('repository_access_level', 0) - end - - subject { described_class.data } - - it 'gathers usage data', :aggregate_failures do - expect(subject.keys).to include(*%i( - active_user_count - counts - recorded_at - edition - version - installation_type - uuid - hostname - mattermost_enabled - signup_enabled - ldap_enabled - gravatar_enabled - omniauth_enabled - reply_by_email_enabled - container_registry_enabled - dependency_proxy_enabled - gitlab_shared_runners_enabled - gitlab_pages - git - gitaly - database - avg_cycle_analytics - influxdb_metrics_enabled - prometheus_metrics_enabled - web_ide_clientside_preview_enabled - ingress_modsecurity_enabled - )) - end - - it 'gathers usage counts' do - smau_keys = %i( - snippet_create - snippet_update - snippet_comment - merge_request_comment - merge_request_create - commit_comment - wiki_pages_create - wiki_pages_update - wiki_pages_delete - web_ide_views - web_ide_commits - web_ide_merge_requests - web_ide_previews - navbar_searches - cycle_analytics_views - productivity_analytics_views - source_code_pushes - ) - - expected_keys = %i( - assignee_lists - boards - ci_builds - ci_internal_pipelines - ci_external_pipelines - ci_pipeline_config_auto_devops - ci_pipeline_config_repository - ci_runners - ci_triggers - ci_pipeline_schedules - auto_devops_enabled - auto_devops_disabled - deploy_keys - deployments - successful_deployments - failed_deployments - environments - clusters - clusters_enabled - project_clusters_enabled - group_clusters_enabled - clusters_disabled - project_clusters_disabled - group_clusters_disabled - clusters_platforms_eks - clusters_platforms_gke - clusters_platforms_user - clusters_applications_helm - clusters_applications_ingress - clusters_applications_cert_managers - clusters_applications_prometheus - clusters_applications_crossplane - clusters_applications_runner - clusters_applications_knative - clusters_applications_elastic_stack - clusters_applications_jupyter - in_review_folder - grafana_integrated_projects - groups - issues - issues_created_from_gitlab_error_tracking_ui - issues_with_associated_zoom_link - issues_using_zoom_quick_actions - issues_with_embedded_grafana_charts_approx - incident_issues - keys - label_lists - labels - lfs_objects - merge_requests - milestone_lists - milestones - notes - pool_repositories - projects - projects_imported_from_github - projects_asana_active - projects_jira_active - projects_jira_server_active - projects_jira_cloud_active - projects_slack_notifications_active - projects_slack_slash_active - projects_slack_active - projects_slack_slash_commands_active - projects_custom_issue_tracker_active - projects_mattermost_active - projects_prometheus_active - projects_with_repositories_enabled - projects_with_error_tracking_enabled - projects_with_alerts_service_enabled - pages_domains - protected_branches - releases - remote_mirrors - snippets - suggestions - todos - uploads - web_hooks - ).push(*smau_keys) - - count_data = subject[:counts] - - expect(count_data[:boards]).to eq(1) - expect(count_data[:projects]).to eq(4) - expect(count_data.values_at(*smau_keys)).to all(be_an(Integer)) - expect(count_data.keys).to include(*expected_keys) - expect(expected_keys - count_data.keys).to be_empty - end - - it 'gathers projects data correctly', :aggregate_failures do - count_data = subject[:counts] - - expect(count_data[:projects]).to eq(4) - expect(count_data[:projects_asana_active]).to eq(0) - expect(count_data[:projects_prometheus_active]).to eq(1) - expect(count_data[:projects_jira_active]).to eq(4) - expect(count_data[:projects_jira_server_active]).to eq(2) - expect(count_data[:projects_jira_cloud_active]).to eq(2) - expect(count_data[:projects_slack_notifications_active]).to eq(2) - expect(count_data[:projects_slack_slash_active]).to eq(1) - expect(count_data[:projects_slack_active]).to eq(2) - expect(count_data[:projects_slack_slash_commands_active]).to eq(1) - expect(count_data[:projects_custom_issue_tracker_active]).to eq(1) - expect(count_data[:projects_mattermost_active]).to eq(0) - expect(count_data[:projects_with_repositories_enabled]).to eq(3) - expect(count_data[:projects_with_error_tracking_enabled]).to eq(1) - expect(count_data[:projects_with_alerts_service_enabled]).to eq(1) - expect(count_data[:issues_created_from_gitlab_error_tracking_ui]).to eq(1) - expect(count_data[:issues_with_associated_zoom_link]).to eq(2) - expect(count_data[:issues_using_zoom_quick_actions]).to eq(3) - expect(count_data[:issues_with_embedded_grafana_charts_approx]).to eq(2) - expect(count_data[:incident_issues]).to eq(4) - - expect(count_data[:clusters_enabled]).to eq(4) - expect(count_data[:project_clusters_enabled]).to eq(3) - expect(count_data[:group_clusters_enabled]).to eq(1) - expect(count_data[:clusters_disabled]).to eq(3) - expect(count_data[:project_clusters_disabled]).to eq(1) - expect(count_data[:group_clusters_disabled]).to eq(2) - expect(count_data[:group_clusters_enabled]).to eq(1) - expect(count_data[:clusters_platforms_eks]).to eq(1) - expect(count_data[:clusters_platforms_gke]).to eq(1) - expect(count_data[:clusters_platforms_user]).to eq(1) - expect(count_data[:clusters_applications_helm]).to eq(1) - expect(count_data[:clusters_applications_ingress]).to eq(1) - expect(count_data[:clusters_applications_cert_managers]).to eq(1) - expect(count_data[:clusters_applications_crossplane]).to eq(1) - expect(count_data[:clusters_applications_prometheus]).to eq(1) - expect(count_data[:clusters_applications_runner]).to eq(1) - expect(count_data[:clusters_applications_knative]).to eq(1) - expect(count_data[:clusters_applications_elastic_stack]).to eq(1) - expect(count_data[:grafana_integrated_projects]).to eq(2) - expect(count_data[:clusters_applications_jupyter]).to eq(1) - end + before do + allow(ActiveRecord::Base.connection).to receive(:transaction_open?).and_return(false) + end + [true, false].each do |usage_ping_batch_counter_on| + describe "when the feature flag usage_ping_batch_counter is set to #{usage_ping_batch_counter_on}" do + before do + stub_feature_flags(usage_ping_batch_counter: usage_ping_batch_counter_on) + end - it 'works when queries time out' do - allow_any_instance_of(ActiveRecord::Relation) - .to receive(:count).and_raise(ActiveRecord::StatementInvalid.new('')) + describe '#data' do + before do + create(:jira_service, project: projects[0]) + create(:jira_service, :without_properties_callback, project: projects[1]) + create(:jira_service, :jira_cloud_service, project: projects[2]) + create(:jira_service, :without_properties_callback, project: projects[3], + properties: { url: 'https://mysite.atlassian.net' }) + create(:prometheus_service, project: projects[1]) + create(:service, project: projects[0], type: 'SlackSlashCommandsService', active: true) + create(:service, project: projects[1], type: 'SlackService', active: true) + create(:service, project: projects[2], type: 'SlackService', active: true) + create(:service, project: projects[2], type: 'MattermostService', active: false) + create(:service, project: projects[2], type: 'MattermostService', active: true, template: true) + create(:service, project: projects[2], type: 'CustomIssueTrackerService', active: true) + create(:project_error_tracking_setting, project: projects[0]) + create(:project_error_tracking_setting, project: projects[1], enabled: false) + create(:alerts_service, project: projects[0]) + create(:alerts_service, :inactive, project: projects[1]) + create_list(:issue, 2, project: projects[0], author: User.alert_bot) + create_list(:issue, 2, project: projects[1], author: User.alert_bot) + create_list(:issue, 4, project: projects[0]) + create(:zoom_meeting, project: projects[0], issue: projects[0].issues[0], issue_status: :added) + create_list(:zoom_meeting, 2, project: projects[0], issue: projects[0].issues[1], issue_status: :removed) + create(:zoom_meeting, project: projects[0], issue: projects[0].issues[2], issue_status: :added) + create_list(:zoom_meeting, 2, project: projects[0], issue: projects[0].issues[2], issue_status: :removed) + create(:sentry_issue, issue: projects[0].issues[0]) + + # Enabled clusters + gcp_cluster = create(:cluster_provider_gcp, :created).cluster + create(:cluster_provider_aws, :created) + create(:cluster_platform_kubernetes) + create(:cluster, :group) + + # Disabled clusters + create(:cluster, :disabled) + create(:cluster, :group, :disabled) + create(:cluster, :group, :disabled) + + # Applications + create(:clusters_applications_helm, :installed, cluster: gcp_cluster) + create(:clusters_applications_ingress, :installed, cluster: gcp_cluster) + create(:clusters_applications_cert_manager, :installed, cluster: gcp_cluster) + create(:clusters_applications_prometheus, :installed, cluster: gcp_cluster) + create(:clusters_applications_crossplane, :installed, cluster: gcp_cluster) + create(:clusters_applications_runner, :installed, cluster: gcp_cluster) + create(:clusters_applications_knative, :installed, cluster: gcp_cluster) + create(:clusters_applications_elastic_stack, :installed, cluster: gcp_cluster) + create(:clusters_applications_jupyter, :installed, cluster: gcp_cluster) + + create(:grafana_integration, project: projects[0], enabled: true) + create(:grafana_integration, project: projects[1], enabled: true) + create(:grafana_integration, project: projects[2], enabled: false) + + allow(Gitlab::GrafanaEmbedUsageData).to receive(:issue_count).and_return(2) + + ProjectFeature.first.update_attribute('repository_access_level', 0) + end + + subject { described_class.data } + + it 'gathers usage data', :aggregate_failures do + expect(subject.keys).to include(*%i( + active_user_count + counts + recorded_at + edition + version + installation_type + uuid + hostname + mattermost_enabled + signup_enabled + ldap_enabled + gravatar_enabled + omniauth_enabled + reply_by_email_enabled + container_registry_enabled + dependency_proxy_enabled + gitlab_shared_runners_enabled + gitlab_pages + git + gitaly + database + avg_cycle_analytics + influxdb_metrics_enabled + prometheus_metrics_enabled + web_ide_clientside_preview_enabled + ingress_modsecurity_enabled + )) + end + + it 'gathers usage counts' do + smau_keys = %i( + snippet_create + snippet_update + snippet_comment + merge_request_comment + merge_request_create + commit_comment + wiki_pages_create + wiki_pages_update + wiki_pages_delete + web_ide_views + web_ide_commits + web_ide_merge_requests + web_ide_previews + navbar_searches + cycle_analytics_views + productivity_analytics_views + source_code_pushes + ) + + expected_keys = %i( + assignee_lists + boards + ci_builds + ci_internal_pipelines + ci_external_pipelines + ci_pipeline_config_auto_devops + ci_pipeline_config_repository + ci_runners + ci_triggers + ci_pipeline_schedules + auto_devops_enabled + auto_devops_disabled + deploy_keys + deployments + successful_deployments + failed_deployments + environments + clusters + clusters_enabled + project_clusters_enabled + group_clusters_enabled + clusters_disabled + project_clusters_disabled + group_clusters_disabled + clusters_platforms_eks + clusters_platforms_gke + clusters_platforms_user + clusters_applications_helm + clusters_applications_ingress + clusters_applications_cert_managers + clusters_applications_prometheus + clusters_applications_crossplane + clusters_applications_runner + clusters_applications_knative + clusters_applications_elastic_stack + clusters_applications_jupyter + in_review_folder + grafana_integrated_projects + groups + issues + issues_created_from_gitlab_error_tracking_ui + issues_with_associated_zoom_link + issues_using_zoom_quick_actions + issues_with_embedded_grafana_charts_approx + incident_issues + keys + label_lists + labels + lfs_objects + merge_requests + milestone_lists + milestones + notes + pool_repositories + projects + projects_imported_from_github + projects_asana_active + projects_jira_active + projects_jira_server_active + projects_jira_cloud_active + projects_slack_notifications_active + projects_slack_slash_active + projects_slack_active + projects_slack_slash_commands_active + projects_custom_issue_tracker_active + projects_mattermost_active + projects_prometheus_active + projects_with_repositories_enabled + projects_with_error_tracking_enabled + projects_with_alerts_service_enabled + pages_domains + protected_branches + releases + remote_mirrors + snippets + suggestions + todos + uploads + web_hooks + ).push(*smau_keys) + + count_data = subject[:counts] + + expect(count_data[:boards]).to eq(1) + expect(count_data[:projects]).to eq(4) + expect(count_data.values_at(*smau_keys)).to all(be_an(Integer)) + expect(count_data.keys).to include(*expected_keys) + expect(expected_keys - count_data.keys).to be_empty + end + + it 'gathers projects data correctly', :aggregate_failures do + count_data = subject[:counts] + + expect(count_data[:projects]).to eq(4) + expect(count_data[:projects_asana_active]).to eq(0) + expect(count_data[:projects_prometheus_active]).to eq(1) + expect(count_data[:projects_jira_active]).to eq(4) + expect(count_data[:projects_jira_server_active]).to eq(2) + expect(count_data[:projects_jira_cloud_active]).to eq(2) + expect(count_data[:projects_slack_notifications_active]).to eq(2) + expect(count_data[:projects_slack_slash_active]).to eq(1) + expect(count_data[:projects_slack_active]).to eq(2) + expect(count_data[:projects_slack_slash_commands_active]).to eq(1) + expect(count_data[:projects_custom_issue_tracker_active]).to eq(1) + expect(count_data[:projects_mattermost_active]).to eq(0) + expect(count_data[:projects_with_repositories_enabled]).to eq(3) + expect(count_data[:projects_with_error_tracking_enabled]).to eq(1) + expect(count_data[:projects_with_alerts_service_enabled]).to eq(1) + expect(count_data[:issues_created_from_gitlab_error_tracking_ui]).to eq(1) + expect(count_data[:issues_with_associated_zoom_link]).to eq(2) + expect(count_data[:issues_using_zoom_quick_actions]).to eq(3) + expect(count_data[:issues_with_embedded_grafana_charts_approx]).to eq(2) + expect(count_data[:incident_issues]).to eq(4) + + expect(count_data[:clusters_enabled]).to eq(4) + expect(count_data[:project_clusters_enabled]).to eq(3) + expect(count_data[:group_clusters_enabled]).to eq(1) + expect(count_data[:clusters_disabled]).to eq(3) + expect(count_data[:project_clusters_disabled]).to eq(1) + expect(count_data[:group_clusters_disabled]).to eq(2) + expect(count_data[:group_clusters_enabled]).to eq(1) + expect(count_data[:clusters_platforms_eks]).to eq(1) + expect(count_data[:clusters_platforms_gke]).to eq(1) + expect(count_data[:clusters_platforms_user]).to eq(1) + expect(count_data[:clusters_applications_helm]).to eq(1) + expect(count_data[:clusters_applications_ingress]).to eq(1) + expect(count_data[:clusters_applications_cert_managers]).to eq(1) + expect(count_data[:clusters_applications_crossplane]).to eq(1) + expect(count_data[:clusters_applications_prometheus]).to eq(1) + expect(count_data[:clusters_applications_runner]).to eq(1) + expect(count_data[:clusters_applications_knative]).to eq(1) + expect(count_data[:clusters_applications_elastic_stack]).to eq(1) + expect(count_data[:grafana_integrated_projects]).to eq(2) + expect(count_data[:clusters_applications_jupyter]).to eq(1) + end + + it 'works when queries time out' do + allow_any_instance_of(ActiveRecord::Relation) + .to receive(:count).and_raise(ActiveRecord::StatementInvalid.new('')) + + expect { subject }.not_to raise_error + end + end - expect { subject }.not_to raise_error - end - end + describe '#usage_data_counters' do + subject { described_class.usage_data_counters } - describe '#usage_data_counters' do - subject { described_class.usage_data_counters } + it { is_expected.to all(respond_to :totals) } - it { is_expected.to all(respond_to :totals) } + describe 'the results of calling #totals on all objects in the array' do + subject { described_class.usage_data_counters.map(&:totals) } - describe 'the results of calling #totals on all objects in the array' do - subject { described_class.usage_data_counters.map(&:totals) } + it { is_expected.to all(be_a Hash) } + it { is_expected.to all(have_attributes(keys: all(be_a Symbol), values: all(be_a Integer))) } + end - it { is_expected.to all(be_a Hash) } - it { is_expected.to all(have_attributes(keys: all(be_a Symbol), values: all(be_a Integer))) } - end + it 'does not have any conflicts' do + all_keys = subject.flat_map { |counter| counter.totals.keys } - it 'does not have any conflicts' do - all_keys = subject.flat_map { |counter| counter.totals.keys } + expect(all_keys.size).to eq all_keys.to_set.size + end + end - expect(all_keys.size).to eq all_keys.to_set.size - end - end + describe '#features_usage_data_ce' do + subject { described_class.features_usage_data_ce } + + it 'gathers feature usage data', :aggregate_failures do + expect(subject[:mattermost_enabled]).to eq(Gitlab.config.mattermost.enabled) + expect(subject[:signup_enabled]).to eq(Gitlab::CurrentSettings.allow_signup?) + expect(subject[:ldap_enabled]).to eq(Gitlab.config.ldap.enabled) + expect(subject[:gravatar_enabled]).to eq(Gitlab::CurrentSettings.gravatar_enabled?) + expect(subject[:omniauth_enabled]).to eq(Gitlab::Auth.omniauth_enabled?) + expect(subject[:reply_by_email_enabled]).to eq(Gitlab::IncomingEmail.enabled?) + expect(subject[:container_registry_enabled]).to eq(Gitlab.config.registry.enabled) + expect(subject[:dependency_proxy_enabled]).to eq(Gitlab.config.dependency_proxy.enabled) + expect(subject[:gitlab_shared_runners_enabled]).to eq(Gitlab.config.gitlab_ci.shared_runners_enabled) + expect(subject[:web_ide_clientside_preview_enabled]).to eq(Gitlab::CurrentSettings.web_ide_clientside_preview_enabled?) + end + end - describe '#features_usage_data_ce' do - subject { described_class.features_usage_data_ce } - - it 'gathers feature usage data', :aggregate_failures do - expect(subject[:mattermost_enabled]).to eq(Gitlab.config.mattermost.enabled) - expect(subject[:signup_enabled]).to eq(Gitlab::CurrentSettings.allow_signup?) - expect(subject[:ldap_enabled]).to eq(Gitlab.config.ldap.enabled) - expect(subject[:gravatar_enabled]).to eq(Gitlab::CurrentSettings.gravatar_enabled?) - expect(subject[:omniauth_enabled]).to eq(Gitlab::Auth.omniauth_enabled?) - expect(subject[:reply_by_email_enabled]).to eq(Gitlab::IncomingEmail.enabled?) - expect(subject[:container_registry_enabled]).to eq(Gitlab.config.registry.enabled) - expect(subject[:dependency_proxy_enabled]).to eq(Gitlab.config.dependency_proxy.enabled) - expect(subject[:gitlab_shared_runners_enabled]).to eq(Gitlab.config.gitlab_ci.shared_runners_enabled) - expect(subject[:web_ide_clientside_preview_enabled]).to eq(Gitlab::CurrentSettings.web_ide_clientside_preview_enabled?) - end - end + describe '#components_usage_data' do + subject { described_class.components_usage_data } + + it 'gathers components usage data', :aggregate_failures do + expect(subject[:gitlab_pages][:enabled]).to eq(Gitlab.config.pages.enabled) + expect(subject[:gitlab_pages][:version]).to eq(Gitlab::Pages::VERSION) + expect(subject[:git][:version]).to eq(Gitlab::Git.version) + expect(subject[:database][:adapter]).to eq(Gitlab::Database.adapter_name) + expect(subject[:database][:version]).to eq(Gitlab::Database.version) + expect(subject[:gitaly][:version]).to be_present + expect(subject[:gitaly][:servers]).to be >= 1 + expect(subject[:gitaly][:filesystems]).to be_an(Array) + expect(subject[:gitaly][:filesystems].first).to be_a(String) + end + end - describe '#components_usage_data' do - subject { described_class.components_usage_data } - - it 'gathers components usage data', :aggregate_failures do - expect(subject[:gitlab_pages][:enabled]).to eq(Gitlab.config.pages.enabled) - expect(subject[:gitlab_pages][:version]).to eq(Gitlab::Pages::VERSION) - expect(subject[:git][:version]).to eq(Gitlab::Git.version) - expect(subject[:database][:adapter]).to eq(Gitlab::Database.adapter_name) - expect(subject[:database][:version]).to eq(Gitlab::Database.version) - expect(subject[:gitaly][:version]).to be_present - expect(subject[:gitaly][:servers]).to be >= 1 - expect(subject[:gitaly][:filesystems]).to be_an(Array) - expect(subject[:gitaly][:filesystems].first).to be_a(String) - end - end + describe '#ingress_modsecurity_usage' do + subject { described_class.ingress_modsecurity_usage } + + it 'gathers variable data' do + allow_any_instance_of( + ::Clusters::Applications::IngressModsecurityUsageService + ).to receive(:execute).and_return( + { + ingress_modsecurity_blocking: 1, + ingress_modsecurity_disabled: 2 + } + ) + + expect(subject[:ingress_modsecurity_blocking]).to eq(1) + expect(subject[:ingress_modsecurity_disabled]).to eq(2) + end + end - describe '#ingress_modsecurity_usage' do - subject { described_class.ingress_modsecurity_usage } - - it 'gathers variable data' do - allow_any_instance_of( - ::Clusters::Applications::IngressModsecurityUsageService - ).to receive(:execute).and_return( - { - ingress_modsecurity_blocking: 1, - ingress_modsecurity_disabled: 2 - } - ) - - expect(subject[:ingress_modsecurity_blocking]).to eq(1) - expect(subject[:ingress_modsecurity_disabled]).to eq(2) - end - end + describe '#license_usage_data' do + subject { described_class.license_usage_data } - describe '#license_usage_data' do - subject { described_class.license_usage_data } + it 'gathers license data', :aggregate_failures do + expect(subject[:uuid]).to eq(Gitlab::CurrentSettings.uuid) + expect(subject[:version]).to eq(Gitlab::VERSION) + expect(subject[:installation_type]).to eq('gitlab-development-kit') + expect(subject[:active_user_count]).to eq(User.active.count) + expect(subject[:recorded_at]).to be_a(Time) + end + end - it 'gathers license data', :aggregate_failures do - expect(subject[:uuid]).to eq(Gitlab::CurrentSettings.uuid) - expect(subject[:version]).to eq(Gitlab::VERSION) - expect(subject[:installation_type]).to eq('gitlab-development-kit') - expect(subject[:active_user_count]).to eq(User.active.count) - expect(subject[:recorded_at]).to be_a(Time) - end - end + describe '#count' do + let(:relation) { double(:relation) } - describe '#count' do - let(:relation) { double(:relation) } + it 'returns the count when counting succeeds' do + allow(relation).to receive(:count).and_return(1) - it 'returns the count when counting succeeds' do - allow(relation).to receive(:count).and_return(1) + expect(described_class.count(relation, batch: false)).to eq(1) + end - expect(described_class.count(relation)).to eq(1) - end + it 'returns the fallback value when counting fails' do + allow(relation).to receive(:count).and_raise(ActiveRecord::StatementInvalid.new('')) - it 'returns the fallback value when counting fails' do - allow(relation).to receive(:count).and_raise(ActiveRecord::StatementInvalid.new('')) + expect(described_class.count(relation, fallback: 15, batch: false)).to eq(15) + end + end - expect(described_class.count(relation, fallback: 15)).to eq(15) - end - end + describe '#approximate_counts' do + it 'gets approximate counts for selected models', :aggregate_failures do + create(:label) - describe '#approximate_counts' do - it 'gets approximate counts for selected models', :aggregate_failures do - create(:label) + expect(Gitlab::Database::Count).to receive(:approximate_counts) + .with(described_class::APPROXIMATE_COUNT_MODELS).once.and_call_original - expect(Gitlab::Database::Count).to receive(:approximate_counts) - .with(described_class::APPROXIMATE_COUNT_MODELS).once.and_call_original + counts = described_class.approximate_counts.values - counts = described_class.approximate_counts.values + expect(counts.count).to eq(described_class::APPROXIMATE_COUNT_MODELS.count) + expect(counts.any? { |count| count < 0 }).to be_falsey + end - expect(counts.count).to eq(described_class::APPROXIMATE_COUNT_MODELS.count) - expect(counts.any? { |count| count < 0 }).to be_falsey - end + it 'returns default values if counts can not be retrieved', :aggregate_failures do + described_class::APPROXIMATE_COUNT_MODELS.map do |model| + model.name.underscore.pluralize.to_sym + end - it 'returns default values if counts can not be retrieved', :aggregate_failures do - described_class::APPROXIMATE_COUNT_MODELS.map do |model| - model.name.underscore.pluralize.to_sym + expect(Gitlab::Database::Count).to receive(:approximate_counts).and_return({}) + expect(described_class.approximate_counts.values.uniq).to eq([-1]) + end end - - expect(Gitlab::Database::Count).to receive(:approximate_counts).and_return({}) - expect(described_class.approximate_counts.values.uniq).to eq([-1]) end end end diff --git a/spec/models/project_services/chat_notification_service_spec.rb b/spec/models/project_services/chat_notification_service_spec.rb index e8c5f5d611a..45ea4cd74ed 100644 --- a/spec/models/project_services/chat_notification_service_spec.rb +++ b/spec/models/project_services/chat_notification_service_spec.rb @@ -35,6 +35,7 @@ describe ChatNotificationService do let(:user) { create(:user) } let(:project) { create(:project, :repository) } let(:webhook_url) { 'https://example.gitlab.com/' } + let(:data) { Gitlab::DataBuilder::Push.build_sample(subject.project, user) } before do allow(chat_service).to receive_messages( @@ -51,9 +52,6 @@ describe ChatNotificationService do context 'with a repository' do it 'returns true' do - subject.project = project - data = Gitlab::DataBuilder::Push.build_sample(project, user) - expect(chat_service).to receive(:notify).and_return(true) expect(chat_service.execute(data)).to be true end @@ -62,11 +60,19 @@ describe ChatNotificationService do context 'with an empty repository' do it 'returns true' do subject.project = create(:project, :empty_repo) - data = Gitlab::DataBuilder::Push.build_sample(subject.project, user) expect(chat_service).to receive(:notify).and_return(true) expect(chat_service.execute(data)).to be true end end + + context 'with a project with name containing spaces' do + it 'does not remove spaces' do + allow(project).to receive(:full_name).and_return('Project Name') + + expect(chat_service).to receive(:get_message).with(any_args, hash_including(project_name: 'Project Name')) + chat_service.execute(data) + end + end end end diff --git a/spec/requests/api/graphql/group/milestones_spec.rb b/spec/requests/api/graphql/group/milestones_spec.rb index 84b14470fd1..f8e3c0026f5 100644 --- a/spec/requests/api/graphql/group/milestones_spec.rb +++ b/spec/requests/api/graphql/group/milestones_spec.rb @@ -29,7 +29,7 @@ describe 'Milestones through GroupQuery' do it_behaves_like 'a working graphql query' it 'returns milestones successfully' do - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(graphql_errors).to be_nil expect_array_response(milestone_1.to_global_id.to_s, milestone_2.to_global_id.to_s, milestone_3.to_global_id.to_s, milestone_4.to_global_id.to_s) end diff --git a/spec/requests/api/graphql/group_query_spec.rb b/spec/requests/api/graphql/group_query_spec.rb index e0f1e4dbe9e..6e2663fb090 100644 --- a/spec/requests/api/graphql/group_query_spec.rb +++ b/spec/requests/api/graphql/group_query_spec.rb @@ -55,7 +55,7 @@ describe 'getting group information' do post_graphql(group_query(group1), current_user: user1) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(graphql_data['group']['id']).to eq(group1.to_global_id.to_s) expect(graphql_data['group']['name']).to eq(group1.name) expect(graphql_data['group']['path']).to eq(group1.path) diff --git a/spec/requests/api/graphql/tasks/task_completion_status_spec.rb b/spec/requests/api/graphql/tasks/task_completion_status_spec.rb index 188bfa8b924..c727750c0ce 100644 --- a/spec/requests/api/graphql/tasks/task_completion_status_spec.rb +++ b/spec/requests/api/graphql/tasks/task_completion_status_spec.rb @@ -33,7 +33,7 @@ describe 'getting task completion status information' do it 'returns the expected task completion status' do post_graphql(create_task_completion_status_query_for(type, item.iid), current_user: user1) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) task_completion_status = graphql_data.dig('project', type, 'taskCompletionStatus') expect(task_completion_status).not_to be_nil diff --git a/spec/requests/api/internal/base_spec.rb b/spec/requests/api/internal/base_spec.rb index 733f0446cf4..02dc2229769 100644 --- a/spec/requests/api/internal/base_spec.rb +++ b/spec/requests/api/internal/base_spec.rb @@ -16,7 +16,7 @@ describe API::Internal::Base do get api("/internal/check"), params: { secret_token: secret_token } - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['api_version']).to eq(API::API.version) expect(json_response['redis']).to be(true) end @@ -34,13 +34,13 @@ describe API::Internal::Base do get api("/internal/check"), headers: { API::Helpers::GITLAB_SHARED_SECRET_HEADER => Base64.encode64(secret_token) } - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) end it 'returns 401 when no credentials provided' do get(api("/internal/check")) - expect(response).to have_gitlab_http_status(401) + expect(response).to have_gitlab_http_status(:unauthorized) end end end @@ -126,7 +126,7 @@ describe API::Internal::Base do it 'returns the correct information about the key' do lfs_auth_key(key.id, project) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['username']).to eq(user.username) expect(json_response['repository_http_path']).to eq(project.http_url_to_repo) expect(json_response['expires_in']).to eq(Gitlab::LfsToken::DEFAULT_EXPIRE_TIME) @@ -136,7 +136,7 @@ describe API::Internal::Base do it 'returns the correct information about the user' do lfs_auth_user(user.id, project) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['username']).to eq(user.username) expect(json_response['repository_http_path']).to eq(project.http_url_to_repo) expect(Gitlab::LfsToken.new(user).token_valid?(json_response['lfs_token'])).to be_truthy @@ -145,19 +145,19 @@ describe API::Internal::Base do it 'returns a 404 when no key or user is provided' do lfs_auth_project(project) - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) end it 'returns a 404 when the wrong key is provided' do lfs_auth_key(key.id + 12345, project) - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) end it 'returns a 404 when the wrong user is provided' do lfs_auth_user(user.id + 12345, project) - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) end end @@ -167,7 +167,7 @@ describe API::Internal::Base do it 'returns the correct information about the key' do lfs_auth_key(key.id, project) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['username']).to eq("lfs+deploy-key-#{key.id}") expect(json_response['repository_http_path']).to eq(project.http_url_to_repo) expect(Gitlab::LfsToken.new(key).token_valid?(json_response['lfs_token'])).to be_truthy @@ -179,7 +179,7 @@ describe API::Internal::Base do it "finds a user by key id" do get(api("/internal/discover"), params: { key_id: key.id, secret_token: secret_token }) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['name']).to eq(user.name) end @@ -187,7 +187,7 @@ describe API::Internal::Base do it "finds a user by username" do get(api("/internal/discover"), params: { username: user.username, secret_token: secret_token }) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['name']).to eq(user.name) end @@ -195,7 +195,7 @@ describe API::Internal::Base do it 'responds successfully when a user is not found' do get(api('/internal/discover'), params: { username: 'noone', secret_token: secret_token }) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(response.body).to eq('null') end @@ -203,7 +203,7 @@ describe API::Internal::Base do it 'response successfully when passing invalid params' do get(api('/internal/discover'), params: { nothing: 'to find a user', secret_token: secret_token }) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(response.body).to eq('null') end @@ -284,7 +284,7 @@ describe API::Internal::Base do GIT_ALTERNATE_OBJECT_DIRECTORIES_RELATIVE: alt_obj_dirs_relative }.to_json) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) end end @@ -292,7 +292,7 @@ describe API::Internal::Base do it 'responds with success' do push(key, project.wiki) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response["status"]).to be_truthy expect(json_response["gl_project_path"]).to eq(project.wiki.full_path) expect(json_response["gl_repository"]).to eq("wiki-#{project.id}") @@ -304,7 +304,7 @@ describe API::Internal::Base do it 'responds with success' do pull(key, project.wiki) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response["status"]).to be_truthy expect(json_response["gl_project_path"]).to eq(project.wiki.full_path) expect(json_response["gl_repository"]).to eq("wiki-#{project.id}") @@ -320,7 +320,7 @@ describe API::Internal::Base do it "has the correct payload" do pull(key, project) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response["status"]).to be_truthy expect(json_response["gl_repository"]).to eq("project-#{project.id}") expect(json_response["gl_project_path"]).to eq(project.full_path) @@ -340,7 +340,7 @@ describe API::Internal::Base do it do push(key, project) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response["status"]).to be_truthy expect(json_response["gl_repository"]).to eq("project-#{project.id}") expect(json_response["gl_project_path"]).to eq(project.full_path) @@ -409,7 +409,7 @@ describe API::Internal::Base do it do pull(key, project) - expect(response).to have_gitlab_http_status(401) + expect(response).to have_gitlab_http_status(:unauthorized) expect(json_response["status"]).to be_falsey expect(user.reload.last_activity_on).to be_nil end @@ -419,7 +419,7 @@ describe API::Internal::Base do it do push(key, project) - expect(response).to have_gitlab_http_status(401) + expect(response).to have_gitlab_http_status(:unauthorized) expect(json_response["status"]).to be_falsey expect(user.reload.last_activity_on).to be_nil end @@ -464,7 +464,7 @@ describe API::Internal::Base do it do push(key, project) - expect(response).to have_gitlab_http_status(300) + expect(response).to have_gitlab_http_status(:multiple_choices) expect(json_response['status']).to be_truthy expect(json_response['payload']).to eql(payload) expect(json_response['gl_console_messages']).to eql(console_messages) @@ -483,7 +483,7 @@ describe API::Internal::Base do it "has the correct payload" do pull(key, project) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['gl_console_messages']).to eq([]) end end @@ -500,7 +500,7 @@ describe API::Internal::Base do pull(key, project) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['gl_console_messages']).to eq(console_messages) end end @@ -518,7 +518,7 @@ describe API::Internal::Base do it do pull(key, personal_project) - expect(response).to have_gitlab_http_status(401) + expect(response).to have_gitlab_http_status(:unauthorized) expect(json_response["status"]).to be_falsey expect(user.reload.last_activity_on).to be_nil end @@ -528,7 +528,7 @@ describe API::Internal::Base do it do push(key, personal_project) - expect(response).to have_gitlab_http_status(401) + expect(response).to have_gitlab_http_status(:unauthorized) expect(json_response["status"]).to be_falsey expect(user.reload.last_activity_on).to be_nil end @@ -545,7 +545,7 @@ describe API::Internal::Base do end push(key, personal_project) - expect(response).to have_gitlab_http_status(503) + expect(response).to have_gitlab_http_status(:service_unavailable) expect(json_response['status']).to be_falsey expect(json_response['message']).to eq("Foo") expect(user.reload.last_activity_on).to be_nil @@ -563,7 +563,7 @@ describe API::Internal::Base do it do pull(key, project) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response["status"]).to be_truthy end end @@ -572,7 +572,7 @@ describe API::Internal::Base do it do push(key, project) - expect(response).to have_gitlab_http_status(401) + expect(response).to have_gitlab_http_status(:unauthorized) expect(json_response["status"]).to be_falsey end end @@ -589,7 +589,7 @@ describe API::Internal::Base do it do archive(key, project) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response["status"]).to be_truthy expect(json_response["gitaly"]).not_to be_nil expect(json_response["gitaly"]["repository"]).not_to be_nil @@ -604,7 +604,7 @@ describe API::Internal::Base do it do archive(key, project) - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) expect(json_response["status"]).to be_falsey end end @@ -616,7 +616,7 @@ describe API::Internal::Base do pull(key, project) - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) expect(json_response["status"]).to be_falsey end @@ -632,7 +632,7 @@ describe API::Internal::Base do } ) - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) expect(json_response["status"]).to be_falsey end end @@ -641,7 +641,7 @@ describe API::Internal::Base do it do pull(OpenStruct.new(id: 0), project) - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) expect(json_response["status"]).to be_falsey end end @@ -714,14 +714,14 @@ describe API::Internal::Base do it 'rejects the push' do push(key, project) - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) expect(json_response['status']).to be_falsy end it 'rejects the SSH pull' do pull(key, project) - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) expect(json_response['status']).to be_falsy end end @@ -750,7 +750,7 @@ describe API::Internal::Base do # # post api("/internal/notify_post_receive"), valid_params # - # expect(response).to have_gitlab_http_status(200) + # expect(response).to have_gitlab_http_status(:ok) # end # # it "calls the Gitaly client with the wiki's repository if it's a wiki" do @@ -762,7 +762,7 @@ describe API::Internal::Base do # # post api("/internal/notify_post_receive"), valid_wiki_params # - # expect(response).to have_gitlab_http_status(200) + # expect(response).to have_gitlab_http_status(:ok) # end # # it "returns 500 if the gitaly call fails" do @@ -771,7 +771,7 @@ describe API::Internal::Base do # # post api("/internal/notify_post_receive"), valid_params # - # expect(response).to have_gitlab_http_status(500) + # expect(response).to have_gitlab_http_status(:internal_server_error) # end # # context 'with a gl_repository parameter' do @@ -792,7 +792,7 @@ describe API::Internal::Base do # # post api("/internal/notify_post_receive"), valid_params # - # expect(response).to have_gitlab_http_status(200) + # expect(response).to have_gitlab_http_status(:ok) # end # # it "calls the Gitaly client with the wiki's repository if it's a wiki" do @@ -804,7 +804,7 @@ describe API::Internal::Base do # # post api("/internal/notify_post_receive"), valid_wiki_params # - # expect(response).to have_gitlab_http_status(200) + # expect(response).to have_gitlab_http_status(:ok) # end # end # end @@ -961,7 +961,7 @@ describe API::Internal::Base do it 'outputs a broadcast message' do post api('/internal/post_receive'), params: valid_params - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['messages']).to include(build_alert_message(broadcast_message.message)) end end @@ -970,7 +970,7 @@ describe API::Internal::Base do it 'does not output a broadcast message' do post api('/internal/post_receive'), params: valid_params - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(has_alert_messages?(json_response['messages'])).to be_falsey end end @@ -981,7 +981,7 @@ describe API::Internal::Base do post api('/internal/post_receive'), params: valid_params - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(has_alert_messages?(json_response['messages'])).to be_falsey end end @@ -993,7 +993,7 @@ describe API::Internal::Base do post api('/internal/post_receive'), params: valid_params - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['messages']).to include(build_basic_message(project_moved.message)) end end @@ -1005,7 +1005,7 @@ describe API::Internal::Base do post api('/internal/post_receive'), params: valid_params - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['messages']).to include(build_basic_message(project_created.message)) end end @@ -1018,7 +1018,7 @@ describe API::Internal::Base do post api('/internal/post_receive'), params: valid_params - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) end end @@ -1032,7 +1032,7 @@ describe API::Internal::Base do post api('/internal/post_receive'), params: valid_params - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) end end end diff --git a/spec/requests/api/internal/pages_spec.rb b/spec/requests/api/internal/pages_spec.rb index 2887163fe58..9a8c1a0e03b 100644 --- a/spec/requests/api/internal/pages_spec.rb +++ b/spec/requests/api/internal/pages_spec.rb @@ -22,7 +22,7 @@ describe API::Internal::Pages do it 'responds with 404 Not Found' do query_host('pages.gitlab.io') - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) end end @@ -31,7 +31,7 @@ describe API::Internal::Pages do it 'responds with 401 Unauthorized' do query_host('pages.gitlab.io') - expect(response).to have_gitlab_http_status(401) + expect(response).to have_gitlab_http_status(:unauthorized) end end @@ -51,7 +51,7 @@ describe API::Internal::Pages do it 'responds with 204 no content' do query_host('pages.gitlab.io') - expect(response).to have_gitlab_http_status(204) + expect(response).to have_gitlab_http_status(:no_content) expect(response.body).to be_empty end end @@ -65,7 +65,7 @@ describe API::Internal::Pages do it 'responds with 204 No Content' do query_host('pages.gitlab.io') - expect(response).to have_gitlab_http_status(204) + expect(response).to have_gitlab_http_status(:no_content) end end @@ -75,7 +75,7 @@ describe API::Internal::Pages do query_host('pages.gitlab.io') - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(response).to match_response_schema('internal/pages/virtual_domain') expect(json_response['certificate']).to eq(pages_domain.certificate) @@ -114,7 +114,7 @@ describe API::Internal::Pages do query_host('mygroup.gitlab-pages.io') - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(response).to match_response_schema('internal/pages/virtual_domain') expect(json_response['lookup_paths']).to eq( @@ -141,7 +141,7 @@ describe API::Internal::Pages do query_host('mygroup.gitlab-pages.io') - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(response).to match_response_schema('internal/pages/virtual_domain') expect(json_response['lookup_paths']).to eq( diff --git a/spec/requests/api/issues/get_group_issues_spec.rb b/spec/requests/api/issues/get_group_issues_spec.rb index 59e89a7f452..0a95f9114a5 100644 --- a/spec/requests/api/issues/get_group_issues_spec.rb +++ b/spec/requests/api/issues/get_group_issues_spec.rb @@ -72,7 +72,7 @@ describe API::Issues do it 'returns issues statistics' do get api("/groups/#{group.id}/issues_statistics", user), params: params - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['statistics']).not_to be_nil expect(json_response['statistics']['counts']['all']).to eq counts[:all] expect(json_response['statistics']['counts']['closed']).to eq counts[:closed] @@ -343,7 +343,7 @@ describe API::Issues do it 'exposes known attributes' do get api(base_url, admin) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response.last.keys).to include(*%w(id iid project_id title description)) expect(json_response.last).not_to have_key('subscribed') end @@ -527,7 +527,7 @@ describe API::Issues do it 'returns an array of issues with no milestone' do get api(base_url, user), params: { milestone: no_milestone_title } - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect_paginated_array_response(group_confidential_issue.id) end @@ -674,14 +674,14 @@ describe API::Issues do it 'returns error when multiple assignees are passed' do get api(base_url, user), params: { assignee_username: [assignee.username, another_assignee.username], scope: 'all' } - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) expect(json_response["error"]).to include("allows one value, but found 2") end it 'returns error when assignee_username and assignee_id are passed together' do get api(base_url, user), params: { assignee_username: [assignee.username], assignee_id: another_assignee.id, scope: 'all' } - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) expect(json_response["error"]).to include("mutually exclusive") end end diff --git a/spec/requests/api/issues/get_project_issues_spec.rb b/spec/requests/api/issues/get_project_issues_spec.rb index edd4ae85729..539841fe460 100644 --- a/spec/requests/api/issues/get_project_issues_spec.rb +++ b/spec/requests/api/issues/get_project_issues_spec.rb @@ -93,7 +93,7 @@ describe API::Issues do it 'returns project issues statistics' do get api("/issues_statistics", user), params: params - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['statistics']).not_to be_nil expect(json_response['statistics']['counts']['all']).to eq counts[:all] expect(json_response['statistics']['counts']['closed']).to eq counts[:closed] @@ -196,7 +196,7 @@ describe API::Issues do get api("/projects/#{max_project_id + 1}/issues", non_member) - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) end it 'returns 404 on private projects for other users' do @@ -205,7 +205,7 @@ describe API::Issues do get api("/projects/#{private_project.id}/issues", non_member) - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) end it 'returns no issues when user has access to project but not issues' do @@ -472,7 +472,7 @@ describe API::Issues do it 'exposes known attributes' do get api("#{base_url}/issues", user) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response.last.keys).to include(*%w(id iid project_id title description)) expect(json_response.last).not_to have_key('subscribed') end @@ -565,14 +565,14 @@ describe API::Issues do it 'returns error when multiple assignees are passed' do get api("/issues", user), params: { assignee_username: [assignee.username, another_assignee.username], scope: 'all' } - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) expect(json_response["error"]).to include("allows one value, but found 2") end it 'returns error when assignee_username and assignee_id are passed together' do get api("/issues", user), params: { assignee_username: [assignee.username], assignee_id: another_assignee.id, scope: 'all' } - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) expect(json_response["error"]).to include("mutually exclusive") end end @@ -583,14 +583,14 @@ describe API::Issues do it 'returns public issues' do get api("/projects/#{project.id}/issues/#{issue.iid}") - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) end end it 'exposes known attributes' do get api("/projects/#{project.id}/issues/#{issue.iid}", user) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['id']).to eq(issue.id) expect(json_response['iid']).to eq(issue.iid) expect(json_response['project_id']).to eq(issue.project.id) @@ -630,7 +630,7 @@ describe API::Issues do it 'exposes the closed_at attribute' do get api("/projects/#{project.id}/issues/#{closed_issue.iid}", user) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['closed_at']).to be_present end @@ -650,39 +650,39 @@ describe API::Issues do it 'returns a project issue by internal id' do get api("/projects/#{project.id}/issues/#{issue.iid}", user) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['title']).to eq(issue.title) expect(json_response['iid']).to eq(issue.iid) end it 'returns 404 if issue id not found' do get api("/projects/#{project.id}/issues/54321", user) - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) end it 'returns 404 if the issue ID is used' do get api("/projects/#{project.id}/issues/#{issue.id}", user) - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) end context 'confidential issues' do it 'returns 404 for non project members' do get api("/projects/#{project.id}/issues/#{confidential_issue.iid}", non_member) - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) end it 'returns 404 for project members with guest role' do get api("/projects/#{project.id}/issues/#{confidential_issue.iid}", guest) - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) end it 'returns confidential issue for project members' do get api("/projects/#{project.id}/issues/#{confidential_issue.iid}", user) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['title']).to eq(confidential_issue.title) expect(json_response['iid']).to eq(confidential_issue.iid) end @@ -690,7 +690,7 @@ describe API::Issues do it 'returns confidential issue for author' do get api("/projects/#{project.id}/issues/#{confidential_issue.iid}", author) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['title']).to eq(confidential_issue.title) expect(json_response['iid']).to eq(confidential_issue.iid) end @@ -698,7 +698,7 @@ describe API::Issues do it 'returns confidential issue for assignee' do get api("/projects/#{project.id}/issues/#{confidential_issue.iid}", assignee) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['title']).to eq(confidential_issue.title) expect(json_response['iid']).to eq(confidential_issue.iid) end @@ -706,7 +706,7 @@ describe API::Issues do it 'returns confidential issue for admin' do get api("/projects/#{project.id}/issues/#{confidential_issue.iid}", admin) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['title']).to eq(confidential_issue.title) expect(json_response['iid']).to eq(confidential_issue.iid) end @@ -744,7 +744,7 @@ describe API::Issues do it "returns 404 when issue doesn't exists" do get api("/projects/#{project.id}/issues/0/closed_by", user) - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) end end @@ -774,7 +774,7 @@ describe API::Issues do get_related_merge_requests(project.id, issue.iid) expect_paginated_array_response(related_mr.id) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response.last).not_to have_key('subscribed') end @@ -785,7 +785,7 @@ describe API::Issues do get_related_merge_requests(private_project.id, private_issue.iid) - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) end end @@ -824,7 +824,7 @@ describe API::Issues do it "returns 404 when issue doesn't exists" do get_related_merge_requests(project.id, 0, user) - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) end end @@ -835,14 +835,14 @@ describe API::Issues do it 'returns unauthorized' do get api("/projects/#{project.id}/issues/#{issue.iid}/user_agent_detail") - expect(response).to have_gitlab_http_status(401) + expect(response).to have_gitlab_http_status(:unauthorized) end end it 'exposes known attributes' do get api("/projects/#{project.id}/issues/#{issue.iid}/user_agent_detail", admin) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['user_agent']).to eq(user_agent_detail.user_agent) expect(json_response['ip_address']).to eq(user_agent_detail.ip_address) expect(json_response['akismet_submitted']).to eq(user_agent_detail.submitted) @@ -851,7 +851,7 @@ describe API::Issues do it 'returns unauthorized for non-admin users' do get api("/projects/#{project.id}/issues/#{issue.iid}/user_agent_detail", user) - expect(response).to have_gitlab_http_status(403) + expect(response).to have_gitlab_http_status(:forbidden) end end @@ -863,7 +863,7 @@ describe API::Issues do it 'returns 404 if the issue is confidential' do post api("/projects/#{project.id}/issues/#{confidential_issue.iid}/participants", non_member) - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) end end end diff --git a/spec/requests/api/issues/issues_spec.rb b/spec/requests/api/issues/issues_spec.rb index 45754736a2c..6fea6201a65 100644 --- a/spec/requests/api/issues/issues_spec.rb +++ b/spec/requests/api/issues/issues_spec.rb @@ -76,7 +76,7 @@ describe API::Issues do it 'returns issues statistics' do get api("/issues_statistics", user), params: params - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['statistics']).not_to be_nil expect(json_response['statistics']['counts']['all']).to eq counts[:all] expect(json_response['statistics']['counts']['closed']).to eq counts[:closed] @@ -89,39 +89,39 @@ describe API::Issues do it 'returns an array of all issues' do get api('/issues'), params: { scope: 'all' } - expect(response).to have_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response).to be_an Array end it 'returns authentication error without any scope' do get api('/issues') - expect(response).to have_http_status(401) + expect(response).to have_gitlab_http_status(:unauthorized) end it 'returns authentication error when scope is assigned-to-me' do get api('/issues'), params: { scope: 'assigned-to-me' } - expect(response).to have_http_status(401) + expect(response).to have_gitlab_http_status(:unauthorized) end it 'returns authentication error when scope is created-by-me' do get api('/issues'), params: { scope: 'created-by-me' } - expect(response).to have_http_status(401) + expect(response).to have_gitlab_http_status(:unauthorized) end it 'returns an array of issues matching state in milestone' do get api('/issues'), params: { milestone: 'foo', scope: 'all' } - expect(response).to have_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect_paginated_array_response([]) end it 'returns an array of issues matching state in milestone' do get api('/issues'), params: { milestone: milestone.title, scope: 'all' } - expect(response).to have_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect_paginated_array_response([issue.id, closed_issue.id]) end @@ -129,19 +129,19 @@ describe API::Issues do it 'returns authentication error without any scope' do get api('/issues_statistics') - expect(response).to have_http_status(401) + expect(response).to have_gitlab_http_status(:unauthorized) end it 'returns authentication error when scope is assigned_to_me' do get api('/issues_statistics'), params: { scope: 'assigned_to_me' } - expect(response).to have_http_status(401) + expect(response).to have_gitlab_http_status(:unauthorized) end it 'returns authentication error when scope is created_by_me' do get api('/issues_statistics'), params: { scope: 'created_by_me' } - expect(response).to have_http_status(401) + expect(response).to have_gitlab_http_status(:unauthorized) end context 'no state is treated as all state' do @@ -642,14 +642,14 @@ describe API::Issues do it 'accepts only predefined order by params' do API::Helpers::IssuesHelpers.sort_options.each do |sort_opt| get api('/issues', user), params: { order_by: sort_opt, sort: 'asc' } - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) end end it 'fails to sort with non predefined options' do %w(milestone title abracadabra).each do |sort_opt| get api('/issues', user), params: { order_by: sort_opt, sort: 'asc' } - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) end end end @@ -657,14 +657,14 @@ describe API::Issues do it 'matches V4 response schema' do get api('/issues', user) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(response).to match_response_schema('public_api/v4/issues') end it 'returns a related merge request count of 0 if there are no related merge requests' do get api('/issues', user) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(response).to match_response_schema('public_api/v4/issues') expect(json_response.first).to include('merge_requests_count' => 0) end @@ -674,7 +674,7 @@ describe API::Issues do get api('/issues', user) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(response).to match_response_schema('public_api/v4/issues') expect(json_response.first).to include('merge_requests_count' => 1) end @@ -767,14 +767,14 @@ describe API::Issues do it 'returns error when multiple assignees are passed' do get api("/issues", user), params: { assignee_username: [assignee.username, another_assignee.username], scope: 'all' } - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) expect(json_response["error"]).to include("allows one value, but found 2") end it 'returns error when assignee_username and assignee_id are passed together' do get api("/issues", user), params: { assignee_username: [assignee.username], assignee_id: another_assignee.id, scope: 'all' } - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) expect(json_response["error"]).to include("mutually exclusive") end end @@ -835,7 +835,7 @@ describe API::Issues do it 'exposes full reference path' do get api("/projects/#{project.id}/issues/#{issue.iid}", user) - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['references']['short']).to eq("##{issue.iid}") expect(json_response['references']['relative']).to eq("##{issue.iid}") expect(json_response['references']['full']).to eq("#{project.parent.path}/#{project.path}##{issue.iid}") @@ -845,12 +845,12 @@ describe API::Issues do describe 'DELETE /projects/:id/issues/:issue_iid' do it 'rejects a non member from deleting an issue' do delete api("/projects/#{project.id}/issues/#{issue.iid}", non_member) - expect(response).to have_gitlab_http_status(403) + expect(response).to have_gitlab_http_status(:forbidden) end it 'rejects a developer from deleting an issue' do delete api("/projects/#{project.id}/issues/#{issue.iid}", author) - expect(response).to have_gitlab_http_status(403) + expect(response).to have_gitlab_http_status(:forbidden) end context 'when the user is project owner' do @@ -860,7 +860,7 @@ describe API::Issues do it 'deletes the issue if an admin requests it' do delete api("/projects/#{project.id}/issues/#{issue.iid}", owner) - expect(response).to have_gitlab_http_status(204) + expect(response).to have_gitlab_http_status(:no_content) end it_behaves_like '412 response' do @@ -872,14 +872,14 @@ describe API::Issues do it 'returns 404 when trying to delete an issue' do delete api("/projects/#{project.id}/issues/123", user) - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) end end it 'returns 404 when using the issue ID instead of IID' do delete api("/projects/#{project.id}/issues/#{issue.id}", user) - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) end end diff --git a/spec/requests/api/issues/post_projects_issues_spec.rb b/spec/requests/api/issues/post_projects_issues_spec.rb index 782eda875af..0ec13eb2b31 100644 --- a/spec/requests/api/issues/post_projects_issues_spec.rb +++ b/spec/requests/api/issues/post_projects_issues_spec.rb @@ -75,7 +75,7 @@ describe API::Issues do post api("/projects/#{project.id}/issues", user), params: { title: 'new issue', assignee_id: user2.id } - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(json_response['title']).to eq('new issue') expect(json_response['assignee']['name']).to eq(user2.name) expect(json_response['assignees'].first['name']).to eq(user2.name) @@ -85,7 +85,7 @@ describe API::Issues do post api("/projects/#{project.id}/issues", user), params: { title: 'new issue', assignee_id: '' } - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(json_response['title']).to eq('new issue') expect(json_response['assignee']).to be_nil end @@ -96,7 +96,7 @@ describe API::Issues do post api("/projects/#{project.id}/issues", user), params: { title: 'new issue', assignee_ids: [user2.id, guest.id] } - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(json_response['title']).to eq('new issue') expect(json_response['assignees'].count).to eq(1) end @@ -112,7 +112,7 @@ describe API::Issues do it 'renders 403' do post api("/projects/#{project.id}/issues", not_member), params: { title: 'new issue' } - expect(response).to have_gitlab_http_status(403) + expect(response).to have_gitlab_http_status(:forbidden) end end @@ -122,7 +122,7 @@ describe API::Issues do post api("/projects/#{project.id}/issues", admin), params: { title: 'new issue', iid: 9001 } - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(json_response['iid']).to eq 9001 end end @@ -132,7 +132,7 @@ describe API::Issues do post api("/projects/#{project.id}/issues", user), params: { title: 'new issue', iid: 9001 } - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(json_response['iid']).to eq 9001 end end @@ -146,7 +146,7 @@ describe API::Issues do post api("/projects/#{group_project.id}/issues", user2), params: { title: 'new issue', iid: 9001 } - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(json_response['iid']).to eq 9001 end end @@ -156,7 +156,7 @@ describe API::Issues do post api("/projects/#{project.id}/issues", user2), params: { title: 'new issue', iid: 9001 } - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(json_response['iid']).not_to eq 9001 end end @@ -166,7 +166,7 @@ describe API::Issues do post api("/projects/#{project.id}/issues", admin), params: { title: 'new issue', iid: issue.iid } - expect(response).to have_gitlab_http_status(409) + expect(response).to have_gitlab_http_status(:conflict) expect(json_response['message']).to eq 'Duplicated issue' end end @@ -176,7 +176,7 @@ describe API::Issues do post api("/projects/#{project.id}/issues", user), params: { title: 'new issue', labels: 'label, label2', weight: 3, assignee_ids: [user2.id] } - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(json_response['title']).to eq('new issue') expect(json_response['description']).to be_nil expect(json_response['labels']).to eq(%w(label label2)) @@ -189,7 +189,7 @@ describe API::Issues do post api("/projects/#{project.id}/issues", user), params: { title: 'new issue', labels: %w(label label2), weight: 3, assignee_ids: [user2.id] } - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(json_response['title']).to eq('new issue') expect(json_response['description']).to be_nil expect(json_response['labels']).to eq(%w(label label2)) @@ -202,7 +202,7 @@ describe API::Issues do post api("/projects/#{project.id}/issues", user), params: { title: 'new issue', confidential: true } - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(json_response['title']).to eq('new issue') expect(json_response['confidential']).to be_truthy end @@ -211,7 +211,7 @@ describe API::Issues do post api("/projects/#{project.id}/issues", user), params: { title: 'new issue', confidential: 'y' } - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(json_response['title']).to eq('new issue') expect(json_response['confidential']).to be_truthy end @@ -220,7 +220,7 @@ describe API::Issues do post api("/projects/#{project.id}/issues", user), params: { title: 'new issue', confidential: false } - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(json_response['title']).to eq('new issue') expect(json_response['confidential']).to be_falsy end @@ -229,13 +229,13 @@ describe API::Issues do post api("/projects/#{project.id}/issues", user), params: { title: 'new issue', confidential: 'foo' } - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) expect(json_response['error']).to eq('confidential is invalid') end it 'returns a 400 bad request if title not given' do post api("/projects/#{project.id}/issues", user), params: { labels: 'label, label2' } - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) end it 'allows special label names' do @@ -269,7 +269,7 @@ describe API::Issues do it 'returns 400 if title is too long' do post api("/projects/#{project.id}/issues", user), params: { title: 'g' * 256 } - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) expect(json_response['message']['title']).to eq([ 'is too long (maximum is 255 characters)' ]) @@ -317,7 +317,7 @@ describe API::Issues do post api("/projects/#{project.id}/issues", user), params: { title: 'new issue', due_date: due_date } - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(json_response['title']).to eq('new issue') expect(json_response['description']).to be_nil expect(json_response['due_date']).to eq(due_date) @@ -332,7 +332,7 @@ describe API::Issues do it 'sets the creation time on the new issue' do post api("/projects/#{project.id}/issues", admin), params: params - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(Time.parse(json_response['created_at'])).to be_like_time(creation_time) end end @@ -341,7 +341,7 @@ describe API::Issues do it 'sets the creation time on the new issue' do post api("/projects/#{project.id}/issues", user), params: params - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(Time.parse(json_response['created_at'])).to be_like_time(creation_time) end end @@ -353,7 +353,7 @@ describe API::Issues do group.add_owner(user2) post api("/projects/#{group_project.id}/issues", user2), params: params - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(Time.parse(json_response['created_at'])).to be_like_time(creation_time) end end @@ -362,7 +362,7 @@ describe API::Issues do it 'ignores the given creation time' do post api("/projects/#{project.id}/issues", user2), params: params - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(Time.parse(json_response['created_at'])).not_to be_like_time(creation_time) end end @@ -417,7 +417,7 @@ describe API::Issues do it 'returns correct status and message' do post_issue - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) expect(json_response['message']).to eq({ 'error' => 'Spam detected' }) end @@ -435,7 +435,7 @@ describe API::Issues do it 'returns correct status' do post_issue - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) end it 'creates a new spam log entry' do @@ -453,7 +453,7 @@ describe API::Issues do post api("/projects/#{project.id}/issues/#{issue.iid}/move", user), params: { to_project_id: target_project.id } - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(json_response['project_id']).to eq(target_project.id) end @@ -462,7 +462,7 @@ describe API::Issues do post api("/projects/#{project.id}/issues/#{issue.iid}/move", user), params: { to_project_id: project.id } - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) expect(json_response['message']).to eq(s_('MoveIssue|Cannot move issue to project it originates from!')) end end @@ -472,7 +472,7 @@ describe API::Issues do post api("/projects/#{project.id}/issues/#{issue.iid}/move", user), params: { to_project_id: target_project2.id } - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) expect(json_response['message']).to eq(s_('MoveIssue|Cannot move issue due to insufficient permissions!')) end end @@ -481,7 +481,7 @@ describe API::Issues do post api("/projects/#{project.id}/issues/#{issue.iid}/move", admin), params: { to_project_id: target_project2.id } - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(json_response['project_id']).to eq(target_project2.id) end @@ -490,7 +490,7 @@ describe API::Issues do post api("/projects/#{project.id}/issues/#{issue.id}/move", user), params: { to_project_id: target_project.id } - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) expect(json_response['message']).to eq('404 Issue Not Found') end end @@ -500,7 +500,7 @@ describe API::Issues do post api("/projects/#{project.id}/issues/123/move", user), params: { to_project_id: target_project.id } - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) expect(json_response['message']).to eq('404 Issue Not Found') end end @@ -510,7 +510,7 @@ describe API::Issues do post api("/projects/0/issues/#{issue.iid}/move", user), params: { to_project_id: target_project.id } - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) expect(json_response['message']).to eq('404 Project Not Found') end end @@ -520,7 +520,7 @@ describe API::Issues do post api("/projects/#{project.id}/issues/#{issue.iid}/move", user), params: { to_project_id: 0 } - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) end end end @@ -529,32 +529,32 @@ describe API::Issues do it 'subscribes to an issue' do post api("/projects/#{project.id}/issues/#{issue.iid}/subscribe", user2) - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(json_response['subscribed']).to eq(true) end it 'returns 304 if already subscribed' do post api("/projects/#{project.id}/issues/#{issue.iid}/subscribe", user) - expect(response).to have_gitlab_http_status(304) + expect(response).to have_gitlab_http_status(:not_modified) end it 'returns 404 if the issue is not found' do post api("/projects/#{project.id}/issues/123/subscribe", user) - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) end it 'returns 404 if the issue ID is used instead of the iid' do post api("/projects/#{project.id}/issues/#{issue.id}/subscribe", user) - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) end it 'returns 404 if the issue is confidential' do post api("/projects/#{project.id}/issues/#{confidential_issue.iid}/subscribe", non_member) - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) end end @@ -562,32 +562,32 @@ describe API::Issues do it 'unsubscribes from an issue' do post api("/projects/#{project.id}/issues/#{issue.iid}/unsubscribe", user) - expect(response).to have_gitlab_http_status(201) + expect(response).to have_gitlab_http_status(:created) expect(json_response['subscribed']).to eq(false) end it 'returns 304 if not subscribed' do post api("/projects/#{project.id}/issues/#{issue.iid}/unsubscribe", user2) - expect(response).to have_gitlab_http_status(304) + expect(response).to have_gitlab_http_status(:not_modified) end it 'returns 404 if the issue is not found' do post api("/projects/#{project.id}/issues/123/unsubscribe", user) - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) end it 'returns 404 if using the issue ID instead of iid' do post api("/projects/#{project.id}/issues/#{issue.id}/unsubscribe", user) - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) end it 'returns 404 if the issue is confidential' do post api("/projects/#{project.id}/issues/#{confidential_issue.iid}/unsubscribe", non_member) - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) end end end diff --git a/spec/requests/api/issues/put_projects_issues_spec.rb b/spec/requests/api/issues/put_projects_issues_spec.rb index 709520b6bdf..b4332c555e1 100644 --- a/spec/requests/api/issues/put_projects_issues_spec.rb +++ b/spec/requests/api/issues/put_projects_issues_spec.rb @@ -73,7 +73,7 @@ describe API::Issues do it 'updates a project issue' do put api("/projects/#{project.id}/issues/#{issue.iid}", user), params: { title: 'updated title' } - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['title']).to eq('updated title') end @@ -81,13 +81,13 @@ describe API::Issues do it 'returns 404 error if issue iid not found' do put api("/projects/#{project.id}/issues/44444", user), params: { title: 'updated title' } - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) end it 'returns 404 error if issue id is used instead of the iid' do put api("/projects/#{project.id}/issues/#{issue.id}", user), params: { title: 'updated title' } - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) end it 'allows special label names' do @@ -124,33 +124,33 @@ describe API::Issues do it 'returns 403 for non project members' do put api("/projects/#{project.id}/issues/#{confidential_issue.iid}", non_member), params: { title: 'updated title' } - expect(response).to have_gitlab_http_status(403) + expect(response).to have_gitlab_http_status(:forbidden) end it 'returns 403 for project members with guest role' do put api("/projects/#{project.id}/issues/#{confidential_issue.iid}", guest), params: { title: 'updated title' } - expect(response).to have_gitlab_http_status(403) + expect(response).to have_gitlab_http_status(:forbidden) end it 'updates a confidential issue for project members' do put api("/projects/#{project.id}/issues/#{confidential_issue.iid}", user), params: { title: 'updated title' } - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['title']).to eq('updated title') end it 'updates a confidential issue for author' do put api("/projects/#{project.id}/issues/#{confidential_issue.iid}", author), params: { title: 'updated title' } - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['title']).to eq('updated title') end it 'updates a confidential issue for admin' do put api("/projects/#{project.id}/issues/#{confidential_issue.iid}", admin), params: { title: 'updated title' } - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['title']).to eq('updated title') end @@ -158,7 +158,7 @@ describe API::Issues do put api("/projects/#{project.id}/issues/#{issue.iid}", user), params: { confidential: true } - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['confidential']).to be_truthy end @@ -166,7 +166,7 @@ describe API::Issues do put api("/projects/#{project.id}/issues/#{confidential_issue.iid}", user), params: { confidential: false } - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['confidential']).to be_falsy end @@ -174,7 +174,7 @@ describe API::Issues do put api("/projects/#{project.id}/issues/#{confidential_issue.iid}", user), params: { confidential: 'foo' } - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) expect(json_response['error']).to eq('confidential is invalid') end end @@ -214,7 +214,7 @@ describe API::Issues do it 'returns correct status and message' do update_issue - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) expect(json_response).to include('message' => { 'error' => 'Spam detected' }) end @@ -232,7 +232,7 @@ describe API::Issues do it 'returns correct status and message' do update_issue - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) end it 'creates a new spam log entry' do @@ -248,7 +248,7 @@ describe API::Issues do put api("/projects/#{project.id}/issues/#{issue.iid}", user), params: { assignee_id: 0 } - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['assignee']).to be_nil end @@ -257,7 +257,7 @@ describe API::Issues do put api("/projects/#{project.id}/issues/#{issue.iid}", user), params: { assignee_id: user2.id } - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['assignee']['name']).to eq(user2.name) end @@ -267,7 +267,7 @@ describe API::Issues do put api("/projects/#{project.id}/issues/#{issue.iid}", user), params: { assignee_ids: [0] } - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['assignees']).to be_empty end @@ -276,7 +276,7 @@ describe API::Issues do put api("/projects/#{project.id}/issues/#{issue.iid}", user), params: { assignee_ids: [user2.id] } - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['assignees'].first['name']).to eq(user2.name) end @@ -286,7 +286,7 @@ describe API::Issues do put api("/projects/#{project.id}/issues/#{issue.iid}", user), params: { assignee_ids: [user2.id, guest.id] } - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['assignees'].size).to eq(1) end @@ -300,7 +300,7 @@ describe API::Issues do it 'does not update labels if not present' do put api("/projects/#{project.id}/issues/#{issue.iid}", user), params: { title: 'updated title' } - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['labels']).to eq([label.title]) end @@ -309,7 +309,7 @@ describe API::Issues do put api("/projects/#{project.id}/issues/#{issue.iid}", user), params: { labels: '' } end - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['labels']).to eq([]) expect(json_response['updated_at']).to be > Time.now end @@ -319,7 +319,7 @@ describe API::Issues do put api("/projects/#{project.id}/issues/#{issue.iid}", user), params: { labels: [''] } end - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['labels']).to eq([]) expect(json_response['updated_at']).to be > Time.now end @@ -329,7 +329,7 @@ describe API::Issues do put api("/projects/#{project.id}/issues/#{issue.iid}", user), params: { labels: 'foo,bar' } end - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['labels']).to include 'foo' expect(json_response['labels']).to include 'bar' expect(json_response['updated_at']).to be > Time.now @@ -340,7 +340,7 @@ describe API::Issues do put api("/projects/#{project.id}/issues/#{issue.iid}", user), params: { labels: %w(foo bar) } end - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['labels']).to include 'foo' expect(json_response['labels']).to include 'bar' expect(json_response['updated_at']).to be > Time.now @@ -377,7 +377,7 @@ describe API::Issues do it 'returns 400 if title is too long' do put api("/projects/#{project.id}/issues/#{issue.iid}", user), params: { title: 'g' * 256 } - expect(response).to have_gitlab_http_status(400) + expect(response).to have_gitlab_http_status(:bad_request) expect(json_response['message']['title']).to eq([ 'is too long (maximum is 255 characters)' ]) @@ -388,7 +388,7 @@ describe API::Issues do it 'updates a project issue' do put api("/projects/#{project.id}/issues/#{issue.iid}", user), params: { labels: 'label2', state_event: 'close' } - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['labels']).to include 'label2' expect(json_response['state']).to eq 'closed' @@ -397,7 +397,7 @@ describe API::Issues do it 'reopens a project isssue' do put api("/projects/#{project.id}/issues/#{closed_issue.iid}", user), params: { state_event: 'reopen' } - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['state']).to eq 'opened' end @@ -407,7 +407,7 @@ describe API::Issues do put api("/projects/#{project.id}/issues/#{issue.iid}", user), params: { labels: 'label3', state_event: 'close', updated_at: update_time } - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['labels']).to include 'label3' expect(Time.parse(json_response['updated_at'])).to be_like_time(update_time) end @@ -420,7 +420,7 @@ describe API::Issues do put api("/projects/#{project.id}/issues/#{issue.iid}", user), params: { due_date: due_date } - expect(response).to have_gitlab_http_status(200) + expect(response).to have_gitlab_http_status(:ok) expect(json_response['due_date']).to eq(due_date) end end diff --git a/spec/requests/api/pages/pages_spec.rb b/spec/requests/api/pages/pages_spec.rb index 2085c509eff..62d43ecff16 100644 --- a/spec/requests/api/pages/pages_spec.rb +++ b/spec/requests/api/pages/pages_spec.rb @@ -32,7 +32,7 @@ describe API::Pages do it 'returns 204' do delete api("/projects/#{project.id}/pages", admin) - expect(response).to have_gitlab_http_status(204) + expect(response).to have_gitlab_http_status(:no_content) end it 'removes the pages' do @@ -53,7 +53,7 @@ describe API::Pages do it 'returns 204' do delete api("/projects/#{project.id}/pages", admin) - expect(response).to have_gitlab_http_status(204) + expect(response).to have_gitlab_http_status(:no_content) end end @@ -63,7 +63,7 @@ describe API::Pages do delete api("/projects/#{id}/pages", admin) - expect(response).to have_gitlab_http_status(404) + expect(response).to have_gitlab_http_status(:not_found) end end end diff --git a/spec/services/submit_usage_ping_service_spec.rb b/spec/services/submit_usage_ping_service_spec.rb index e2f1ef089bf..26ce5968ad6 100644 --- a/spec/services/submit_usage_ping_service_spec.rb +++ b/spec/services/submit_usage_ping_service_spec.rb @@ -76,6 +76,7 @@ describe SubmitUsagePingService do context 'when usage ping is enabled' do before do + allow(ActiveRecord::Base.connection).to receive(:transaction_open?).and_return(false) stub_application_setting(usage_ping_enabled: true) end diff --git a/vendor/elastic_stack/values.yaml b/vendor/elastic_stack/values.yaml index 9355a9b6b81..48950ed8bbb 100644 --- a/vendor/elastic_stack/values.yaml +++ b/vendor/elastic_stack/values.yaml @@ -23,6 +23,29 @@ filebeat: output.elasticsearch: enabled: true hosts: ["http://elastic-stack-elasticsearch-client:9200"] + filebeat.prospectors: + - type: log + enabled: true + paths: + - /var/log/*.log + - /var/log/messages + - /var/log/syslog + - type: docker + containers.ids: + - "*" + json.keys_under_root: true + json.ignore_decoding_error: true + processors: + - add_kubernetes_metadata: + - drop_event: + when: + equals: + kubernetes.container.name: "filebeat" + - decode_json_fields: + fields: ["message"] + when: + equals: + kubernetes.container.name: "modsecurity-log" fluentd: enabled: false |