diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-06-07 09:09:00 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-06-07 09:09:00 +0000 |
commit | bdd03bc52aee1c3f37e25ae9b1fc8a27885b7428 (patch) | |
tree | e409a6e1f76d9dc69c5413a06e9b4c4b3f74fef7 | |
parent | bed53d96d214fd96ea688d3e86e53457ce50043e (diff) | |
download | gitlab-ce-bdd03bc52aee1c3f37e25ae9b1fc8a27885b7428.tar.gz |
Add latest changes from gitlab-org/gitlab@master
52 files changed, 323 insertions, 185 deletions
diff --git a/.gitlab/ci/global.gitlab-ci.yml b/.gitlab/ci/global.gitlab-ci.yml index 792e0ccc346..6a2c27a1c22 100644 --- a/.gitlab/ci/global.gitlab-ci.yml +++ b/.gitlab/ci/global.gitlab-ci.yml @@ -238,7 +238,7 @@ services: - name: postgres:13 command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"] - - name: redis:5.0-alpine + - name: redis:6.2-alpine variables: POSTGRES_HOST_AUTH_METHOD: trust PG_VERSION: "13" @@ -269,7 +269,7 @@ services: - name: postgres:13 command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"] - - name: redis:5.0-alpine + - name: redis:6.2-alpine - name: elasticsearch:7.17.0 command: ["elasticsearch", "-E", "discovery.type=single-node", "-E", "xpack.security.enabled=false"] variables: @@ -402,6 +402,8 @@ group :development, :test do gem 'test_file_finder', '~> 0.1.3' gem 'sigdump', '~> 0.2.4', require: 'sigdump/setup' + + gem 'pact', '~> 1.12' end group :development, :test, :danger do diff --git a/Gemfile.lock b/Gemfile.lock index d7d9a013f82..a0561ae2697 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -394,6 +394,8 @@ GEM rake ffi-yajl (2.3.4) libyajl2 (~> 1.2) + filelock (1.1.1) + find_a_port (1.0.1) flipper (0.21.0) flipper-active_record (0.21.0) activerecord (>= 5.0, < 7) @@ -914,6 +916,29 @@ GEM rubypants (~> 0.2) orm_adapter (0.5.0) os (1.1.1) + pact (1.59.0) + pact-mock_service (~> 3.0, >= 3.3.1) + pact-support (~> 1.15) + rack-test (>= 0.6.3, < 2.0.0) + rspec (~> 3.0) + term-ansicolor (~> 1.0) + thor (>= 0.20, < 2.0) + webrick (~> 1.3) + pact-mock_service (3.6.2) + filelock (~> 1.1) + find_a_port (~> 1.0.1) + json + pact-support (~> 1.12, >= 1.12.0) + rack (~> 2.0) + rspec (>= 2.14) + term-ansicolor (~> 1.0) + thor (>= 0.19, < 2.0) + webrick (~> 1.3) + pact-support (1.15.1) + awesome_print (~> 1.1) + randexp (~> 0.1.7) + rspec (>= 2.14) + term-ansicolor (~> 1.0) parallel (1.20.1) parser (3.1.2.0) ast (~> 2.4.1) @@ -1015,6 +1040,7 @@ GEM thor (~> 1.0) rainbow (3.0.0) rake (13.0.6) + randexp (0.1.7) rb-fsevent (0.10.4) rb-inotify (0.10.1) ffi (~> 1.0) @@ -1278,11 +1304,14 @@ GEM activesupport (>= 3) attr_required (>= 0.0.5) httpclient (>= 2.4) + sync (0.5.0) sys-filesystem (1.4.3) ffi (~> 1.1) sysexits (1.2.0) tanuki_emoji (0.6.0) temple (0.8.2) + term-ansicolor (1.7.1) + tins (~> 1.0) terminal-table (1.8.0) unicode-display_width (~> 1.1, >= 1.1.1) terser (1.0.2) @@ -1301,6 +1330,8 @@ GEM timecop (0.9.1) timeliness (0.3.10) timfel-krb5-auth (0.8.3) + tins (1.31.0) + sync toml-rb (2.0.1) citrus (~> 3.0, > 3.0) tomlrb (1.3.0) @@ -1595,6 +1626,7 @@ DEPENDENCIES omniauth-twitter (~> 1.4) omniauth_crowd (~> 2.4.0) org-ruby (~> 0.9.12) + pact (~> 1.12) parallel (~> 1.19) parslet (~> 1.8) peek (~> 1.1) diff --git a/app/assets/javascripts/design_management/pages/index.vue b/app/assets/javascripts/design_management/pages/index.vue index 915eb2aaee8..6dbf7585283 100644 --- a/app/assets/javascripts/design_management/pages/index.vue +++ b/app/assets/javascripts/design_management/pages/index.vue @@ -1,5 +1,6 @@ <script> import { GlLoadingIcon, GlButton, GlAlert, GlLink, GlSprintf } from '@gitlab/ui'; +import { GlBreakpointInstance } from '@gitlab/ui/dist/utils'; import VueDraggable from 'vuedraggable'; import permissionsQuery from 'shared_queries/design_management/design_permissions.query.graphql'; import getDesignListQuery from 'shared_queries/design_management/get_design_list.query.graphql'; @@ -97,6 +98,9 @@ export default { isSaving() { return this.filesToBeSaved.length > 0; }, + isMobile() { + return GlBreakpointInstance.getBreakpointSize() === 'xs'; + }, canCreateDesign() { return this.permissions.createDesign; }, @@ -429,7 +433,7 @@ export default { <vue-draggable v-else :value="designs" - :disabled="!isLatestVersion || isReorderingInProgress" + :disabled="!isLatestVersion || isReorderingInProgress || isMobile" v-bind="$options.dragOptions" tag="ol" draggable=".js-design-tile" diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_button.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_button.vue index 60111210f5d..9388ef4ba45 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_button.vue +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_button.vue @@ -2,6 +2,9 @@ import { GlButton, GlIcon } from '@gitlab/ui'; import { mapActions, mapGetters } from 'vuex'; +// @deprecated This component should only be used when there is no GraphQL API. +// In most cases you should use +// `app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget` instead. export default { components: { GlButton, diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_contents.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_contents.vue index 399db978b60..1064cbc26e3 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_contents.vue +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_contents.vue @@ -4,6 +4,9 @@ import { mapGetters, mapState } from 'vuex'; import DropdownContentsCreateView from './dropdown_contents_create_view.vue'; import DropdownContentsLabelsView from './dropdown_contents_labels_view.vue'; +// @deprecated This component should only be used when there is no GraphQL API. +// In most cases you should use +// `app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents.vue` instead. export default { components: { DropdownContentsLabelsView, diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_create_view.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_create_view.vue index 40c1808dfea..3ff3755de46 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_create_view.vue +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_create_view.vue @@ -2,6 +2,9 @@ import { GlTooltipDirective, GlButton, GlFormInput, GlLink, GlLoadingIcon } from '@gitlab/ui'; import { mapState, mapActions } from 'vuex'; +// @deprecated This component should only be used when there is no GraphQL API. +// In most cases you should use +// `app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view.vue` instead. export default { components: { GlButton, diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view.vue index 70627ec06ca..e235bfde394 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view.vue +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view.vue @@ -13,6 +13,9 @@ import { UP_KEY_CODE, DOWN_KEY_CODE, ENTER_KEY_CODE, ESC_KEY_CODE } from '~/lib/ import LabelItem from './label_item.vue'; +// @deprecated This component should only be used when there is no GraphQL API. +// In most cases you should use +// `app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view.vue` instead. export default { components: { GlIntersectionObserver, diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_title.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_title.vue index 18ebfe1dc9c..e4325492334 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_title.vue +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_title.vue @@ -2,6 +2,9 @@ import { GlButton, GlLoadingIcon } from '@gitlab/ui'; import { mapState, mapActions } from 'vuex'; +// @deprecated This component should only be used when there is no GraphQL API. +// In most cases you should use +// `app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_header.vue` instead. export default { components: { GlButton, diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_value.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_value.vue index 35ac9ef8565..e59d150dd43 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_value.vue +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_value.vue @@ -5,6 +5,9 @@ import { mapState } from 'vuex'; import { isScopedLabel } from '~/lib/utils/common_utils'; +// @deprecated This component should only be used when there is no GraphQL API. +// In most cases you should use +// `app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_value.vue` instead. export default { components: { GlLabel, diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_value_collapsed.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_value_collapsed.vue index 8a26c4a6618..5966c78aa51 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_value_collapsed.vue +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_value_collapsed.vue @@ -2,6 +2,9 @@ import { GlIcon, GlTooltipDirective } from '@gitlab/ui'; import { s__, sprintf } from '~/locale'; +// @deprecated This component should only be used when there is no GraphQL API. +// In most cases you should use +// `app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget` instead. export default { directives: { GlTooltip: GlTooltipDirective, diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/label_item.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/label_item.vue index 1f52f4c064f..154e3013acd 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/label_item.vue +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/label_item.vue @@ -2,6 +2,9 @@ import { GlLink, GlIcon } from '@gitlab/ui'; import { __ } from '~/locale'; +// @deprecated This component should only be used when there is no GraphQL API. +// In most cases you should use +// `app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/label_item.vue` instead. export default { functional: true, props: { diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/labels_select_root.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/labels_select_root.vue index b514e4a27af..b61996cdcdb 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/labels_select_root.vue +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/labels_select_root.vue @@ -15,6 +15,9 @@ import labelsSelectModule from './store'; Vue.use(Vuex); +// @deprecated This component should only be used when there is no GraphQL API. +// In most cases you should use +// `app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/labels_select_root.vue` instead. export default { store: new Vuex.Store(labelsSelectModule()), components: { diff --git a/app/assets/stylesheets/page_bundles/issues_show.scss b/app/assets/stylesheets/page_bundles/issues_show.scss index 4bfe8a3d620..c664e0a734e 100644 --- a/app/assets/stylesheets/page_bundles/issues_show.scss +++ b/app/assets/stylesheets/page_bundles/issues_show.scss @@ -24,8 +24,9 @@ /* The inside bullet aligns itself to the bottom, which we see when text to the right of * a multi-line list item wraps. We fix this by aligning it to the top, and excluding - * other elements adversely affected by this. Targeting ::marker doesn't seem to work. */ - > *:not(code):not(gl-emoji):not(input):not(.gl-label):not(.js-add-task) { + * other elements. Targeting ::marker doesn't seem to work, instead we exclude custom elements + * or anything with a class */ + > *:not(gl-emoji, code, [class]) { vertical-align: top; } diff --git a/app/controllers/ide_controller.rb b/app/controllers/ide_controller.rb index 2bcbf88039b..9fcb8385312 100644 --- a/app/controllers/ide_controller.rb +++ b/app/controllers/ide_controller.rb @@ -22,6 +22,11 @@ class IdeController < ApplicationController def index Gitlab::UsageDataCounters::WebIdeCounter.increment_views_count + + if project && Feature.enabled?(:route_hll_to_snowplow_phase2, project&.namespace) + Gitlab::Tracking.event(self.class.to_s, 'web_ide_views', + namespace: project&.namespace, user: current_user) + end end private diff --git a/db/migrate/20220607011733_add_phone_verification_code_enabled_to_application_settings.rb b/db/migrate/20220607011733_add_phone_verification_code_enabled_to_application_settings.rb new file mode 100644 index 00000000000..321e55a2abf --- /dev/null +++ b/db/migrate/20220607011733_add_phone_verification_code_enabled_to_application_settings.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +class AddPhoneVerificationCodeEnabledToApplicationSettings < Gitlab::Database::Migration[2.0] + def up + add_column :application_settings, + :phone_verification_code_enabled, + :boolean, + null: false, + default: false, + comment: 'JiHu-specific column' + end + + def down + remove_column :application_settings, :phone_verification_code_enabled + end +end diff --git a/db/schema_migrations/20220607011733 b/db/schema_migrations/20220607011733 new file mode 100644 index 00000000000..7581765679c --- /dev/null +++ b/db/schema_migrations/20220607011733 @@ -0,0 +1 @@ +2d4dd4b889b5fc9c3f329669734f086997ebb514ed62afe6ca4220fc525797c9
\ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index 9eff36609e7..1c1b57a6648 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -11320,6 +11320,7 @@ CREATE TABLE application_settings ( globally_allowed_ips text DEFAULT ''::text NOT NULL, container_registry_pre_import_tags_rate numeric(6,2) DEFAULT 0.5 NOT NULL, license_usage_data_exported boolean DEFAULT false NOT NULL, + phone_verification_code_enabled boolean DEFAULT false NOT NULL, CONSTRAINT app_settings_container_reg_cleanup_tags_max_list_size_positive CHECK ((container_registry_cleanup_tags_service_max_list_size >= 0)), CONSTRAINT app_settings_container_registry_pre_import_tags_rate_positive CHECK ((container_registry_pre_import_tags_rate >= (0)::numeric)), CONSTRAINT app_settings_dep_proxy_ttl_policies_worker_capacity_positive CHECK ((dependency_proxy_ttl_group_policy_worker_capacity >= 0)), @@ -11380,6 +11381,8 @@ COMMENT ON COLUMN application_settings.encrypted_dingtalk_app_secret IS 'JiHu-sp COMMENT ON COLUMN application_settings.encrypted_dingtalk_app_secret_iv IS 'JiHu-specific column'; +COMMENT ON COLUMN application_settings.phone_verification_code_enabled IS 'JiHu-specific column'; + CREATE SEQUENCE application_settings_id_seq START WITH 1 INCREMENT BY 1 diff --git a/doc/api/members.md b/doc/api/members.md index 1db9714bfd1..5002e1003e3 100644 --- a/doc/api/members.md +++ b/doc/api/members.md @@ -6,6 +6,8 @@ info: To determine the technical writer assigned to the Stage/Group associated w # Group and project members API **(FREE)** +> `created_by` field [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/28789) in GitLab 14.10. + ## Valid access levels The access levels are defined in the `Gitlab::Access` module. Currently, these levels are recognized: diff --git a/doc/user/analytics/value_stream_analytics.md b/doc/user/analytics/value_stream_analytics.md index afefbee7ca0..c0f97369740 100644 --- a/doc/user/analytics/value_stream_analytics.md +++ b/doc/user/analytics/value_stream_analytics.md @@ -44,7 +44,7 @@ To view value stream analytics for your project: - In the **To** field, select an end date. 1. Optional. Sort results by ascending or descending: - To sort by most recent or oldest workflow item, select the **Last event** header. - - To sort by most or least amount of time spent in each stage, select the **Time** header. + - To sort by most or least amount of time spent in each stage, select the **Duration** header. The table shows a list of related workflow items for the selected stage. Based on the stage you choose, this can be: diff --git a/doc/user/group/value_stream_analytics/index.md b/doc/user/group/value_stream_analytics/index.md index c2b729ebcc2..72d42a8081f 100644 --- a/doc/user/group/value_stream_analytics/index.md +++ b/doc/user/group/value_stream_analytics/index.md @@ -51,7 +51,7 @@ To view value stream analytics for your group: during the date range. 1. Optional. Sort results by ascending or descending: - To sort by most recent or oldest workflow item, select the **Last event** header. - - To sort by most or least amount of time spent in each stage, select the **Time** header. + - To sort by most or least amount of time spent in each stage, select the **Duration** header. A badge next to the workflow items table header shows the number of workflow items that completed during the selected stage. diff --git a/qa/tasks/contracts.rake b/lib/tasks/contracts.rake index 682ec0e2e21..75c350f5be5 100644 --- a/qa/tasks/contracts.rake +++ b/lib/tasks/contracts.rake @@ -1,8 +1,10 @@ # frozen_string_literal: true +return if Rails.env.production? + require 'pact/tasks/verification_task' -contracts = File.expand_path('../contracts', __dir__) +contracts = File.expand_path('../../spec/contracts', __dir__) provider = File.expand_path('provider', contracts) # rubocop:disable Rails/RakeEnvironment @@ -11,21 +13,21 @@ namespace :contracts do Pact::VerificationTask.new(:metadata) do |pact| pact.uri( "#{contracts}/contracts/merge_request_page-merge_request_metadata_endpoint.json", - pact_helper: "#{provider}/spec/metadata_helper.rb" + pact_helper: "#{provider}/specs/metadata_helper.rb" ) end Pact::VerificationTask.new(:discussions) do |pact| pact.uri( "#{contracts}/contracts/merge_request_page-merge_request_discussions_endpoint.json", - pact_helper: "#{provider}/spec/discussions_helper.rb" + pact_helper: "#{provider}/specs/discussions_helper.rb" ) end Pact::VerificationTask.new(:diffs) do |pact| pact.uri( "#{contracts}/contracts/merge_request_page-merge_request_diffs_endpoint.json", - pact_helper: "#{provider}/spec/diffs_helper.rb" + pact_helper: "#{provider}/specs/diffs_helper.rb" ) end diff --git a/qa/Gemfile b/qa/Gemfile index 28fd1c9394d..d8d00400563 100644 --- a/qa/Gemfile +++ b/qa/Gemfile @@ -35,8 +35,6 @@ gem 'confiner', '~> 0.3' gem 'chemlab', '~> 0.9' gem 'chemlab-library-www-gitlab-com', '~> 0.1' -gem "pact", "~> 1.12" - gem 'deprecation_toolkit', '~> 1.5.1', require: false group :development do diff --git a/qa/Gemfile.lock b/qa/Gemfile.lock index ca23c4ac39d..3b89c3ece56 100644 --- a/qa/Gemfile.lock +++ b/qa/Gemfile.lock @@ -28,7 +28,6 @@ GEM require_all (>= 2, < 4) uuid (>= 2.3, < 3) ast (2.4.2) - awesome_print (1.9.2) binding_ninja (0.2.3) builder (3.2.4) byebug (9.1.0) @@ -92,8 +91,6 @@ GEM ffi-compiler (1.0.1) ffi (>= 1.0.0) rake - filelock (1.1.1) - find_a_port (1.0.1) fog-core (2.1.0) builder excon (~> 0.58) @@ -177,7 +174,6 @@ GEM concurrent-ruby (~> 1.0) ice_nine (0.11.2) influxdb-client (1.17.0) - json (2.6.1) jwt (2.3.0) knapsack (4.0.0) rake @@ -210,29 +206,6 @@ GEM sawyer (~> 0.8.0, >= 0.5.3) oj (3.13.11) os (1.1.4) - pact (1.59.0) - pact-mock_service (~> 3.0, >= 3.3.1) - pact-support (~> 1.15) - rack-test (>= 0.6.3, < 2.0.0) - rspec (~> 3.0) - term-ansicolor (~> 1.0) - thor (>= 0.20, < 2.0) - webrick (~> 1.3) - pact-mock_service (3.6.2) - filelock (~> 1.1) - find_a_port (~> 1.0.1) - json - pact-support (~> 1.12, >= 1.12.0) - rack (~> 2.0) - rspec (>= 2.14) - term-ansicolor (~> 1.0) - thor (>= 0.19, < 2.0) - webrick (~> 1.3) - pact-support (1.15.1) - awesome_print (~> 1.1) - randexp (~> 0.1.7) - rspec (>= 2.14) - term-ansicolor (~> 1.0) parallel (1.19.2) parallel_tests (2.29.0) parallel @@ -256,7 +229,6 @@ GEM rack (>= 1.0, < 3) rainbow (3.0.0) rake (13.0.6) - randexp (0.1.7) regexp_parser (2.1.1) representable (3.1.1) declarative (< 0.1.0) @@ -311,18 +283,12 @@ GEM jwt (>= 1.5, < 3.0) multi_json (~> 1.10) slack-notifier (2.4.0) - sync (0.5.0) systemu (2.6.5) table_print (1.5.7) - term-ansicolor (1.7.1) - tins (~> 1.0) terminal-table (3.0.2) unicode-display_width (>= 1.1.1, < 3) - thor (1.2.1) thread_safe (0.3.6) timecop (0.9.1) - tins (1.31.0) - sync trailblazer-option (0.1.2) tzinfo (2.0.4) concurrent-ruby (~> 1.0) @@ -372,7 +338,6 @@ DEPENDENCIES influxdb-client (~> 1.17) knapsack (~> 4.0) octokit (~> 4.21) - pact (~> 1.12) parallel (~> 1.19) parallel_tests (~> 2.29) pry-byebug (~> 3.5.1) diff --git a/qa/contracts/provider/environments/base.rb b/qa/contracts/provider/environments/base.rb deleted file mode 100644 index 695ee6b867d..00000000000 --- a/qa/contracts/provider/environments/base.rb +++ /dev/null @@ -1,24 +0,0 @@ -# frozen_string_literal: true - -module Provider - module Environments - class Base - attr_writer :base_url, :merge_request - - def call(env) - @payload - end - - def http(endpoint) - Faraday.default_adapter = :net_http - response = Faraday.get(@base_url + endpoint) - @payload = [response.status, response.headers, [response.body]] - self - end - - def merge_request(endpoint) - http(@merge_request + endpoint) if endpoint.include? '.json' - end - end - end -end diff --git a/qa/contracts/provider/environments/local.rb b/qa/contracts/provider/environments/local.rb deleted file mode 100644 index 0d472bc25e9..00000000000 --- a/qa/contracts/provider/environments/local.rb +++ /dev/null @@ -1,12 +0,0 @@ -# frozen_string_literal: true - -module Provider - module Environments - class Local < Base - def initialize - @base_url = ENV['CONTRACT_HOST'] - @merge_request = ENV['CONTRACT_MR'] - end - end - end -end diff --git a/qa/contracts/provider/spec_helper.rb b/qa/contracts/provider/spec_helper.rb deleted file mode 100644 index 1869c039910..00000000000 --- a/qa/contracts/provider/spec_helper.rb +++ /dev/null @@ -1,22 +0,0 @@ -# frozen_string_literal: true - -module SpecHelper - unless ENV['CONTRACT_HOST'] - raise(ArgumentError, 'Contract tests require CONTRACT_HOST environment variable to be set!') - end - - require_relative '../../../config/bundler_setup' - Bundler.require(:default) - - root = File.expand_path('../', __dir__) - - loader = Zeitwerk::Loader.new - loader.push_dir(root) - - loader.ignore("#{root}/consumer") - loader.ignore("#{root}/contracts") - - loader.collapse("#{root}/provider/spec") - - loader.setup -end diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_when_pipeline_succeeds_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_when_pipeline_succeeds_spec.rb index 85270791f0f..9c55a6cf9a3 100644 --- a/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_when_pipeline_succeeds_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/merge_when_pipeline_succeeds_spec.rb @@ -4,6 +4,8 @@ module QA RSpec.describe 'Create', :runner do describe 'Merge requests' do shared_examples 'merge when pipeline succeeds' do |repeat: 1| + let(:runner_name) { "qa-runner-#{Faker::Alphanumeric.alphanumeric(number: 8)}" } + let(:project) do Resource::Project.fabricate_via_api! do |project| project.name = 'merge-when-pipeline-succeeds' @@ -14,24 +16,12 @@ module QA let!(:runner) do Resource::Runner.fabricate! do |runner| runner.project = project - runner.name = "runner-for-#{project.name}" - runner.tags = ["runner-for-#{project.name}"] + runner.name = runner_name + runner.tags = [runner_name] end end - before do - Flow::Login.sign_in - end - - after do - runner&.remove_via_api! - project&.remove_via_api! - end - - it 'merges after pipeline succeeds' do - transient_test = repeat > 1 - - # Push a new pipeline config file + let!(:ci_file) do Resource::Repository::Commit.fabricate_via_api! do |commit| commit.project = project commit.commit_message = 'Add .gitlab-ci.yml' @@ -39,60 +29,48 @@ module QA [ { file_path: '.gitlab-ci.yml', - content: <<~EOF + content: <<~YAML test: - tags: ["runner-for-#{project.name}"] - script: sleep 30 + tags: ["#{runner_name}"] + script: sleep 5 only: - merge_requests - EOF + YAML } ] ) end + end - repeat.times do |i| - QA::Runtime::Logger.info("Transient bug test - Trial #{i}") if transient_test + before do + Flow::Login.sign_in + end - branch_name = "mr-test-#{SecureRandom.hex(6)}-#{i}" + after do + runner&.remove_via_api! + end - # Create a branch that will be merged into the default branch - Resource::Repository::ProjectPush.fabricate! do |project_push| - project_push.project = project - project_push.new_branch = true - project_push.branch_name = branch_name - project_push.file_name = "#{branch_name}.txt" - end + it 'merges after pipeline succeeds' do + transient_test = repeat > 1 + + repeat.times do |i| + QA::Runtime::Logger.info("Transient bug test - Trial #{i + 1}") if transient_test - # Create a merge request to merge the branch we just created + # Create a merge request to trigger pipeline merge_request = Resource::MergeRequest.fabricate_via_api! do |merge_request| merge_request.project = project - merge_request.source_branch = branch_name - merge_request.no_preparation = true + merge_request.description = Faker::Lorem.sentence + merge_request.target_new_branch = false + merge_request.source_branch = "mr-test-#{SecureRandom.hex(6)}-#{i + 1}" + merge_request.file_name = Faker::Lorem.word + merge_request.file_content = Faker::Lorem.sentence end # Load the page so that the browser is as prepared as possible to display the pipeline in progress when we # start it. merge_request.visit! - # Push a new file to trigger a new pipeline - Resource::Repository::Commit.fabricate_via_api! do |commit| - commit.project = project - commit.commit_message = 'Add new file' - commit.branch = branch_name - commit.add_files( - [ - { - file_path: "#{branch_name}-file.md", - content: "file content" - } - ] - ) - end - Page::MergeRequest::Show.perform do |mr| - mr.refresh - # Part of the challenge with this test is that the MR widget has many components that could be displayed # and many errors states that those components could encounter. Most of the time few of those # possible components will be relevant, so it would be inefficient for this test to check for each of @@ -102,8 +80,6 @@ module QA mr.wait_until_ready_to_merge(transient_test: transient_test) mr.retry_until(reload: true, message: 'Wait until ready to click MWPS') do - merge_request.reload! - # Click the MWPS button if we can break mr.merge_when_pipeline_succeeds! if mr.has_element?(:merge_button, text: 'Merge when pipeline succeeds') diff --git a/qa/contracts/.gitignore b/spec/contracts/.gitignore index cb89d4102d3..cb89d4102d3 100644 --- a/qa/contracts/.gitignore +++ b/spec/contracts/.gitignore diff --git a/qa/contracts/consumer/.node-version b/spec/contracts/consumer/.node-version index 18711d290ea..18711d290ea 100644 --- a/qa/contracts/consumer/.node-version +++ b/spec/contracts/consumer/.node-version diff --git a/qa/contracts/consumer/endpoints/merge_request.js b/spec/contracts/consumer/endpoints/merge_requests.js index 74fd4e75bec..04e66c57dc9 100644 --- a/qa/contracts/consumer/endpoints/merge_request.js +++ b/spec/contracts/consumer/endpoints/merge_requests.js @@ -9,7 +9,7 @@ exports.getMetadata = (endpoint) => { .request({ method: 'GET', baseURL: url, - url: '/diffs_metadata.json', + url: '/gitlab-org/gitlab-qa/-/merge_requests/1/diffs_metadata.json', headers: { Accept: '*/*' }, }) .then((response) => response.data); @@ -22,7 +22,7 @@ exports.getDiscussions = (endpoint) => { .request({ method: 'GET', baseURL: url, - url: '/discussions.json', + url: '/gitlab-org/gitlab-qa/-/merge_requests/1/discussions.json', headers: { Accept: '*/*' }, }) .then((response) => response.data); @@ -35,7 +35,7 @@ exports.getDiffs = (endpoint) => { .request({ method: 'GET', baseURL: url, - url: '/diffs_batch.json?page=0', + url: '/gitlab-org/gitlab-qa/-/merge_requests/1/diffs_batch.json?page=0', headers: { Accept: '*/*' }, }) .then((response) => response.data); diff --git a/qa/contracts/consumer/fixtures/diffs.fixture.js b/spec/contracts/consumer/fixtures/diffs.fixture.js index 286d71f421c..7dbe825b093 100644 --- a/qa/contracts/consumer/fixtures/diffs.fixture.js +++ b/spec/contracts/consumer/fixtures/diffs.fixture.js @@ -77,7 +77,7 @@ const Diffs = { uponReceiving: 'a request for diff lines', withRequest: { method: 'GET', - path: '/diffs_batch.json', + path: '/gitlab-org/gitlab-qa/-/merge_requests/1/diffs_batch.json', headers: { Accept: '*/*', }, diff --git a/qa/contracts/consumer/fixtures/discussions.fixture.js b/spec/contracts/consumer/fixtures/discussions.fixture.js index cfc6112561b..c28b9bdd505 100644 --- a/qa/contracts/consumer/fixtures/discussions.fixture.js +++ b/spec/contracts/consumer/fixtures/discussions.fixture.js @@ -74,7 +74,7 @@ const Discussions = { uponReceiving: 'a request for discussions', withRequest: { method: 'GET', - path: '/discussions.json', + path: '/gitlab-org/gitlab-qa/-/merge_requests/1/discussions.json', headers: { Accept: '*/*', }, diff --git a/qa/contracts/consumer/fixtures/metadata.fixture.js b/spec/contracts/consumer/fixtures/metadata.fixture.js index 05a4831c447..3fca6cf9181 100644 --- a/qa/contracts/consumer/fixtures/metadata.fixture.js +++ b/spec/contracts/consumer/fixtures/metadata.fixture.js @@ -85,7 +85,7 @@ const Metadata = { uponReceiving: 'a request for Metadata', withRequest: { method: 'GET', - path: '/diffs_metadata.json', + path: '/gitlab-org/gitlab-qa/-/merge_requests/1/diffs_metadata.json', headers: { Accept: '*/*', }, diff --git a/qa/contracts/consumer/package.json b/spec/contracts/consumer/package.json index b4a3f59e89e..6a427ff8a7b 100644 --- a/qa/contracts/consumer/package.json +++ b/spec/contracts/consumer/package.json @@ -12,6 +12,6 @@ "prettier": "^2.5.1" }, "scripts": { - "test": "jest specs/ --runInBand" + "test": "jest --runInBand" } } diff --git a/qa/contracts/consumer/specs/diffs.spec.js b/spec/contracts/consumer/specs/diffs.spec.js index 5be2ed7ac00..b812461cb69 100644 --- a/qa/contracts/consumer/specs/diffs.spec.js +++ b/spec/contracts/consumer/specs/diffs.spec.js @@ -3,7 +3,7 @@ const { pactWith } = require('jest-pact'); const { Diffs } = require('../fixtures/diffs.fixture'); -const { getDiffs } = require('../endpoints/merge_request'); +const { getDiffs } = require('../endpoints/merge_requests'); pactWith( { @@ -17,10 +17,11 @@ pactWith( describe('Diffs Endpoint', () => { beforeEach(() => { const interaction = { + state: 'a merge request with diffs exists', ...Diffs.request, willRespondWith: Diffs.success, }; - return provider.addInteraction(interaction); + provider.addInteraction(interaction); }); it('return a successful body', () => { diff --git a/qa/contracts/consumer/specs/discussions.spec.js b/spec/contracts/consumer/specs/discussions.spec.js index 28ee3186a9f..304c240f7d3 100644 --- a/qa/contracts/consumer/specs/discussions.spec.js +++ b/spec/contracts/consumer/specs/discussions.spec.js @@ -3,7 +3,7 @@ const { pactWith } = require('jest-pact'); const { Discussions } = require('../fixtures/discussions.fixture'); -const { getDiscussions } = require('../endpoints/merge_request'); +const { getDiscussions } = require('../endpoints/merge_requests'); pactWith( { @@ -17,10 +17,11 @@ pactWith( describe('Discussions Endpoint', () => { beforeEach(() => { const interaction = { + state: 'a merge request with discussions exists', ...Discussions.request, willRespondWith: Discussions.success, }; - return provider.addInteraction(interaction); + provider.addInteraction(interaction); }); it('return a successful body', () => { diff --git a/qa/contracts/consumer/specs/metadata.spec.js b/spec/contracts/consumer/specs/metadata.spec.js index 31fc398f228..c49d4c354b1 100644 --- a/qa/contracts/consumer/specs/metadata.spec.js +++ b/spec/contracts/consumer/specs/metadata.spec.js @@ -3,7 +3,7 @@ const { pactWith } = require('jest-pact'); const { Metadata } = require('../fixtures/metadata.fixture'); -const { getMetadata } = require('../endpoints/merge_request'); +const { getMetadata } = require('../endpoints/merge_requests'); pactWith( { @@ -17,10 +17,11 @@ pactWith( describe('Metadata Endpoint', () => { beforeEach(() => { const interaction = { + state: 'a merge request exists', ...Metadata.request, willRespondWith: Metadata.success, }; - return provider.addInteraction(interaction); + provider.addInteraction(interaction); }); it('return a successful body', () => { diff --git a/qa/contracts/contracts/merge_request_page-merge_request_diffs_endpoint.json b/spec/contracts/contracts/merge_request_page-merge_request_diffs_endpoint.json index 8df54c25326..2f097d8eb24 100644 --- a/qa/contracts/contracts/merge_request_page-merge_request_diffs_endpoint.json +++ b/spec/contracts/contracts/merge_request_page-merge_request_diffs_endpoint.json @@ -8,9 +8,10 @@ "interactions": [ { "description": "a request for diff lines", + "providerState": "a merge request with diffs exists", "request": { "method": "GET", - "path": "/diffs_batch.json", + "path": "/gitlab-org/gitlab-qa/-/merge_requests/1/diffs_batch.json", "query": "page=0", "headers": { "Accept": "*/*" @@ -225,4 +226,4 @@ "version": "2.0.0" } } -}
\ No newline at end of file +} diff --git a/qa/contracts/contracts/merge_request_page-merge_request_discussions_endpoint.json b/spec/contracts/contracts/merge_request_page-merge_request_discussions_endpoint.json index 14839053e57..819d95276b3 100644 --- a/qa/contracts/contracts/merge_request_page-merge_request_discussions_endpoint.json +++ b/spec/contracts/contracts/merge_request_page-merge_request_discussions_endpoint.json @@ -8,9 +8,10 @@ "interactions": [ { "description": "a request for discussions", + "providerState": "a merge request with discussions exists", "request": { "method": "GET", - "path": "/discussions.json", + "path": "/gitlab-org/gitlab-qa/-/merge_requests/1/discussions.json", "headers": { "Accept": "*/*" } @@ -232,4 +233,4 @@ "version": "2.0.0" } } -}
\ No newline at end of file +} diff --git a/qa/contracts/contracts/merge_request_page-merge_request_metadata_endpoint.json b/spec/contracts/contracts/merge_request_page-merge_request_metadata_endpoint.json index 4b6cab0fc94..eb22b7d2e3c 100644 --- a/qa/contracts/contracts/merge_request_page-merge_request_metadata_endpoint.json +++ b/spec/contracts/contracts/merge_request_page-merge_request_metadata_endpoint.json @@ -8,9 +8,10 @@ "interactions": [ { "description": "a request for Metadata", + "providerState": "a merge request exists", "request": { "method": "GET", - "path": "/diffs_metadata.json", + "path": "/gitlab-org/gitlab-qa/-/merge_requests/1/diffs_metadata.json", "headers": { "Accept": "*/*" } @@ -219,4 +220,4 @@ "version": "2.0.0" } } -}
\ No newline at end of file +} diff --git a/spec/contracts/provider/environments/test.rb b/spec/contracts/provider/environments/test.rb new file mode 100644 index 00000000000..6efb19508d8 --- /dev/null +++ b/spec/contracts/provider/environments/test.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module Provider + module Environments + class Test + def self.app + Rack::Builder.app do + map "/" do + run Gitlab::Application + end + end + end + end + end +end diff --git a/spec/contracts/provider/helpers/users_helper.rb b/spec/contracts/provider/helpers/users_helper.rb new file mode 100644 index 00000000000..1982bd9cfd2 --- /dev/null +++ b/spec/contracts/provider/helpers/users_helper.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +module Provider + module UsersHelper + CONTRACT_USER_NAME = "Contract Test User" + end +end diff --git a/spec/contracts/provider/spec_helper.rb b/spec/contracts/provider/spec_helper.rb new file mode 100644 index 00000000000..6009d6524e1 --- /dev/null +++ b/spec/contracts/provider/spec_helper.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +require 'spec_helper' +require 'zeitwerk' +require_relative 'helpers/users_helper' + +RSpec.configure do |config| + config.include Devise::Test::IntegrationHelpers + config.include FactoryBot::Syntax::Methods + + config.before do + user = create(:user, name: Provider::UsersHelper::CONTRACT_USER_NAME).tap do |user| + user.current_sign_in_at = Time.current + end + + sign_in user + end +end + +Pact.configure do |config| + config.include FactoryBot::Syntax::Methods +end + +module SpecHelper + require_relative '../../../config/bundler_setup' + Bundler.require(:default) + + root = File.expand_path('../', __dir__) + + loader = Zeitwerk::Loader.new + loader.push_dir(root) + + loader.ignore("#{root}/consumer") + loader.ignore("#{root}/contracts") + + loader.collapse("#{root}/provider/spec") + + loader.setup +end diff --git a/qa/contracts/provider/spec/diffs_helper.rb b/spec/contracts/provider/specs/diffs_helper.rb index 95dbc4254e6..24bdd00dbae 100644 --- a/qa/contracts/provider/spec/diffs_helper.rb +++ b/spec/contracts/provider/specs/diffs_helper.rb @@ -1,13 +1,12 @@ # frozen_string_literal: true require_relative '../spec_helper' +require_relative '../states/diffs_state' module Provider module DiffsHelper - local = Environments::Local.new - Pact.service_provider "Merge Request Diffs Endpoint" do - app { local.merge_request('/diffs_batch.json?page=0') } + app { Environments::Test.app } honours_pact_with 'Merge Request Page' do pact_uri '../contracts/merge_request_page-merge_request_diffs_endpoint.json' diff --git a/qa/contracts/provider/spec/discussions_helper.rb b/spec/contracts/provider/specs/discussions_helper.rb index 642dde79e1d..135ccf48276 100644 --- a/qa/contracts/provider/spec/discussions_helper.rb +++ b/spec/contracts/provider/specs/discussions_helper.rb @@ -1,13 +1,12 @@ # frozen_string_literal: true require_relative '../spec_helper' +require_relative '../states/discussions_state' module Provider module DiscussionsHelper - local = Environments::Local.new - Pact.service_provider "Merge Request Discussions Endpoint" do - app { local.merge_request('/discussions.json') } + app { Environments::Test.app } honours_pact_with 'Merge Request Page' do pact_uri '../contracts/merge_request_page-merge_request_discussions_endpoint.json' diff --git a/qa/contracts/provider/spec/metadata_helper.rb b/spec/contracts/provider/specs/metadata_helper.rb index a3eb4978641..e73b993a31a 100644 --- a/qa/contracts/provider/spec/metadata_helper.rb +++ b/spec/contracts/provider/specs/metadata_helper.rb @@ -1,13 +1,12 @@ # frozen_string_literal: true require_relative '../spec_helper' +require_relative '../states/metadata_state' module Provider module MetadataHelper - local = Environments::Local.new - Pact.service_provider "Merge Request Metadata Endpoint" do - app { local.merge_request('/diffs_metadata.json') } + app { Environments::Test.app } honours_pact_with 'Merge Request Page' do pact_uri '../contracts/merge_request_page-merge_request_metadata_endpoint.json' diff --git a/spec/contracts/provider/states/diffs_state.rb b/spec/contracts/provider/states/diffs_state.rb new file mode 100644 index 00000000000..d959cde5f5e --- /dev/null +++ b/spec/contracts/provider/states/diffs_state.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +Pact.provider_states_for "Merge Request Page" do + provider_state "a merge request with diffs exists" do + set_up do + user = User.find_by(name: Provider::UsersHelper::CONTRACT_USER_NAME) + namespace = create(:namespace, name: 'gitlab-org') + project = create(:project, :custom_repo, name: 'gitlab-qa', namespace: namespace, files: {}) + + project.add_maintainer(user) + + merge_request = create(:merge_request_with_multiple_diffs, source_project: project) + merge_request_diff = create(:merge_request_diff, merge_request: merge_request) + + create(:merge_request_diff_file, :new_file, merge_request_diff: merge_request_diff) + end + end +end diff --git a/spec/contracts/provider/states/discussions_state.rb b/spec/contracts/provider/states/discussions_state.rb new file mode 100644 index 00000000000..ddbcf80f2c8 --- /dev/null +++ b/spec/contracts/provider/states/discussions_state.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +Pact.provider_states_for "Merge Request Page" do + provider_state "a merge request with discussions exists" do + set_up do + user = User.find_by(name: Provider::UsersHelper::CONTRACT_USER_NAME) + namespace = create(:namespace, name: 'gitlab-org') + project = create(:project, name: 'gitlab-qa', namespace: namespace) + + project.add_maintainer(user) + + merge_request = create(:merge_request_with_diffs, source_project: project, author: user) + + create(:discussion_note_on_merge_request, noteable: merge_request, project: project, author: user) + end + end +end diff --git a/spec/contracts/provider/states/metadata_state.rb b/spec/contracts/provider/states/metadata_state.rb new file mode 100644 index 00000000000..59b290ce2fe --- /dev/null +++ b/spec/contracts/provider/states/metadata_state.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +Pact.provider_states_for "Merge Request Page" do + provider_state "a merge request exists" do + set_up do + user = User.find_by(name: Provider::UsersHelper::CONTRACT_USER_NAME) + namespace = create(:namespace, name: 'gitlab-org') + project = create(:project, :custom_repo, name: 'gitlab-qa', namespace: namespace, files: {}) + + project.add_maintainer(user) + + merge_request = create(:merge_request, source_project: project) + merge_request_diff = create(:merge_request_diff, merge_request: merge_request) + + create(:merge_request_diff_file, :new_file, merge_request_diff: merge_request_diff) + end + end +end diff --git a/spec/frontend/design_management/pages/index_spec.js b/spec/frontend/design_management/pages/index_spec.js index 87531e8b645..087655d10f7 100644 --- a/spec/frontend/design_management/pages/index_spec.js +++ b/spec/frontend/design_management/pages/index_spec.js @@ -4,6 +4,7 @@ import Vue, { nextTick } from 'vue'; import VueApollo, { ApolloMutation } from 'vue-apollo'; import VueRouter from 'vue-router'; +import { GlBreakpointInstance as breakpointInstance } from '@gitlab/ui/dist/utils'; import VueDraggable from 'vuedraggable'; import createMockApollo from 'helpers/mock_apollo_helper'; import waitForPromises from 'helpers/wait_for_promises'; @@ -762,6 +763,25 @@ describe('Design management index page', () => { expect(findDesigns().at(0).props('id')).toBe('2'); }); + it.each` + breakpoint | reorderDisabled + ${'xs'} | ${true} + ${'sm'} | ${false} + ${'md'} | ${false} + ${'lg'} | ${false} + ${'xl'} | ${false} + `( + 'sets draggable disabled value to $reorderDisabled when breakpoint is $breakpoint', + async ({ breakpoint, reorderDisabled }) => { + jest.spyOn(breakpointInstance, 'getBreakpointSize').mockReturnValue(breakpoint); + + createComponentWithApollo({}); + await waitForPromises(); + + expect(draggableAttributes().disabled).toBe(reorderDisabled); + }, + ); + it('prevents reordering when reorderDesigns mutation is in progress', async () => { createComponentWithApollo({}); await moveDesigns(wrapper); diff --git a/spec/requests/ide_controller_spec.rb b/spec/requests/ide_controller_spec.rb index 4bf1e43ba40..151fa89b819 100644 --- a/spec/requests/ide_controller_spec.rb +++ b/spec/requests/ide_controller_spec.rb @@ -208,6 +208,31 @@ RSpec.describe IdeController do it_behaves_like 'user access rights check' end + + describe 'Snowplow view event', :snowplow do + it 'is tracked' do + subject + + expect_snowplow_event( + category: described_class.to_s, + action: 'web_ide_views', + namespace: project.namespace, + user: user + ) + end + + context 'when route_hll_to_snowplow_phase2 FF is disabled' do + before do + stub_feature_flags(route_hll_to_snowplow_phase2: false) + end + + it 'does not track Snowplow event' do + subject + + expect_no_snowplow_event + end + end + end end end end |