Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-06-07 09:09:00 +00:00
parent bed53d96d2
commit bdd03bc52a
52 changed files with 328 additions and 190 deletions

View File

@ -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:

View File

@ -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

View File

@ -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)

View File

@ -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"

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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: {

View File

@ -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: {

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -0,0 +1 @@
2d4dd4b889b5fc9c3f329669734f086997ebb514ed62afe6ca4220fc525797c9

View File

@ -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

View File

@ -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:

View File

@ -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:

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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,8 +16,29 @@ 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
let!(:ci_file) do
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.project = project
commit.commit_message = 'Add .gitlab-ci.yml'
commit.add_files(
[
{
file_path: '.gitlab-ci.yml',
content: <<~YAML
test:
tags: ["#{runner_name}"]
script: sleep 5
only:
- merge_requests
YAML
}
]
)
end
end
@ -25,74 +48,29 @@ module QA
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
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.project = project
commit.commit_message = 'Add .gitlab-ci.yml'
commit.add_files(
[
{
file_path: '.gitlab-ci.yml',
content: <<~EOF
test:
tags: ["runner-for-#{project.name}"]
script: sleep 30
only:
- merge_requests
EOF
}
]
)
end
repeat.times do |i|
QA::Runtime::Logger.info("Transient bug test - Trial #{i}") if transient_test
QA::Runtime::Logger.info("Transient bug test - Trial #{i + 1}") if transient_test
branch_name = "mr-test-#{SecureRandom.hex(6)}-#{i}"
# 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
# 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')

View File

@ -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);

View File

@ -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: '*/*',
},

View File

@ -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: '*/*',
},

View File

@ -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: '*/*',
},

View File

@ -12,6 +12,6 @@
"prettier": "^2.5.1"
},
"scripts": {
"test": "jest specs/ --runInBand"
"test": "jest --runInBand"
}
}

View File

@ -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', () => {

View File

@ -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', () => {

View File

@ -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', () => {

View File

@ -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"
}
}
}
}

View File

@ -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"
}
}
}
}

View File

@ -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"
}
}
}
}

View File

@ -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

View File

@ -0,0 +1,7 @@
# frozen_string_literal: true
module Provider
module UsersHelper
CONTRACT_USER_NAME = "Contract Test User"
end
end

View File

@ -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

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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