diff options
22 files changed, 427 insertions, 174 deletions
diff --git a/app/assets/javascripts/diffs/components/app.vue b/app/assets/javascripts/diffs/components/app.vue index 5521e4ab696..6317c146f7e 100644 --- a/app/assets/javascripts/diffs/components/app.vue +++ b/app/assets/javascripts/diffs/components/app.vue @@ -14,7 +14,7 @@ import { } from '~/behaviors/shortcuts/keybindings'; import createFlash from '~/flash'; import { isSingleViewStyle } from '~/helpers/diffs_helper'; -import { getParameterByName, parseBoolean } from '~/lib/utils/common_utils'; +import { parseBoolean } from '~/lib/utils/common_utils'; import { updateHistory } from '~/lib/utils/url_utility'; import { __ } from '~/locale'; import PanelResizer from '~/vue_shared/components/panel_resizer.vue'; @@ -192,6 +192,7 @@ export default { 'showTreeList', 'isLoading', 'startVersion', + 'latestDiff', 'currentDiffFileId', 'isTreeLoaded', 'conflictResolutionPath', @@ -234,8 +235,8 @@ export default { isLimitedContainer() { return !this.renderFileTree && !this.isParallelView && !this.isFluidLayout; }, - isDiffHead() { - return parseBoolean(getParameterByName('diff_head')); + isFullChangeset() { + return this.startVersion === null && this.latestDiff; }, showFileByFileNavigation() { return this.diffFiles.length > 1 && this.viewDiffsFileByFile; @@ -258,7 +259,7 @@ export default { if (this.renderOverflowWarning) { visible = this.$options.alerts.ALERT_OVERFLOW_HIDDEN; - } else if (this.isDiffHead && this.hasConflicts) { + } else if (this.isFullChangeset && this.hasConflicts) { visible = this.$options.alerts.ALERT_MERGE_CONFLICT; } else if (this.whichCollapsedTypes.automatic && !this.viewDiffsFileByFile) { visible = this.$options.alerts.ALERT_COLLAPSED_FILES; @@ -474,7 +475,11 @@ export default { }, setDiscussions() { requestIdleCallback( - () => this.assignDiscussionsToDiff().then(this.$nextTick).then(this.startTaskList), + () => + this.assignDiscussionsToDiff() + .then(this.$nextTick) + .then(this.startTaskList) + .then(this.scrollVirtualScrollerToDiffNote), { timeout: 1000 }, ); }, @@ -538,6 +543,22 @@ export default { this.virtualScrollCurrentIndex = -1; }, + scrollVirtualScrollerToDiffNote() { + if (!window.gon?.features?.diffsVirtualScrolling) return; + + const id = window?.location?.hash; + + if (id.startsWith('#note_')) { + const noteId = id.replace('#note_', ''); + const discussion = this.$store.state.notes.discussions.find((d) => + d.notes.find((n) => n.id === noteId), + ); + + if (discussion) { + this.scrollVirtualScrollerToFileHash(discussion.diff_file.file_hash); + } + } + }, }, minTreeWidth: MIN_TREE_WIDTH, maxTreeWidth: MAX_TREE_WIDTH, diff --git a/app/assets/javascripts/tracking/index.js b/app/assets/javascripts/tracking/index.js index e0ba7dba97f..3714cac3fba 100644 --- a/app/assets/javascripts/tracking/index.js +++ b/app/assets/javascripts/tracking/index.js @@ -34,6 +34,12 @@ const addExperimentContext = (opts) => { return options; }; +const renameKey = (o, oldKey, newKey) => { + const ret = {}; + delete Object.assign(ret, o, { [newKey]: o[oldKey] })[oldKey]; + return ret; +}; + const createEventPayload = (el, { suffix = '' } = {}) => { const { trackAction, @@ -186,15 +192,18 @@ export default class Tracking { (context) => context.schema !== standardContext.schema, ); - const mappedConfig = { - forms: { whitelist: config.forms?.allow || [] }, - fields: { whitelist: config.fields?.allow || [] }, - }; + const mappedConfig = {}; + if (config.forms) mappedConfig.forms = renameKey(config.forms, 'allow', 'whitelist'); + if (config.fields) mappedConfig.fields = renameKey(config.fields, 'allow', 'whitelist'); const enabler = () => window.snowplow('enableFormTracking', mappedConfig, userProvidedContexts); - if (document.readyState !== 'loading') enabler(); - else document.addEventListener('DOMContentLoaded', enabler); + if (document.readyState === 'complete') enabler(); + else { + document.addEventListener('readystatechange', () => { + if (document.readyState === 'complete') enabler(); + }); + } } static mixin(opts = {}) { diff --git a/app/controllers/profiles/personal_access_tokens_controller.rb b/app/controllers/profiles/personal_access_tokens_controller.rb index ba539ef808d..8dc9697c56d 100644 --- a/app/controllers/profiles/personal_access_tokens_controller.rb +++ b/app/controllers/profiles/personal_access_tokens_controller.rb @@ -9,7 +9,11 @@ class Profiles::PersonalAccessTokensController < Profiles::ApplicationController def index set_index_vars - @personal_access_token = finder.build + scopes = params[:scopes].split(',').map(&:squish).select(&:present?).map(&:to_sym) unless params[:scopes].nil? + @personal_access_token = finder.build( + name: params[:name], + scopes: scopes + ) end def create diff --git a/app/graphql/mutations/ci/runner/update.rb b/app/graphql/mutations/ci/runner/update.rb index 5b61b2ffc0d..4cdfa1fb1bd 100644 --- a/app/graphql/mutations/ci/runner/update.rb +++ b/app/graphql/mutations/ci/runner/update.rb @@ -66,3 +66,5 @@ module Mutations end end end + +Mutations::Ci::Runner::Update.prepend_mod_with('Mutations::Ci::Runner::Update') diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md index 8352977375c..d5477546ed4 100644 --- a/doc/api/graphql/reference/index.md +++ b/doc/api/graphql/reference/index.md @@ -3558,6 +3558,8 @@ Input type: `RunnerUpdateInput` | <a id="mutationrunnerupdateid"></a>`id` | [`CiRunnerID!`](#cirunnerid) | ID of the runner to update. | | <a id="mutationrunnerupdatelocked"></a>`locked` | [`Boolean`](#boolean) | Indicates the runner is locked. | | <a id="mutationrunnerupdatemaximumtimeout"></a>`maximumTimeout` | [`Int`](#int) | Maximum timeout (in seconds) for jobs processed by the runner. | +| <a id="mutationrunnerupdateprivateprojectsminutescostfactor"></a>`privateProjectsMinutesCostFactor` | [`Float`](#float) | Private projects' "minutes cost factor" associated with the runner (GitLab.com only). | +| <a id="mutationrunnerupdatepublicprojectsminutescostfactor"></a>`publicProjectsMinutesCostFactor` | [`Float`](#float) | Public projects' "minutes cost factor" associated with the runner (GitLab.com only). | | <a id="mutationrunnerupdaterununtagged"></a>`runUntagged` | [`Boolean`](#boolean) | Indicates the runner is able to run untagged jobs. | | <a id="mutationrunnerupdatetaglist"></a>`tagList` | [`[String!]`](#string) | Tags associated with the runner. | diff --git a/doc/development/usage_ping/dictionary.md b/doc/development/usage_ping/dictionary.md index bfe0fd56df3..cfb97f565b4 100644 --- a/doc/development/usage_ping/dictionary.md +++ b/doc/development/usage_ping/dictionary.md @@ -11712,7 +11712,7 @@ Tiers: `free`, `premium`, `ultimate` ### `redis_hll_counters.incident_management.incident_management_alert_assigned_monthly` -Count of an alert's assignments per month +Count of unique users assigning an alert per month [YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/metrics/counts_28d/20210216180533_incident_management_alert_assigned_monthly.yml) @@ -11724,7 +11724,7 @@ Tiers: `free`, `premium`, `ultimate` ### `redis_hll_counters.incident_management.incident_management_alert_assigned_weekly` -Count of an alert's assignments per week +Count of unique users assigning an alert per week [YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/metrics/counts_7d/20210216180532_incident_management_alert_assigned_weekly.yml) @@ -11736,7 +11736,7 @@ Tiers: `free`, `premium`, `ultimate` ### `redis_hll_counters.incident_management.incident_management_alert_status_changed_monthly` -Count of an alert's status changes per month +Count of unique users changing alert's status changes per month [YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/metrics/counts_28d/20210216180530_incident_management_alert_status_changed_monthly.yml) @@ -11748,7 +11748,7 @@ Tiers: `free`, `premium`, `ultimate` ### `redis_hll_counters.incident_management.incident_management_alert_status_changed_weekly` -Count of an alert's status changes per week +Count of unique users changing alert's status per week [YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/metrics/counts_7d/20210216180528_incident_management_alert_status_changed_weekly.yml) @@ -11760,7 +11760,7 @@ Tiers: `free`, `premium`, `ultimate` ### `redis_hll_counters.incident_management.incident_management_alert_todo_monthly` -Count of alerts added to the TODO list per month +Count of unique users adding alerts to the TODO list per month [YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/metrics/counts_28d/20210216180537_incident_management_alert_todo_monthly.yml) @@ -11772,7 +11772,7 @@ Tiers: `free`, `premium`, `ultimate` ### `redis_hll_counters.incident_management.incident_management_alert_todo_weekly` -Count of alerts added to the TODO list per week +Count of unique users adding alerts to the TODO list per week [YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/metrics/counts_7d/20210216180535_incident_management_alert_todo_weekly.yml) @@ -11784,7 +11784,7 @@ Tiers: `free`, `premium`, `ultimate` ### `redis_hll_counters.incident_management.incident_management_incident_assigned_monthly` -Count of an incidents's assignments per month +Count of users assigning incidents per month [YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/metrics/counts_28d/20210216180552_incident_management_incident_assigned_monthly.yml) @@ -11796,7 +11796,7 @@ Tiers: `free`, `premium`, `ultimate` ### `redis_hll_counters.incident_management.incident_management_incident_assigned_weekly` -Count of an incidents's assignments per week +Count of unique users assiging incidents per week [YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/metrics/counts_7d/20210216180550_incident_management_incident_assigned_weekly.yml) @@ -11808,7 +11808,7 @@ Tiers: `free`, `premium`, `ultimate` ### `redis_hll_counters.incident_management.incident_management_incident_change_confidential_monthly` -Count of incidents changed to confidential per month +Count of users changing incidents to confidential per month [YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/metrics/counts_28d/20210216180618_incident_management_incident_change_confidential_monthly.yml) @@ -11820,7 +11820,7 @@ Tiers: `free`, `premium`, `ultimate` ### `redis_hll_counters.incident_management.incident_management_incident_change_confidential_weekly` -Count of incidents changed to confidential per week +Count of unique users changing incidents to confidential per week [YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/metrics/counts_7d/20210216180616_incident_management_incident_change_confidential_weekly.yml) @@ -11832,7 +11832,7 @@ Tiers: `free`, `premium`, `ultimate` ### `redis_hll_counters.incident_management.incident_management_incident_closed_monthly` -Count of incidents closed per month +Count of users closing incidents per month [YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/metrics/counts_28d/20210216180548_incident_management_incident_closed_monthly.yml) @@ -11844,7 +11844,7 @@ Tiers: `free`, `premium`, `ultimate` ### `redis_hll_counters.incident_management.incident_management_incident_closed_weekly` -Count of incidents closed per week +Count of users closing incidents per week [YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/metrics/counts_7d/20210216180546_incident_management_incident_closed_weekly.yml) @@ -11856,7 +11856,7 @@ Tiers: `free`, `premium`, `ultimate` ### `redis_hll_counters.incident_management.incident_management_incident_comment_monthly` -Count of comments per month on incidents +Count of unique users adding comments per month on incidents [YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/metrics/counts_28d/20210216180559_incident_management_incident_comment_monthly.yml) @@ -11868,7 +11868,7 @@ Tiers: `free`, `premium`, `ultimate` ### `redis_hll_counters.incident_management.incident_management_incident_comment_weekly` -Count of comments per week on incidents +Count of unique users adding comments on incidents per week [YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/metrics/counts_7d/20210216180558_incident_management_incident_comment_weekly.yml) @@ -11880,7 +11880,7 @@ Tiers: `free`, `premium`, `ultimate` ### `redis_hll_counters.incident_management.incident_management_incident_created_monthly` -Count of incidents created per month +Count of unique users creating incidents per month [YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/metrics/counts_28d/20210216180541_incident_management_incident_created_monthly.yml) @@ -11892,7 +11892,7 @@ Tiers: `free`, `premium`, `ultimate` ### `redis_hll_counters.incident_management.incident_management_incident_created_weekly` -Count of incidents created per week +Count of unique users creating incidents per week [YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/metrics/counts_7d/20210216180539_incident_management_incident_created_weekly.yml) @@ -11904,7 +11904,7 @@ Tiers: `free`, `premium`, `ultimate` ### `redis_hll_counters.incident_management.incident_management_incident_published_monthly` -Count of published incidents per month +Count of unique users that published incidents per month [YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/config/metrics/counts_28d/20210216180607_incident_management_incident_published_monthly.yml) @@ -11916,7 +11916,7 @@ Tiers: `free`, `premium`, `ultimate` ### `redis_hll_counters.incident_management.incident_management_incident_published_weekly` -Count of published incidents per week +Count of unique users that published incidents per week [YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/config/metrics/counts_7d/20210216180605_incident_management_incident_published_weekly.yml) @@ -11928,7 +11928,7 @@ Tiers: `free`, `premium`, `ultimate` ### `redis_hll_counters.incident_management.incident_management_incident_relate_monthly` -Count of issues added per month that are related to an incident +Count of unique users adding issues per month that are related to an incident [YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/metrics/counts_28d/20210216180611_incident_management_incident_relate_monthly.yml) @@ -11940,7 +11940,7 @@ Tiers: `free`, `premium`, `ultimate` ### `redis_hll_counters.incident_management.incident_management_incident_relate_weekly` -Count of issues added per week that are related to an incident +Count of unique users adding issues per that are related to an incident week [YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/metrics/counts_7d/20210216180609_incident_management_incident_relate_weekly.yml) @@ -11952,7 +11952,7 @@ Tiers: `free`, `premium`, `ultimate` ### `redis_hll_counters.incident_management.incident_management_incident_reopened_monthly` -Count of incidents reopened per month +Count of unique users reopening incidents per month [YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/metrics/counts_28d/20210216180545_incident_management_incident_reopened_monthly.yml) @@ -11964,7 +11964,7 @@ Tiers: `free`, `premium`, `ultimate` ### `redis_hll_counters.incident_management.incident_management_incident_reopened_weekly` -Count of incidents reopened per week +Count of unique users reopening incidents per week [YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/metrics/counts_7d/20210216180543_incident_management_incident_reopened_weekly.yml) @@ -11976,7 +11976,7 @@ Tiers: `free`, `premium`, `ultimate` ### `redis_hll_counters.incident_management.incident_management_incident_todo_monthly` -Count of incidents added to the TODO list per month +Count of unique users adding incidents to the TODO list per month [YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/metrics/counts_28d/20210216180556_incident_management_incident_todo_monthly.yml) @@ -11988,7 +11988,7 @@ Tiers: `free`, `premium`, `ultimate` ### `redis_hll_counters.incident_management.incident_management_incident_todo_weekly` -Count of incidents added to the TODO list per week +Count of unique users adding incidents to the TODO list per week [YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/metrics/counts_7d/20210216180554_incident_management_incident_todo_weekly.yml) @@ -12000,7 +12000,7 @@ Tiers: `free`, `premium`, `ultimate` ### `redis_hll_counters.incident_management.incident_management_incident_unrelate_monthly` -Count of issues removed per month that are related to an incident +Count of users removing issues that are related to an incident per month [YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/metrics/counts_28d/20210216180614_incident_management_incident_unrelate_monthly.yml) @@ -12012,7 +12012,7 @@ Tiers: `free`, `premium`, `ultimate` ### `redis_hll_counters.incident_management.incident_management_incident_unrelate_weekly` -Count of issues removed per week that are related to an incident +Count of unique users removing issue that are related to an incident per week [YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/metrics/counts_7d/20210216180612_incident_management_incident_unrelate_weekly.yml) @@ -12024,7 +12024,7 @@ Tiers: `free`, `premium`, `ultimate` ### `redis_hll_counters.incident_management.incident_management_incident_zoom_meeting_monthly` -Count of Zoom meetings about incidents per month +Count of users creating Zoom meetings about incidents per month [YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/metrics/counts_28d/20210216180603_incident_management_incident_zoom_meeting_monthly.yml) @@ -12036,7 +12036,7 @@ Tiers: `free`, `premium`, `ultimate` ### `redis_hll_counters.incident_management.incident_management_incident_zoom_meeting_weekly` -Count of Zoom meetings about incidents per week +Count of unique users creating Zoom meetings about incidents per week [YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/metrics/counts_7d/20210216180601_incident_management_incident_zoom_meeting_weekly.yml) @@ -12048,7 +12048,7 @@ Tiers: `free`, `premium`, `ultimate` ### `redis_hll_counters.incident_management.incident_management_total_unique_counts_monthly` -Count of total unique incidents per month +Count of unique users performing events related with incidents per month [YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/metrics/counts_28d/20210216180622_incident_management_total_unique_counts_monthly.yml) @@ -12060,7 +12060,7 @@ Tiers: `free`, `premium`, `ultimate` ### `redis_hll_counters.incident_management.incident_management_total_unique_counts_weekly` -Count of total unique incidents per week +Count of unique users performing events related to the incident management [YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/metrics/counts_7d/20210216180620_incident_management_total_unique_counts_weekly.yml) @@ -12934,6 +12934,30 @@ Status: `data_available` Tiers: `free`, `premium`, `ultimate` +### `redis_hll_counters.network_policies.clusters_using_network_policies_ui_monthly` + +Monthly number of distinct clusters with network policies using the network policies UI + +[YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/config/metrics/counts_28d/20210623202402_clusters_using_network_policies_ui_monthly.yml) + +Group: `group::container security` + +Status: `implemented` + +Tiers: `ultimate` + +### `redis_hll_counters.network_policies.clusters_using_network_policies_ui_weekly` + +Weekly number of distinct clusters with network policies using the network policies UI + +[YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/config/metrics/counts_7d/20210623202358_clusters_using_network_policies_ui_weekly.yml) + +Group: `group::container security` + +Status: `implemented` + +Tiers: `ultimate` + ### `redis_hll_counters.pipeline_authoring.o_pipeline_authoring_unique_users_committing_ciconfigfile_monthly` Monthly unique user count doing commits which contains the CI config file diff --git a/doc/user/profile/personal_access_tokens.md b/doc/user/profile/personal_access_tokens.md index b31b56515cf..0dbf00a83fb 100644 --- a/doc/user/profile/personal_access_tokens.md +++ b/doc/user/profile/personal_access_tokens.md @@ -11,6 +11,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w > - [Notifications for expiring tokens](https://gitlab.com/gitlab-org/gitlab/-/issues/3649) added in GitLab 12.6. > - [Token lifetime limits](https://gitlab.com/gitlab-org/gitlab/-/issues/3649) added in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.6. > - [Additional notifications for expiring tokens](https://gitlab.com/gitlab-org/gitlab/-/issues/214721) added in GitLab 13.3. +> - [Prefill token name and scopes](https://gitlab.com/gitlab-org/gitlab/-/issues/334664) added in GitLab 14.1. If you're unable to use [OAuth2](../../api/oauth2.md), you can use a personal access token to authenticate with the [GitLab API](../../api/index.md#personalproject-access-tokens). You can also use a personal access token with Git to authenticate over HTTP. @@ -37,6 +38,16 @@ You can create as many personal access tokens as you like. Save the personal access token somewhere safe. After you leave the page, you no longer have access to the token. +### Prefill personal access token name and scopes + +You can link directly to the Personal Access Token page and have the form prefilled with a name and +list of scopes. To do this, you can append a `name` parameter and a list of comma-separated scopes +to the URL. For example: + +```plaintext +https://gitlab.example.com/-/profile/personal_access_tokens?name=Example+Access+token&scopes=api,read_user,read_registry +``` + ## Revoke a personal access token At any time, you can revoke a personal access token. diff --git a/lib/gitlab/content_security_policy/config_loader.rb b/lib/gitlab/content_security_policy/config_loader.rb index d7b31946ab0..842920ba02e 100644 --- a/lib/gitlab/content_security_policy/config_loader.rb +++ b/lib/gitlab/content_security_policy/config_loader.rb @@ -37,6 +37,7 @@ module Gitlab allow_webpack_dev_server(settings_hash) if Rails.env.development? allow_cdn(settings_hash) if ENV['GITLAB_CDN_HOST'].present? + allow_customersdot(settings_hash) if Rails.env.development? && ENV['CUSTOMER_PORTAL_URL'].present? settings_hash end @@ -85,6 +86,12 @@ module Gitlab def self.append_to_directive(settings_hash, directive, text) settings_hash['directives'][directive] = "#{settings_hash['directives'][directive]} #{text}".strip end + + def self.allow_customersdot(settings_hash) + customersdot_host = ENV['CUSTOMER_PORTAL_URL'] + + append_to_directive(settings_hash, 'frame_src', customersdot_host) + end end end end diff --git a/lib/gitlab/sidekiq_middleware/client_metrics.rb b/lib/gitlab/sidekiq_middleware/client_metrics.rb index 6bc08a97c07..e3cc7b28c41 100644 --- a/lib/gitlab/sidekiq_middleware/client_metrics.rb +++ b/lib/gitlab/sidekiq_middleware/client_metrics.rb @@ -15,6 +15,7 @@ module Gitlab # worker_class can either be the string or class of the worker being enqueued. worker_class = worker_class.safe_constantize if worker_class.respond_to?(:safe_constantize) labels = create_labels(worker_class, queue, job) + labels[:scheduling] = job.key?('at') ? 'delayed' : 'immediate' @metrics.fetch(ENQUEUED).increment(labels, 1) diff --git a/lib/gitlab/usage_data_counters/known_events/common.yml b/lib/gitlab/usage_data_counters/known_events/common.yml index f2e45a52434..fe1eb090fa4 100644 --- a/lib/gitlab/usage_data_counters/known_events/common.yml +++ b/lib/gitlab/usage_data_counters/known_events/common.yml @@ -369,3 +369,8 @@ category: testing aggregation: weekly feature_flag: users_expanding_widgets_usage_data +# Container Security - Network Policies +- name: clusters_using_network_policies_ui + redis_slot: network_policies + category: network_policies + aggregation: weekly diff --git a/lib/tasks/gitlab/db.rake b/lib/tasks/gitlab/db.rake index d3e0080b3b9..68705a55602 100644 --- a/lib/tasks/gitlab/db.rake +++ b/lib/tasks/gitlab/db.rake @@ -114,7 +114,7 @@ namespace :gitlab do end desc 'Create missing dynamic database partitions' - task :create_dynamic_partitions do + task create_dynamic_partitions: :environment do Gitlab::Database::Partitioning::PartitionCreator.new.create_partitions end diff --git a/spec/controllers/profiles/personal_access_tokens_controller_spec.rb b/spec/controllers/profiles/personal_access_tokens_controller_spec.rb index 1fdd1200028..3859af66292 100644 --- a/spec/controllers/profiles/personal_access_tokens_controller_spec.rb +++ b/spec/controllers/profiles/personal_access_tokens_controller_spec.rb @@ -64,5 +64,17 @@ RSpec.describe Profiles::PersonalAccessTokensController do it "retrieves newly created personal access token value" do expect(assigns(:new_personal_access_token)).to eql(token_value) end + + it "sets PAT name and scopes" do + name = 'My PAT' + scopes = 'api,read_user' + + get :index, params: { name: name, scopes: scopes } + + expect(assigns(:personal_access_token)).to have_attributes( + name: eq(name), + scopes: contain_exactly(:api, :read_user) + ) + end end end diff --git a/spec/features/profiles/personal_access_tokens_spec.rb b/spec/features/profiles/personal_access_tokens_spec.rb index 1166ebd944f..de511e99182 100644 --- a/spec/features/profiles/personal_access_tokens_spec.rb +++ b/spec/features/profiles/personal_access_tokens_spec.rb @@ -149,4 +149,15 @@ RSpec.describe 'Profile > Personal Access Tokens', :js do expect(page).to have_pushed_frontend_feature_flags(personalAccessTokensScopedToProjects: true) end + + it "prefills token details" do + name = 'My PAT' + scopes = 'api,read_user' + + visit profile_personal_access_tokens_path({ name: name, scopes: scopes }) + + expect(page).to have_field("Token name", with: name) + expect(find("#personal_access_token_scopes_api")).to be_checked + expect(find("#personal_access_token_scopes_read_user")).to be_checked + end end diff --git a/spec/frontend/diffs/components/app_spec.js b/spec/frontend/diffs/components/app_spec.js index 8a1c5547581..b5eb3e1713c 100644 --- a/spec/frontend/diffs/components/app_spec.js +++ b/spec/frontend/diffs/components/app_spec.js @@ -6,14 +6,19 @@ import Vue, { nextTick } from 'vue'; import Vuex from 'vuex'; import { TEST_HOST } from 'spec/test_constants'; import App from '~/diffs/components/app.vue'; -import CollapsedFilesWarning from '~/diffs/components/collapsed_files_warning.vue'; import CommitWidget from '~/diffs/components/commit_widget.vue'; import CompareVersions from '~/diffs/components/compare_versions.vue'; import DiffFile from '~/diffs/components/diff_file.vue'; -import HiddenFilesWarning from '~/diffs/components/hidden_files_warning.vue'; import NoChanges from '~/diffs/components/no_changes.vue'; import TreeList from '~/diffs/components/tree_list.vue'; +/* eslint-disable import/order */ +/* You know what: sometimes alphabetical isn't the best order */ +import CollapsedFilesWarning from '~/diffs/components/collapsed_files_warning.vue'; +import HiddenFilesWarning from '~/diffs/components/hidden_files_warning.vue'; +import MergeConflictWarning from '~/diffs/components/merge_conflict_warning.vue'; +/* eslint-enable import/order */ + import axios from '~/lib/utils/axios_utils'; import * as urlUtils from '~/lib/utils/url_utility'; import createDiffsStore from '../create_diffs_store'; @@ -541,6 +546,43 @@ describe('diffs/components/app', () => { expect(getCollapsedFilesWarning(wrapper).exists()).toBe(false); }); }); + + describe('merge conflicts', () => { + it('should render the merge conflicts banner if viewing the whole changeset and there are conflicts', () => { + createComponent({}, ({ state }) => { + Object.assign(state.diffs, { + latestDiff: true, + startVersion: null, + hasConflicts: true, + canMerge: false, + conflictResolutionPath: 'path', + }); + }); + + expect(wrapper.find(MergeConflictWarning).exists()).toBe(true); + }); + + it.each` + prop | value + ${'latestDiff'} | ${false} + ${'startVersion'} | ${'notnull'} + ${'hasConflicts'} | ${false} + `( + "should not render if any of the MR properties aren't correct - like $prop: $value", + ({ prop, value }) => { + createComponent({}, ({ state }) => { + Object.assign(state.diffs, { + latestDiff: true, + startVersion: null, + hasConflicts: true, + [prop]: value, + }); + }); + + expect(wrapper.find(MergeConflictWarning).exists()).toBe(false); + }, + ); + }); }); it('should display commit widget if store has a commit', () => { diff --git a/spec/frontend/tracking_spec.js b/spec/frontend/tracking_spec.js index d8dae2b2dc0..13498cfb823 100644 --- a/spec/frontend/tracking_spec.js +++ b/spec/frontend/tracking_spec.js @@ -197,6 +197,52 @@ describe('Tracking', () => { expectedError, ); }); + + it('does not add empty form whitelist rules', () => { + Tracking.enableFormTracking({ fields: { allow: ['input-class1'] } }); + + expect(snowplowSpy).toHaveBeenCalledWith( + 'enableFormTracking', + { fields: { whitelist: ['input-class1'] } }, + [], + ); + }); + + describe('when `document.readyState` does not equal `complete`', () => { + const originalReadyState = document.readyState; + const setReadyState = (value) => { + Object.defineProperty(document, 'readyState', { + value, + configurable: true, + }); + }; + const fireReadyStateChangeEvent = () => { + document.dispatchEvent(new Event('readystatechange')); + }; + + beforeEach(() => { + setReadyState('interactive'); + }); + + afterEach(() => { + setReadyState(originalReadyState); + }); + + it('does not call `window.snowplow` until `readystatechange` is fired and `document.readyState` equals `complete`', () => { + Tracking.enableFormTracking({ fields: { allow: ['input-class1'] } }); + + expect(snowplowSpy).not.toHaveBeenCalled(); + + fireReadyStateChangeEvent(); + + expect(snowplowSpy).not.toHaveBeenCalled(); + + setReadyState('complete'); + fireReadyStateChangeEvent(); + + expect(snowplowSpy).toHaveBeenCalled(); + }); + }); }); describe('.flushPendingEvents', () => { diff --git a/spec/lib/gitlab/content_security_policy/config_loader_spec.rb b/spec/lib/gitlab/content_security_policy/config_loader_spec.rb index d08057fb10a..8e63e771caa 100644 --- a/spec/lib/gitlab/content_security_policy/config_loader_spec.rb +++ b/spec/lib/gitlab/content_security_policy/config_loader_spec.rb @@ -61,6 +61,36 @@ RSpec.describe Gitlab::ContentSecurityPolicy::ConfigLoader do expect(directives['font_src']).to eq("'self' https://example.com") end end + + context 'when CUSTOMER_PORTAL_URL is set' do + before do + stub_env('CUSTOMER_PORTAL_URL', 'https://customers.example.com') + end + + context 'when in production' do + before do + allow(Rails).to receive(:env).and_return(ActiveSupport::StringInquirer.new('production')) + end + + it 'does not add CUSTOMER_PORTAL_URL to CSP' do + directives = settings['directives'] + + expect(directives['frame_src']).to eq("'self' https://www.google.com/recaptcha/ https://www.recaptcha.net/ https://content.googleapis.com https://content-compute.googleapis.com https://content-cloudbilling.googleapis.com https://content-cloudresourcemanager.googleapis.com") + end + end + + context 'when in development' do + before do + allow(Rails).to receive(:env).and_return(ActiveSupport::StringInquirer.new('development')) + end + + it 'adds CUSTOMER_PORTAL_URL to CSP' do + directives = settings['directives'] + + expect(directives['frame_src']).to eq("'self' https://www.google.com/recaptcha/ https://www.recaptcha.net/ https://content.googleapis.com https://content-compute.googleapis.com https://content-cloudbilling.googleapis.com https://content-cloudresourcemanager.googleapis.com https://customers.example.com") + end + end + end end describe '#load' do diff --git a/spec/lib/gitlab/sidekiq_middleware/client_metrics_spec.rb b/spec/lib/gitlab/sidekiq_middleware/client_metrics_spec.rb index 82ca84f0697..698758a13fd 100644 --- a/spec/lib/gitlab/sidekiq_middleware/client_metrics_spec.rb +++ b/spec/lib/gitlab/sidekiq_middleware/client_metrics_spec.rb @@ -3,11 +3,12 @@ require 'spec_helper' RSpec.describe Gitlab::SidekiqMiddleware::ClientMetrics do + let(:enqueued_jobs_metric) { double('enqueued jobs metric', increment: true) } + shared_examples "a metrics middleware" do context "with mocked prometheus" do - let(:enqueued_jobs_metric) { double('enqueued jobs metric', increment: true) } - before do + labels[:scheduling] = 'immediate' allow(Gitlab::Metrics).to receive(:counter).with(described_class::ENQUEUED, anything).and_return(enqueued_jobs_metric) end @@ -32,4 +33,35 @@ RSpec.describe Gitlab::SidekiqMiddleware::ClientMetrics do end it_behaves_like 'metrics middleware with worker attribution' + + context 'when mounted' do + before do + stub_const('TestWorker', Class.new) + TestWorker.class_eval do + include Sidekiq::Worker + + def perform(*args) + end + end + + allow(Gitlab::Metrics).to receive(:counter).and_return(Gitlab::Metrics::NullMetric.instance) + allow(Gitlab::Metrics).to receive(:counter).with(described_class::ENQUEUED, anything).and_return(enqueued_jobs_metric) + end + + context 'when scheduling jobs for immediate execution' do + it 'increments enqueued jobs metric with scheduling label set to immediate' do + expect(enqueued_jobs_metric).to receive(:increment).with(a_hash_including(scheduling: 'immediate'), 1) + + Sidekiq::Testing.inline! { TestWorker.perform_async } + end + end + + context 'when scheduling jobs for future execution' do + it 'increments enqueued jobs metric with scheduling label set to delayed' do + expect(enqueued_jobs_metric).to receive(:increment).with(a_hash_including(scheduling: 'delayed'), 1) + + Sidekiq::Testing.inline! { TestWorker.perform_in(1.second) } + end + end + end end diff --git a/spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb b/spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb index 4efacae0a48..d89202ae7fe 100644 --- a/spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb +++ b/spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb @@ -46,7 +46,8 @@ RSpec.describe Gitlab::UsageDataCounters::HLLRedisCounter, :clean_gitlab_redis_s 'pipeline_authoring', 'epics_usage', 'epic_boards_usage', - 'secure' + 'secure', + 'network_policies' ) end end diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb index 8652f9c4a58..145ca750ad6 100644 --- a/spec/lib/gitlab/usage_data_spec.rb +++ b/spec/lib/gitlab/usage_data_spec.rb @@ -1269,7 +1269,7 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do let(:categories) { ::Gitlab::UsageDataCounters::HLLRedisCounter.categories } let(:ineligible_total_categories) do - %w[source_code ci_secrets_management incident_management_alerts snippets terraform incident_management_oncall secure] + %w[source_code ci_secrets_management incident_management_alerts snippets terraform incident_management_oncall secure network_policies] end context 'with redis_hll_tracking feature enabled' do diff --git a/spec/models/integrations/ewm_spec.rb b/spec/models/integrations/ewm_spec.rb index 38897adb447..2baf670f4ae 100644 --- a/spec/models/integrations/ewm_spec.rb +++ b/spec/models/integrations/ewm_spec.rb @@ -9,7 +9,7 @@ RSpec.describe Integrations::Ewm do end describe 'Validations' do - context 'when service is active' do + context 'when integration is active' do before do subject.active = true end @@ -17,12 +17,12 @@ RSpec.describe Integrations::Ewm do it { is_expected.to validate_presence_of(:project_url) } it { is_expected.to validate_presence_of(:issues_url) } it { is_expected.to validate_presence_of(:new_issue_url) } - it_behaves_like 'issue tracker service URL attribute', :project_url - it_behaves_like 'issue tracker service URL attribute', :issues_url - it_behaves_like 'issue tracker service URL attribute', :new_issue_url + it_behaves_like 'issue tracker integration URL attribute', :project_url + it_behaves_like 'issue tracker integration URL attribute', :issues_url + it_behaves_like 'issue tracker integration URL attribute', :new_issue_url end - context 'when service is inactive' do + context 'when integration is inactive' do before do subject.active = false end diff --git a/spec/models/integrations/jira_spec.rb b/spec/models/integrations/jira_spec.rb index d63f5261915..37a0920153e 100644 --- a/spec/models/integrations/jira_spec.rb +++ b/spec/models/integrations/jira_spec.rb @@ -100,9 +100,9 @@ RSpec.describe Integrations::Jira do end describe '#fields' do - let(:service) { create(:jira_integration) } + let(:integration) { create(:jira_integration) } - subject(:fields) { service.fields } + subject(:fields) { integration.fields } it 'returns custom fields' do expect(fields.pluck(:name)).to eq(%w[url api_url username password]) @@ -146,39 +146,35 @@ RSpec.describe Integrations::Jira do } end - subject { described_class.create!(params) } + subject(:integration) { described_class.create!(params) } it 'does not store data into properties' do - expect(subject.properties).to be_nil + expect(integration.properties).to be_nil end it 'stores data in data_fields correctly' do - service = subject - - expect(service.jira_tracker_data.url).to eq(url) - expect(service.jira_tracker_data.api_url).to eq(api_url) - expect(service.jira_tracker_data.username).to eq(username) - expect(service.jira_tracker_data.password).to eq(password) - expect(service.jira_tracker_data.jira_issue_transition_id).to eq(transition_id) - expect(service.jira_tracker_data.deployment_cloud?).to be_truthy + expect(integration.jira_tracker_data.url).to eq(url) + expect(integration.jira_tracker_data.api_url).to eq(api_url) + expect(integration.jira_tracker_data.username).to eq(username) + expect(integration.jira_tracker_data.password).to eq(password) + expect(integration.jira_tracker_data.jira_issue_transition_id).to eq(transition_id) + expect(integration.jira_tracker_data.deployment_cloud?).to be_truthy end context 'when loading serverInfo' do - let(:jira_integration) { subject } - - context 'from a Cloud instance' do + context 'with a Cloud instance' do let(:server_info_results) { { 'deploymentType' => 'Cloud' } } it 'is detected' do - expect(jira_integration.jira_tracker_data.deployment_cloud?).to be_truthy + expect(integration.jira_tracker_data).to be_deployment_cloud end end - context 'from a Server instance' do + context 'with a Server instance' do let(:server_info_results) { { 'deploymentType' => 'Server' } } it 'is detected' do - expect(jira_integration.jira_tracker_data.deployment_server?).to be_truthy + expect(integration.jira_tracker_data).to be_deployment_server end end @@ -189,7 +185,7 @@ RSpec.describe Integrations::Jira do let(:api_url) { 'http://example-api.atlassian.net' } it 'deployment_type is set to cloud' do - expect(jira_integration.jira_tracker_data.deployment_cloud?).to be_truthy + expect(integration.jira_tracker_data).to be_deployment_cloud end end @@ -197,7 +193,7 @@ RSpec.describe Integrations::Jira do let(:api_url) { 'http://my-jira-api.someserver.com' } it 'deployment_type is set to server' do - expect(jira_integration.jira_tracker_data.deployment_server?).to be_truthy + expect(integration.jira_tracker_data).to be_deployment_server end end end @@ -210,7 +206,7 @@ RSpec.describe Integrations::Jira do it 'deployment_type is set to cloud' do expect(Gitlab::AppLogger).to receive(:warn).with(message: "Jira API returned no ServerInfo, setting deployment_type from URL", server_info: server_info_results, url: api_url) - expect(jira_integration.jira_tracker_data.deployment_cloud?).to be_truthy + expect(integration.jira_tracker_data).to be_deployment_cloud end end @@ -219,7 +215,7 @@ RSpec.describe Integrations::Jira do it 'deployment_type is set to server' do expect(Gitlab::AppLogger).to receive(:warn).with(message: "Jira API returned no ServerInfo, setting deployment_type from URL", server_info: server_info_results, url: api_url) - expect(jira_integration.jira_tracker_data.deployment_server?).to be_truthy + expect(integration.jira_tracker_data).to be_deployment_server end end end @@ -253,11 +249,11 @@ RSpec.describe Integrations::Jira do context 'reading data' do it 'reads data correctly' do - expect(service.url).to eq(url) - expect(service.api_url).to eq(api_url) - expect(service.username).to eq(username) - expect(service.password).to eq(password) - expect(service.jira_issue_transition_id).to eq(transition_id) + expect(integration.url).to eq(url) + expect(integration.api_url).to eq(api_url) + expect(integration.username).to eq(username) + expect(integration.password).to eq(password) + expect(integration.jira_issue_transition_id).to eq(transition_id) end end @@ -267,15 +263,11 @@ RSpec.describe Integrations::Jira do let_it_be(:new_url) { 'http://jira-new.example.com' } before do - service.update!(username: new_username, url: new_url) - end - - it 'leaves properties field emtpy' do - # expect(service.reload.properties).to be_empty + integration.update!(username: new_username, url: new_url) end it 'stores updated data in jira_tracker_data table' do - data = service.jira_tracker_data.reload + data = integration.jira_tracker_data.reload expect(data.url).to eq(new_url) expect(data.api_url).to eq(api_url) @@ -288,15 +280,15 @@ RSpec.describe Integrations::Jira do context 'when updating the url, api_url, username, or password' do context 'when updating the integration' do it 'updates deployment type' do - service.update!(url: 'http://first.url') - service.jira_tracker_data.update!(deployment_type: 'server') + integration.update!(url: 'http://first.url') + integration.jira_tracker_data.update!(deployment_type: 'server') - expect(service.jira_tracker_data.deployment_server?).to be_truthy + expect(integration.jira_tracker_data.deployment_server?).to be_truthy - service.update!(api_url: 'http://another.url') - service.jira_tracker_data.reload + integration.update!(api_url: 'http://another.url') + integration.jira_tracker_data.reload - expect(service.jira_tracker_data.deployment_cloud?).to be_truthy + expect(integration.jira_tracker_data.deployment_cloud?).to be_truthy expect(WebMock).to have_requested(:get, /serverInfo/).twice end end @@ -305,34 +297,34 @@ RSpec.describe Integrations::Jira do let(:server_info_results) { {} } it 'updates deployment type' do - service.update!(url: nil, api_url: nil, active: false) + integration.update!(url: nil, api_url: nil, active: false) - service.jira_tracker_data.reload + integration.jira_tracker_data.reload - expect(service.jira_tracker_data.deployment_unknown?).to be_truthy + expect(integration.jira_tracker_data.deployment_unknown?).to be_truthy end end it 'calls serverInfo for url' do - service.update!(url: 'http://first.url') + integration.update!(url: 'http://first.url') expect(WebMock).to have_requested(:get, /serverInfo/) end it 'calls serverInfo for api_url' do - service.update!(api_url: 'http://another.url') + integration.update!(api_url: 'http://another.url') expect(WebMock).to have_requested(:get, /serverInfo/) end it 'calls serverInfo for username' do - service.update!(username: 'test-user') + integration.update!(username: 'test-user') expect(WebMock).to have_requested(:get, /serverInfo/) end it 'calls serverInfo for password' do - service.update!(password: 'test-password') + integration.update!(password: 'test-password') expect(WebMock).to have_requested(:get, /serverInfo/) end @@ -340,7 +332,8 @@ RSpec.describe Integrations::Jira do context 'when not updating the url, api_url, username, or password' do it 'does not update deployment type' do - expect {service.update!(jira_issue_transition_id: 'jira_issue_transition_id')}.to raise_error(ActiveRecord::RecordInvalid) + expect { integration.update!(jira_issue_transition_id: 'jira_issue_transition_id') } + .to raise_error(ActiveRecord::RecordInvalid) expect(WebMock).not_to have_requested(:get, /serverInfo/) end @@ -348,9 +341,9 @@ RSpec.describe Integrations::Jira do context 'when not allowed to test an instance or group' do it 'does not update deployment type' do - allow(service).to receive(:can_test?).and_return(false) + allow(integration).to receive(:can_test?).and_return(false) - service.update!(url: 'http://first.url') + integration.update!(url: 'http://first.url') expect(WebMock).not_to have_requested(:get, /serverInfo/) end @@ -368,68 +361,68 @@ RSpec.describe Integrations::Jira do end it 'resets password if url changed' do - service - service.url = 'http://jira_edited.example.com' - service.save! + integration + integration.url = 'http://jira_edited.example.com' + integration.save! - expect(service.reload.url).to eq('http://jira_edited.example.com') - expect(service.password).to be_nil + expect(integration.reload.url).to eq('http://jira_edited.example.com') + expect(integration.password).to be_nil end it 'does not reset password if url "changed" to the same url as before' do - service.url = 'http://jira.example.com' - service.save! + integration.url = 'http://jira.example.com' + integration.save! - expect(service.reload.url).to eq('http://jira.example.com') - expect(service.password).not_to be_nil + expect(integration.reload.url).to eq('http://jira.example.com') + expect(integration.password).not_to be_nil end it 'resets password if url not changed but api url added' do - service.api_url = 'http://jira_edited.example.com/rest/api/2' - service.save! + integration.api_url = 'http://jira_edited.example.com/rest/api/2' + integration.save! - expect(service.reload.api_url).to eq('http://jira_edited.example.com/rest/api/2') - expect(service.password).to be_nil + expect(integration.reload.api_url).to eq('http://jira_edited.example.com/rest/api/2') + expect(integration.password).to be_nil end it 'does not reset password if new url is set together with password, even if it\'s the same password' do - service.url = 'http://jira_edited.example.com' - service.password = password - service.save! + integration.url = 'http://jira_edited.example.com' + integration.password = password + integration.save! - expect(service.password).to eq(password) - expect(service.url).to eq('http://jira_edited.example.com') + expect(integration.password).to eq(password) + expect(integration.url).to eq('http://jira_edited.example.com') end it 'resets password if url changed, even if setter called multiple times' do - service.url = 'http://jira1.example.com/rest/api/2' - service.url = 'http://jira1.example.com/rest/api/2' - service.save! + integration.url = 'http://jira1.example.com/rest/api/2' + integration.url = 'http://jira1.example.com/rest/api/2' + integration.save! - expect(service.password).to be_nil + expect(integration.password).to be_nil end it 'does not reset password if username changed' do - service.username = 'some_name' - service.save! + integration.username = 'some_name' + integration.save! - expect(service.reload.password).to eq(password) + expect(integration.reload.password).to eq(password) end it 'does not reset password if password changed' do - service.url = 'http://jira_edited.example.com' - service.password = 'new_password' - service.save! + integration.url = 'http://jira_edited.example.com' + integration.password = 'new_password' + integration.save! - expect(service.reload.password).to eq('new_password') + expect(integration.reload.password).to eq('new_password') end it 'does not reset password if the password is touched and same as before' do - service.url = 'http://jira_edited.example.com' - service.password = password - service.save! + integration.url = 'http://jira_edited.example.com' + integration.password = password + integration.save! - expect(service.reload.password).to eq(password) + expect(integration.reload.password).to eq(password) end end @@ -443,23 +436,23 @@ RSpec.describe Integrations::Jira do end it 'resets password if api url changed' do - service.api_url = 'http://jira_edited.example.com/rest/api/2' - service.save! + integration.api_url = 'http://jira_edited.example.com/rest/api/2' + integration.save! - expect(service.password).to be_nil + expect(integration.password).to be_nil end it 'does not reset password if url changed' do - service.url = 'http://jira_edited.example.com' - service.save! + integration.url = 'http://jira_edited.example.com' + integration.save! - expect(service.password).to eq(password) + expect(integration.password).to eq(password) end it 'resets password if api url set to empty' do - service.update!(api_url: '') + integration.update!(api_url: '') - expect(service.reload.password).to be_nil + expect(integration.reload.password).to be_nil end end end @@ -472,11 +465,11 @@ RSpec.describe Integrations::Jira do end it 'saves password if new url is set together with password' do - service.url = 'http://jira_edited.example.com/rest/api/2' - service.password = 'password' - service.save! - expect(service.reload.password).to eq('password') - expect(service.reload.url).to eq('http://jira_edited.example.com/rest/api/2') + integration.url = 'http://jira_edited.example.com/rest/api/2' + integration.password = 'password' + integration.save! + expect(integration.reload.password).to eq('password') + expect(integration.reload.url).to eq('http://jira_edited.example.com/rest/api/2') end end end @@ -486,7 +479,7 @@ RSpec.describe Integrations::Jira do # this will be removed as part of https://gitlab.com/gitlab-org/gitlab/issues/29404 context 'when data are stored in properties' do let(:properties) { data_params } - let!(:service) do + let!(:integration) do create(:jira_integration, :without_properties_callback, properties: properties.merge(additional: 'something')) end @@ -494,7 +487,7 @@ RSpec.describe Integrations::Jira do end context 'when data are stored in separated fields' do - let(:service) do + let(:integration) do create(:jira_integration, data_params.merge(properties: {})) end @@ -503,7 +496,7 @@ RSpec.describe Integrations::Jira do context 'when data are stored in both properties and separated fields' do let(:properties) { data_params } - let(:service) do + let(:integration) do create(:jira_integration, :without_properties_callback, active: false, properties: properties).tap do |integration| create(:jira_tracker_data, data_params.merge(integration: integration)) end diff --git a/spec/models/integrations/microsoft_teams_spec.rb b/spec/models/integrations/microsoft_teams_spec.rb index a7b45ebec87..ab2846d8ccb 100644 --- a/spec/models/integrations/microsoft_teams_spec.rb +++ b/spec/models/integrations/microsoft_teams_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe Integrations::MicrosoftTeams do - let(:chat_service) { described_class.new } + let(:chat_integration) { described_class.new } let(:webhook_url) { 'https://example.gitlab.com/' } describe "Associations" do @@ -12,16 +12,16 @@ RSpec.describe Integrations::MicrosoftTeams do end describe 'Validations' do - context 'when service is active' do + context 'when integration is active' do before do subject.active = true end it { is_expected.to validate_presence_of(:webhook) } - it_behaves_like 'issue tracker service URL attribute', :webhook + it_behaves_like 'issue tracker integration URL attribute', :webhook end - context 'when service is inactive' do + context 'when integration is inactive' do before do subject.active = false end @@ -42,7 +42,7 @@ RSpec.describe Integrations::MicrosoftTeams do let_it_be(:project) { create(:project, :repository, :wiki_repo) } before do - allow(chat_service).to receive_messages( + allow(chat_integration).to receive_messages( project: project, project_id: project.id, service_hook: true, @@ -58,7 +58,7 @@ RSpec.describe Integrations::MicrosoftTeams do end it "calls Microsoft Teams API for push events" do - chat_service.execute(push_sample_data) + chat_integration.execute(push_sample_data) expect(WebMock).to have_requested(:post, webhook_url).once end @@ -67,7 +67,7 @@ RSpec.describe Integrations::MicrosoftTeams do integration = double(:microsoft_teams_integration).as_null_object expect(::MicrosoftTeams::Notifier).to receive(:new).with(webhook_url).and_return(integration) - chat_service.execute(push_sample_data) + chat_integration.execute(push_sample_data) end end @@ -80,7 +80,7 @@ RSpec.describe Integrations::MicrosoftTeams do end it "calls Microsoft Teams API" do - chat_service.execute(issues_sample_data) + chat_integration.execute(issues_sample_data) expect(WebMock).to have_requested(:post, webhook_url).once end @@ -107,7 +107,7 @@ RSpec.describe Integrations::MicrosoftTeams do end it "calls Microsoft Teams API" do - chat_service.execute(merge_sample_data) + chat_integration.execute(merge_sample_data) expect(WebMock).to have_requested(:post, webhook_url).once end @@ -127,7 +127,7 @@ RSpec.describe Integrations::MicrosoftTeams do let(:wiki_page_sample_data) { Gitlab::DataBuilder::WikiPage.build(wiki_page, user, 'create') } it "calls Microsoft Teams API" do - chat_service.execute(wiki_page_sample_data) + chat_integration.execute(wiki_page_sample_data) expect(WebMock).to have_requested(:post, webhook_url).once end @@ -139,7 +139,7 @@ RSpec.describe Integrations::MicrosoftTeams do let(:project) { create(:project, :repository, creator: user) } before do - allow(chat_service).to receive_messages( + allow(chat_integration).to receive_messages( project: project, project_id: project.id, service_hook: true, @@ -160,7 +160,7 @@ RSpec.describe Integrations::MicrosoftTeams do it "calls Microsoft Teams API for commit comment events" do data = Gitlab::DataBuilder::Note.build(commit_note, user) - chat_service.execute(data) + chat_integration.execute(data) expect(WebMock).to have_requested(:post, webhook_url).once end @@ -175,7 +175,7 @@ RSpec.describe Integrations::MicrosoftTeams do it "calls Microsoft Teams API for merge request comment events" do data = Gitlab::DataBuilder::Note.build(merge_request_note, user) - chat_service.execute(data) + chat_integration.execute(data) expect(WebMock).to have_requested(:post, webhook_url).once end @@ -189,7 +189,7 @@ RSpec.describe Integrations::MicrosoftTeams do it "calls Microsoft Teams API for issue comment events" do data = Gitlab::DataBuilder::Note.build(issue_note, user) - chat_service.execute(data) + chat_integration.execute(data) expect(WebMock).to have_requested(:post, webhook_url).once end @@ -204,7 +204,7 @@ RSpec.describe Integrations::MicrosoftTeams do it "calls Microsoft Teams API for snippet comment events" do data = Gitlab::DataBuilder::Note.build(snippet_note, user) - chat_service.execute(data) + chat_integration.execute(data) expect(WebMock).to have_requested(:post, webhook_url).once end @@ -222,7 +222,7 @@ RSpec.describe Integrations::MicrosoftTeams do end before do - allow(chat_service).to receive_messages( + allow(chat_integration).to receive_messages( project: project, service_hook: true, webhook: webhook_url @@ -232,14 +232,14 @@ RSpec.describe Integrations::MicrosoftTeams do shared_examples 'call Microsoft Teams API' do |branches_to_be_notified: nil| before do WebMock.stub_request(:post, webhook_url) - chat_service.branches_to_be_notified = branches_to_be_notified if branches_to_be_notified + chat_integration.branches_to_be_notified = branches_to_be_notified if branches_to_be_notified end it 'calls Microsoft Teams API for pipeline events' do data = Gitlab::DataBuilder::Pipeline.build(pipeline) data[:markdown] = true - chat_service.execute(data) + chat_integration.execute(data) message = Integrations::ChatMessage::PipelineMessage.new(data) @@ -251,11 +251,11 @@ RSpec.describe Integrations::MicrosoftTeams do shared_examples 'does not call Microsoft Teams API' do |branches_to_be_notified: nil| before do - chat_service.branches_to_be_notified = branches_to_be_notified if branches_to_be_notified + chat_integration.branches_to_be_notified = branches_to_be_notified if branches_to_be_notified end it 'does not call Microsoft Teams API for pipeline events' do data = Gitlab::DataBuilder::Pipeline.build(pipeline) - result = chat_service.execute(data) + result = chat_integration.execute(data) expect(result).to be_falsy end @@ -273,7 +273,7 @@ RSpec.describe Integrations::MicrosoftTeams do context 'with default to notify_only_broken_pipelines' do it 'does not call Microsoft Teams API for pipeline events' do data = Gitlab::DataBuilder::Pipeline.build(pipeline) - result = chat_service.execute(data) + result = chat_integration.execute(data) expect(result).to be_falsy end @@ -281,7 +281,7 @@ RSpec.describe Integrations::MicrosoftTeams do context 'with setting notify_only_broken_pipelines to false' do before do - chat_service.notify_only_broken_pipelines = false + chat_integration.notify_only_broken_pipelines = false end it_behaves_like 'call Microsoft Teams API' |