Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-06-16 09:08:59 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-06-16 09:08:59 +0300
commit06bcbc77e472a70b8332150a941539c55953ef2b (patch)
tree903ff19991a3c3234626b1e86827a42063eeac61 /spec
parent1325f8cf2dce0f24403ea27c4ee58afd51fa3a8e (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/components/pajamas/checkbox_component_spec.rb130
-rw-r--r--spec/components/pajamas/component_spec.rb17
-rw-r--r--spec/components/pajamas/concerns/checkbox_radio_label_with_help_text_spec.rb110
-rw-r--r--spec/components/pajamas/concerns/checkbox_radio_options_spec.rb32
-rw-r--r--spec/components/pajamas/radio_component_spec.rb126
-rw-r--r--spec/contracts/consumer/endpoints/project/merge_requests.js (renamed from spec/contracts/consumer/endpoints/merge_requests.js)4
-rw-r--r--spec/contracts/consumer/fixtures/project/merge_request/diffs_batch.fixture.js (renamed from spec/contracts/consumer/fixtures/diffs.fixture.js)5
-rw-r--r--spec/contracts/consumer/fixtures/project/merge_request/diffs_metadata.fixture.js (renamed from spec/contracts/consumer/fixtures/metadata.fixture.js)7
-rw-r--r--spec/contracts/consumer/fixtures/project/merge_request/discussions.fixture.js (renamed from spec/contracts/consumer/fixtures/discussions.fixture.js)1
-rw-r--r--spec/contracts/consumer/specs/diffs.spec.js37
-rw-r--r--spec/contracts/consumer/specs/discussions.spec.js37
-rw-r--r--spec/contracts/consumer/specs/metadata.spec.js37
-rw-r--r--spec/contracts/consumer/specs/project/merge_request/show.spec.js112
-rw-r--r--spec/contracts/contracts/project/merge_request/show/mergerequest#show-merge_request_diffs_batch_endpoint.json (renamed from spec/contracts/contracts/merge_request_page-merge_request_diffs_endpoint.json)6
-rw-r--r--spec/contracts/contracts/project/merge_request/show/mergerequest#show-merge_request_diffs_metadata_endpoint.json (renamed from spec/contracts/contracts/merge_request_page-merge_request_metadata_endpoint.json)8
-rw-r--r--spec/contracts/contracts/project/merge_request/show/mergerequest#show-merge_request_discussions_endpoint.json (renamed from spec/contracts/contracts/merge_request_page-merge_request_discussions_endpoint.json)4
-rw-r--r--spec/contracts/provider/pact_helpers/project/merge_request/diffs_batch_helper.rb16
-rw-r--r--spec/contracts/provider/pact_helpers/project/merge_request/diffs_metadata_helper.rb16
-rw-r--r--spec/contracts/provider/pact_helpers/project/merge_request/discussions_helper.rb16
-rw-r--r--spec/contracts/provider/specs/diffs_helper.rb16
-rw-r--r--spec/contracts/provider/specs/discussions_helper.rb16
-rw-r--r--spec/contracts/provider/specs/metadata_helper.rb16
-rw-r--r--spec/contracts/provider/states/project/merge_request/diffs_batch_state.rb (renamed from spec/contracts/provider/states/diffs_state.rb)2
-rw-r--r--spec/contracts/provider/states/project/merge_request/diffs_metadata_state.rb (renamed from spec/contracts/provider/states/metadata_state.rb)2
-rw-r--r--spec/contracts/provider/states/project/merge_request/discussions_state.rb (renamed from spec/contracts/provider/states/discussions_state.rb)2
-rw-r--r--spec/controllers/projects/releases_controller_spec.rb14
-rw-r--r--spec/helpers/diff_helper_spec.rb21
-rw-r--r--spec/lib/gitlab/form_builders/gitlab_ui_form_builder_spec.rb269
-rw-r--r--spec/requests/api/internal/workhorse_spec.rb2
-rw-r--r--spec/requests/api/releases_spec.rb1
-rw-r--r--spec/services/merge_requests/mergeability/run_checks_service_spec.rb22
-rw-r--r--spec/support/helpers/form_builder_helpers.rb13
-rw-r--r--spec/support/shared_examples/components/pajamas_shared_examples.rb13
-rw-r--r--spec/support/shared_examples/graphql/types/gitlab_style_deprecations_shared_examples.rb8
34 files changed, 819 insertions, 319 deletions
diff --git a/spec/components/pajamas/checkbox_component_spec.rb b/spec/components/pajamas/checkbox_component_spec.rb
new file mode 100644
index 00000000000..b2f3a84fbfe
--- /dev/null
+++ b/spec/components/pajamas/checkbox_component_spec.rb
@@ -0,0 +1,130 @@
+# frozen_string_literal: true
+require "spec_helper"
+
+RSpec.describe Pajamas::CheckboxComponent, :aggregate_failures, type: :component do
+ include FormBuilderHelpers
+
+ let_it_be(:method) { :view_diffs_file_by_file }
+ let_it_be(:label) { "Show one file at a time on merge request's Changes tab" }
+ let_it_be(:help_text) { 'Instead of all the files changed, show only one file at a time.' }
+
+ RSpec.shared_examples 'it renders unchecked checkbox with value of `1`' do
+ it 'renders unchecked checkbox with value of `1`' do
+ expect(rendered_component).to have_unchecked_field(label, with: '1')
+ end
+ end
+
+ context 'with default options' do
+ before do
+ fake_form_for do |form|
+ render_inline(
+ described_class.new(
+ form: form,
+ method: method,
+ label: label
+ )
+ )
+ end
+ end
+
+ include_examples 'it renders unchecked checkbox with value of `1`'
+ include_examples 'it does not render help text'
+
+ it 'renders hidden input with value of `0`' do
+ expect(rendered_component).to have_field('user[view_diffs_file_by_file]', type: 'hidden', with: '0')
+ end
+ end
+
+ context 'with custom options' do
+ let_it_be(:checked_value) { 'yes' }
+ let_it_be(:unchecked_value) { 'no' }
+ let_it_be(:checkbox_options) { { class: 'checkbox-foo-bar', checked: true } }
+ let_it_be(:label_options) { { class: 'label-foo-bar' } }
+
+ before do
+ fake_form_for do |form|
+ render_inline(
+ described_class.new(
+ form: form,
+ method: method,
+ label: label,
+ help_text: help_text,
+ checked_value: checked_value,
+ unchecked_value: unchecked_value,
+ checkbox_options: checkbox_options,
+ label_options: label_options
+ )
+ )
+ end
+ end
+
+ include_examples 'it renders help text'
+
+ it 'renders checked checkbox with value of `yes`' do
+ expect(rendered_component).to have_checked_field(label, with: checked_value, class: checkbox_options[:class])
+ end
+
+ it 'adds CSS class to label' do
+ expect(rendered_component).to have_selector('label.label-foo-bar')
+ end
+
+ it 'renders hidden input with value of `no`' do
+ expect(rendered_component).to have_field('user[view_diffs_file_by_file]', type: 'hidden', with: unchecked_value)
+ end
+ end
+
+ context 'with `label` slot' do
+ before do
+ fake_form_for do |form|
+ render_inline(
+ described_class.new(
+ form: form,
+ method: method
+ )
+ ) do |c|
+ c.label { label }
+ end
+ end
+ end
+
+ include_examples 'it renders unchecked checkbox with value of `1`'
+ end
+
+ context 'with `help_text` slot' do
+ before do
+ fake_form_for do |form|
+ render_inline(
+ described_class.new(
+ form: form,
+ method: method,
+ label: label
+ )
+ ) do |c|
+ c.help_text { help_text }
+ end
+ end
+ end
+
+ include_examples 'it renders unchecked checkbox with value of `1`'
+ include_examples 'it renders help text'
+ end
+
+ context 'with `label` and `help_text` slots' do
+ before do
+ fake_form_for do |form|
+ render_inline(
+ described_class.new(
+ form: form,
+ method: method
+ )
+ ) do |c|
+ c.label { label }
+ c.help_text { help_text }
+ end
+ end
+ end
+
+ include_examples 'it renders unchecked checkbox with value of `1`'
+ include_examples 'it renders help text'
+ end
+end
diff --git a/spec/components/pajamas/component_spec.rb b/spec/components/pajamas/component_spec.rb
index 96f6b43bac1..7385519b468 100644
--- a/spec/components/pajamas/component_spec.rb
+++ b/spec/components/pajamas/component_spec.rb
@@ -23,4 +23,21 @@ RSpec.describe Pajamas::Component do
expect(value).to eq('something')
end
end
+
+ describe '#format_options' do
+ it 'merges CSS classes and additional options' do
+ expect(
+ subject.send(
+ :format_options,
+ options: { foo: 'bar', class: 'gl-display-flex gl-py-5' },
+ css_classes: %w(gl-px-5 gl-mt-5),
+ additional_options: { baz: 'bax' }
+ )
+ ).to match({
+ foo: 'bar',
+ baz: 'bax',
+ class: ['gl-px-5', 'gl-mt-5', 'gl-display-flex gl-py-5']
+ })
+ end
+ end
end
diff --git a/spec/components/pajamas/concerns/checkbox_radio_label_with_help_text_spec.rb b/spec/components/pajamas/concerns/checkbox_radio_label_with_help_text_spec.rb
new file mode 100644
index 00000000000..7a792592b3c
--- /dev/null
+++ b/spec/components/pajamas/concerns/checkbox_radio_label_with_help_text_spec.rb
@@ -0,0 +1,110 @@
+# frozen_string_literal: true
+require "spec_helper"
+
+RSpec.describe Pajamas::Concerns::CheckboxRadioLabelWithHelpText do
+ let(:form) { instance_double('ActionView::Helpers::FormBuilder') }
+ let(:component_class) do
+ Class.new do
+ attr_reader(
+ :form,
+ :method,
+ :label_argument,
+ :help_text_argument,
+ :label_options,
+ :input_options,
+ :value
+ )
+
+ def initialize(
+ form:,
+ method:,
+ label: nil,
+ help_text: nil,
+ label_options: {},
+ radio_options: {},
+ value: nil
+ )
+ @form = form
+ @method = method
+ @label_argument = label
+ @help_text_argument = help_text
+ @label_options = label_options
+ @input_options = radio_options
+ @value = value
+ end
+
+ def label_content
+ @label_argument
+ end
+
+ def help_text_content
+ @help_text_argument
+ end
+
+ def format_options(options:, css_classes: [], additional_options: {})
+ {}
+ end
+
+ include Pajamas::Concerns::CheckboxRadioLabelWithHelpText
+ include ActionView::Helpers::TagHelper
+ end
+ end
+
+ let_it_be(:method) { 'username' }
+ let_it_be(:label_options) { { class: 'foo-bar' } }
+ let_it_be(:value) { 'Foo bar' }
+
+ describe '#render_label_with_help_text' do
+ it 'calls `#format_options` with correct arguments' do
+ allow(form).to receive(:label)
+
+ component = component_class.new(form: form, method: method, label_options: label_options, value: value)
+
+ expect(component).to receive(:format_options).with(
+ options: label_options,
+ css_classes: ['custom-control-label'],
+ additional_options: { value: value }
+ )
+
+ component.render_label_with_help_text
+ end
+
+ context 'when `help_text` argument is passed' do
+ it 'calls `form.label` with `label` and `help_text` arguments used in the block' do
+ component = component_class.new(
+ form: form,
+ method: method,
+ label: 'Label argument',
+ help_text: 'Help text argument'
+ )
+
+ expected_label_entry = '<span>Label argument</span><p class="help-text"' \
+ ' data-testid="pajamas-component-help-text">Help text argument</p>'
+
+ expect(form).to receive(:label).with(method, {}) do |&block|
+ expect(block.call).to eq(expected_label_entry)
+ end
+
+ component.render_label_with_help_text
+ end
+ end
+
+ context 'when `help_text` argument is not passed' do
+ it 'calls `form.label` with `label` argument used in the block' do
+ component = component_class.new(
+ form: form,
+ method: method,
+ label: 'Label argument'
+ )
+
+ expected_label_entry = '<span>Label argument</span>'
+
+ expect(form).to receive(:label).with(method, {}) do |&block|
+ expect(block.call).to eq(expected_label_entry)
+ end
+
+ component.render_label_with_help_text
+ end
+ end
+ end
+end
diff --git a/spec/components/pajamas/concerns/checkbox_radio_options_spec.rb b/spec/components/pajamas/concerns/checkbox_radio_options_spec.rb
new file mode 100644
index 00000000000..3eb888e5f3b
--- /dev/null
+++ b/spec/components/pajamas/concerns/checkbox_radio_options_spec.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+require "spec_helper"
+
+RSpec.describe Pajamas::Concerns::CheckboxRadioOptions do
+ let(:component_class) do
+ Class.new do
+ include Pajamas::Concerns::CheckboxRadioOptions
+
+ attr_reader(:input_options)
+
+ def initialize(input_options: {})
+ @input_options = input_options
+ end
+
+ def format_options(options:, css_classes: [], additional_options: {})
+ {}
+ end
+ end
+ end
+
+ describe '#formatted_input_options' do
+ let_it_be(:input_options) { { class: 'foo-bar' } }
+
+ it 'calls `#format_options` with correct arguments' do
+ component = component_class.new(input_options: input_options)
+
+ expect(component).to receive(:format_options).with(options: input_options, css_classes: ['custom-control-input'])
+
+ component.formatted_input_options
+ end
+ end
+end
diff --git a/spec/components/pajamas/radio_component_spec.rb b/spec/components/pajamas/radio_component_spec.rb
new file mode 100644
index 00000000000..3885d101c7a
--- /dev/null
+++ b/spec/components/pajamas/radio_component_spec.rb
@@ -0,0 +1,126 @@
+# frozen_string_literal: true
+require "spec_helper"
+
+RSpec.describe Pajamas::RadioComponent, :aggregate_failures, type: :component do
+ include FormBuilderHelpers
+
+ let_it_be(:method) { :access_level }
+ let_it_be(:label) { "Access Level" }
+ let_it_be(:value) { :regular }
+ let_it_be(:help_text) do
+ 'Administrators have access to all groups, projects, and users and can manage all features in this installation'
+ end
+
+ RSpec.shared_examples 'it renders unchecked radio' do
+ it 'renders unchecked radio' do
+ expect(rendered_component).to have_unchecked_field(label)
+ end
+ end
+
+ context 'with default options' do
+ before do
+ fake_form_for do |form|
+ render_inline(
+ described_class.new(
+ form: form,
+ method: method,
+ value: value,
+ label: label
+ )
+ )
+ end
+ end
+
+ include_examples 'it renders unchecked radio'
+ include_examples 'it does not render help text'
+ end
+
+ context 'with custom options' do
+ let_it_be(:radio_options) { { class: 'radio-foo-bar', checked: true } }
+ let_it_be(:label_options) { { class: 'label-foo-bar' } }
+
+ before do
+ fake_form_for do |form|
+ render_inline(
+ described_class.new(
+ form: form,
+ method: method,
+ value: method,
+ label: label,
+ help_text: help_text,
+ radio_options: radio_options,
+ label_options: label_options
+ )
+ )
+ end
+ end
+
+ include_examples 'it renders help text'
+
+ it 'renders checked radio' do
+ expect(rendered_component).to have_checked_field(label, class: radio_options[:class])
+ end
+
+ it 'adds CSS class to label' do
+ expect(rendered_component).to have_selector('label.label-foo-bar')
+ end
+ end
+
+ context 'with `label` slot' do
+ before do
+ fake_form_for do |form|
+ render_inline(
+ described_class.new(
+ form: form,
+ method: method,
+ value: value
+ )
+ ) do |c|
+ c.label { label }
+ end
+ end
+ end
+
+ include_examples 'it renders unchecked radio'
+ end
+
+ context 'with `help_text` slot' do
+ before do
+ fake_form_for do |form|
+ render_inline(
+ described_class.new(
+ form: form,
+ method: method,
+ value: value,
+ label: label
+ )
+ ) do |c|
+ c.help_text { help_text }
+ end
+ end
+ end
+
+ include_examples 'it renders unchecked radio'
+ include_examples 'it renders help text'
+ end
+
+ context 'with `label` and `help_text` slots' do
+ before do
+ fake_form_for do |form|
+ render_inline(
+ described_class.new(
+ form: form,
+ method: method,
+ value: value
+ )
+ ) do |c|
+ c.label { label }
+ c.help_text { help_text }
+ end
+ end
+ end
+
+ include_examples 'it renders unchecked radio'
+ include_examples 'it renders help text'
+ end
+end
diff --git a/spec/contracts/consumer/endpoints/merge_requests.js b/spec/contracts/consumer/endpoints/project/merge_requests.js
index ae4d5544df6..38773e5fb10 100644
--- a/spec/contracts/consumer/endpoints/merge_requests.js
+++ b/spec/contracts/consumer/endpoints/project/merge_requests.js
@@ -1,6 +1,6 @@
import { request } from 'axios';
-export function getMetadata(endpoint) {
+export function getDiffsMetadata(endpoint) {
const { url } = endpoint;
return request({
@@ -22,7 +22,7 @@ export function getDiscussions(endpoint) {
}).then((response) => response.data);
}
-export function getDiffs(endpoint) {
+export function getDiffsBatch(endpoint) {
const { url } = endpoint;
return request({
diff --git a/spec/contracts/consumer/fixtures/diffs.fixture.js b/spec/contracts/consumer/fixtures/project/merge_request/diffs_batch.fixture.js
index cc2c054b08f..b53e4bb335d 100644
--- a/spec/contracts/consumer/fixtures/diffs.fixture.js
+++ b/spec/contracts/consumer/fixtures/project/merge_request/diffs_batch.fixture.js
@@ -62,7 +62,7 @@ const body = {
},
};
-const Diffs = {
+const DiffsBatch = {
body: Matchers.extractPayload(body),
success: {
@@ -86,5 +86,6 @@ const Diffs = {
},
};
-export { Diffs };
+export { DiffsBatch };
+
/* eslint-enable @gitlab/require-i18n-strings */
diff --git a/spec/contracts/consumer/fixtures/metadata.fixture.js b/spec/contracts/consumer/fixtures/project/merge_request/diffs_metadata.fixture.js
index c19ca2175b3..39dbcf78ee7 100644
--- a/spec/contracts/consumer/fixtures/metadata.fixture.js
+++ b/spec/contracts/consumer/fixtures/project/merge_request/diffs_metadata.fixture.js
@@ -70,7 +70,7 @@ const body = {
project_name: Matchers.string('contract-testing'),
};
-const Metadata = {
+const DiffsMetadata = {
body: Matchers.extractPayload(body),
success: {
@@ -82,7 +82,7 @@ const Metadata = {
},
request: {
- uponReceiving: 'a request for Metadata',
+ uponReceiving: 'a request for Diffs Metadata',
withRequest: {
method: 'GET',
path: '/gitlab-org/gitlab-qa/-/merge_requests/1/diffs_metadata.json',
@@ -93,5 +93,6 @@ const Metadata = {
},
};
-export { Metadata };
+export { DiffsMetadata };
+
/* eslint-enable @gitlab/require-i18n-strings */
diff --git a/spec/contracts/consumer/fixtures/discussions.fixture.js b/spec/contracts/consumer/fixtures/project/merge_request/discussions.fixture.js
index 26f1d65f663..af0962a01cb 100644
--- a/spec/contracts/consumer/fixtures/discussions.fixture.js
+++ b/spec/contracts/consumer/fixtures/project/merge_request/discussions.fixture.js
@@ -83,4 +83,5 @@ const Discussions = {
};
export { Discussions };
+
/* eslint-enable @gitlab/require-i18n-strings */
diff --git a/spec/contracts/consumer/specs/diffs.spec.js b/spec/contracts/consumer/specs/diffs.spec.js
deleted file mode 100644
index 6b1cefdbdbc..00000000000
--- a/spec/contracts/consumer/specs/diffs.spec.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* eslint-disable @gitlab/require-i18n-strings */
-
-import { pactWith } from 'jest-pact';
-
-import { Diffs } from '../fixtures/diffs.fixture';
-import { getDiffs } from '../endpoints/merge_requests';
-
-pactWith(
- {
- consumer: 'Merge Request Page',
- provider: 'Merge Request Diffs Endpoint',
- log: '../logs/consumer.log',
- dir: '../contracts',
- },
-
- (provider) => {
- describe('Diffs Endpoint', () => {
- beforeEach(() => {
- const interaction = {
- state: 'a merge request with diffs exists',
- ...Diffs.request,
- willRespondWith: Diffs.success,
- };
- provider.addInteraction(interaction);
- });
-
- it('return a successful body', () => {
- return getDiffs({
- url: provider.mockService.baseUrl,
- }).then((diffs) => {
- expect(diffs).toEqual(Diffs.body);
- });
- });
- });
- },
-);
-/* eslint-enable @gitlab/require-i18n-strings */
diff --git a/spec/contracts/consumer/specs/discussions.spec.js b/spec/contracts/consumer/specs/discussions.spec.js
deleted file mode 100644
index 2a5d0ba6267..00000000000
--- a/spec/contracts/consumer/specs/discussions.spec.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* eslint-disable @gitlab/require-i18n-strings */
-
-import { pactWith } from 'jest-pact';
-
-import { Discussions } from '../fixtures/discussions.fixture';
-import { getDiscussions } from '../endpoints/merge_requests';
-
-pactWith(
- {
- consumer: 'Merge Request Page',
- provider: 'Merge Request Discussions Endpoint',
- log: '../logs/consumer.log',
- dir: '../contracts',
- },
-
- (provider) => {
- describe('Discussions Endpoint', () => {
- beforeEach(() => {
- const interaction = {
- state: 'a merge request with discussions exists',
- ...Discussions.request,
- willRespondWith: Discussions.success,
- };
- provider.addInteraction(interaction);
- });
-
- it('return a successful body', () => {
- return getDiscussions({
- url: provider.mockService.baseUrl,
- }).then((discussions) => {
- expect(discussions).toEqual(Discussions.body);
- });
- });
- });
- },
-);
-/* eslint-enable @gitlab/require-i18n-strings */
diff --git a/spec/contracts/consumer/specs/metadata.spec.js b/spec/contracts/consumer/specs/metadata.spec.js
deleted file mode 100644
index fc082cb6a46..00000000000
--- a/spec/contracts/consumer/specs/metadata.spec.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* eslint-disable @gitlab/require-i18n-strings */
-
-import { pactWith } from 'jest-pact';
-
-import { Metadata } from '../fixtures/metadata.fixture';
-import { getMetadata } from '../endpoints/merge_requests';
-
-pactWith(
- {
- consumer: 'Merge Request Page',
- provider: 'Merge Request Metadata Endpoint',
- log: '../logs/consumer.log',
- dir: '../contracts',
- },
-
- (provider) => {
- describe('Metadata Endpoint', () => {
- beforeEach(() => {
- const interaction = {
- state: 'a merge request exists',
- ...Metadata.request,
- willRespondWith: Metadata.success,
- };
- provider.addInteraction(interaction);
- });
-
- it('return a successful body', () => {
- return getMetadata({
- url: provider.mockService.baseUrl,
- }).then((metadata) => {
- expect(metadata).toEqual(Metadata.body);
- });
- });
- });
- },
-);
-/* eslint-enable @gitlab/require-i18n-strings */
diff --git a/spec/contracts/consumer/specs/project/merge_request/show.spec.js b/spec/contracts/consumer/specs/project/merge_request/show.spec.js
new file mode 100644
index 00000000000..8c6e029cb12
--- /dev/null
+++ b/spec/contracts/consumer/specs/project/merge_request/show.spec.js
@@ -0,0 +1,112 @@
+/* eslint-disable @gitlab/require-i18n-strings */
+
+import { pactWith } from 'jest-pact';
+
+import { DiffsBatch } from '../../../fixtures/project/merge_request/diffs_batch.fixture';
+import { Discussions } from '../../../fixtures/project/merge_request/discussions.fixture';
+import { DiffsMetadata } from '../../../fixtures/project/merge_request/diffs_metadata.fixture';
+import {
+ getDiffsBatch,
+ getDiffsMetadata,
+ getDiscussions,
+} from '../../../endpoints/project/merge_requests';
+
+const CONSUMER_NAME = 'MergeRequest#show';
+const CONSUMER_LOG = '../logs/consumer.log';
+const CONTRACT_DIR = '../contracts/project/merge_request/show';
+const DIFFS_BATCH_PROVIDER_NAME = 'Merge Request Diffs Batch Endpoint';
+const DISCUSSIONS_PROVIDER_NAME = 'Merge Request Discussions Endpoint';
+const DIFFS_METADATA_PROVIDER_NAME = 'Merge Request Diffs Metadata Endpoint';
+
+// API endpoint: /merge_requests/:id/diffs_batch.json
+pactWith(
+ {
+ consumer: CONSUMER_NAME,
+ provider: DIFFS_BATCH_PROVIDER_NAME,
+ log: CONSUMER_LOG,
+ dir: CONTRACT_DIR,
+ },
+
+ (provider) => {
+ describe(DIFFS_BATCH_PROVIDER_NAME, () => {
+ beforeEach(() => {
+ const interaction = {
+ state: 'a merge request with diffs exists',
+ ...DiffsBatch.request,
+ willRespondWith: DiffsBatch.success,
+ };
+ provider.addInteraction(interaction);
+ });
+
+ it('returns a successful body', () => {
+ return getDiffsBatch({
+ url: provider.mockService.baseUrl,
+ }).then((diffsBatch) => {
+ expect(diffsBatch).toEqual(DiffsBatch.body);
+ });
+ });
+ });
+ },
+);
+
+pactWith(
+ {
+ consumer: CONSUMER_NAME,
+ provider: DISCUSSIONS_PROVIDER_NAME,
+ log: CONSUMER_LOG,
+ dir: CONTRACT_DIR,
+ },
+
+ (provider) => {
+ describe(DISCUSSIONS_PROVIDER_NAME, () => {
+ beforeEach(() => {
+ const interaction = {
+ state: 'a merge request with discussions exists',
+ ...Discussions.request,
+ willRespondWith: Discussions.success,
+ };
+ provider.addInteraction(interaction);
+ });
+
+ it('return a successful body', () => {
+ return getDiscussions({
+ url: provider.mockService.baseUrl,
+ }).then((discussions) => {
+ expect(discussions).toEqual(Discussions.body);
+ });
+ });
+ });
+ },
+);
+
+pactWith(
+ {
+ consumer: CONSUMER_NAME,
+ provider: DIFFS_METADATA_PROVIDER_NAME,
+ log: CONSUMER_LOG,
+ dir: CONTRACT_DIR,
+ },
+
+ (provider) => {
+ describe(DIFFS_METADATA_PROVIDER_NAME, () => {
+ beforeEach(() => {
+ const interaction = {
+ state: 'a merge request exists',
+ ...DiffsMetadata.request,
+ willRespondWith: DiffsMetadata.success,
+ };
+ provider.addInteraction(interaction);
+ });
+
+ it('return a successful body', () => {
+ return getDiffsMetadata({
+ url: provider.mockService.baseUrl,
+ }).then((diffsMetadata) => {
+ expect(diffsMetadata).toEqual(DiffsMetadata.body);
+ });
+ });
+ });
+ },
+);
+
+/* eslint-enable @gitlab/require-i18n-strings */
diff --git a/spec/contracts/contracts/merge_request_page-merge_request_diffs_endpoint.json b/spec/contracts/contracts/project/merge_request/show/mergerequest#show-merge_request_diffs_batch_endpoint.json
index 2f097d8eb24..3fa13766766 100644
--- a/spec/contracts/contracts/merge_request_page-merge_request_diffs_endpoint.json
+++ b/spec/contracts/contracts/project/merge_request/show/mergerequest#show-merge_request_diffs_batch_endpoint.json
@@ -1,9 +1,9 @@
{
"consumer": {
- "name": "Merge Request Page"
+ "name": "MergeRequest#show"
},
"provider": {
- "name": "Merge Request Diffs Endpoint"
+ "name": "Merge Request Diffs Batch Endpoint"
},
"interactions": [
{
@@ -226,4 +226,4 @@
"version": "2.0.0"
}
}
-}
+} \ No newline at end of file
diff --git a/spec/contracts/contracts/merge_request_page-merge_request_metadata_endpoint.json b/spec/contracts/contracts/project/merge_request/show/mergerequest#show-merge_request_diffs_metadata_endpoint.json
index eb22b7d2e3c..b98a0127e54 100644
--- a/spec/contracts/contracts/merge_request_page-merge_request_metadata_endpoint.json
+++ b/spec/contracts/contracts/project/merge_request/show/mergerequest#show-merge_request_diffs_metadata_endpoint.json
@@ -1,13 +1,13 @@
{
"consumer": {
- "name": "Merge Request Page"
+ "name": "MergeRequest#show"
},
"provider": {
- "name": "Merge Request Metadata Endpoint"
+ "name": "Merge Request Diffs Metadata Endpoint"
},
"interactions": [
{
- "description": "a request for Metadata",
+ "description": "a request for Diffs Metadata",
"providerState": "a merge request exists",
"request": {
"method": "GET",
@@ -220,4 +220,4 @@
"version": "2.0.0"
}
}
-}
+} \ No newline at end of file
diff --git a/spec/contracts/contracts/merge_request_page-merge_request_discussions_endpoint.json b/spec/contracts/contracts/project/merge_request/show/mergerequest#show-merge_request_discussions_endpoint.json
index 819d95276b3..ecaf9c123af 100644
--- a/spec/contracts/contracts/merge_request_page-merge_request_discussions_endpoint.json
+++ b/spec/contracts/contracts/project/merge_request/show/mergerequest#show-merge_request_discussions_endpoint.json
@@ -1,6 +1,6 @@
{
"consumer": {
- "name": "Merge Request Page"
+ "name": "MergeRequest#show"
},
"provider": {
"name": "Merge Request Discussions Endpoint"
@@ -233,4 +233,4 @@
"version": "2.0.0"
}
}
-}
+} \ No newline at end of file
diff --git a/spec/contracts/provider/pact_helpers/project/merge_request/diffs_batch_helper.rb b/spec/contracts/provider/pact_helpers/project/merge_request/diffs_batch_helper.rb
new file mode 100644
index 00000000000..7d1fbe91e86
--- /dev/null
+++ b/spec/contracts/provider/pact_helpers/project/merge_request/diffs_batch_helper.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+require_relative '../../../spec_helper'
+require_relative '../../../states/project/merge_request/diffs_batch_state'
+
+module Provider
+ module DiffsBatchHelper
+ Pact.service_provider "Merge Request Diffs Batch Endpoint" do
+ app { Environments::Test.app }
+
+ honours_pact_with 'MergeRequest#show' do
+ pact_uri '../contracts/project/merge_request/show/mergerequest#show-merge_request_diffs_batch_endpoint.json'
+ end
+ end
+ end
+end
diff --git a/spec/contracts/provider/pact_helpers/project/merge_request/diffs_metadata_helper.rb b/spec/contracts/provider/pact_helpers/project/merge_request/diffs_metadata_helper.rb
new file mode 100644
index 00000000000..5f0c58d18d4
--- /dev/null
+++ b/spec/contracts/provider/pact_helpers/project/merge_request/diffs_metadata_helper.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+require_relative '../../../spec_helper'
+require_relative '../../../states/project/merge_request/diffs_metadata_state'
+
+module Provider
+ module DiffsMetadataHelper
+ Pact.service_provider "Merge Request Diffs Metadata Endpoint" do
+ app { Environments::Test.app }
+
+ honours_pact_with 'MergeRequest#show' do
+ pact_uri '../contracts/project/merge_request/show/mergerequest#show-merge_request_diffs_metadata_endpoint.json'
+ end
+ end
+ end
+end
diff --git a/spec/contracts/provider/pact_helpers/project/merge_request/discussions_helper.rb b/spec/contracts/provider/pact_helpers/project/merge_request/discussions_helper.rb
new file mode 100644
index 00000000000..0f4244ba40a
--- /dev/null
+++ b/spec/contracts/provider/pact_helpers/project/merge_request/discussions_helper.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+require_relative '../../../spec_helper'
+require_relative '../../../states/project/merge_request/discussions_state'
+
+module Provider
+ module DiscussionsHelper
+ Pact.service_provider "Merge Request Discussions Endpoint" do
+ app { Environments::Test.app }
+
+ honours_pact_with 'MergeRequest#show' do
+ pact_uri '../contracts/project/merge_request/show/mergerequest#show-merge_request_discussions_endpoint.json'
+ end
+ end
+ end
+end
diff --git a/spec/contracts/provider/specs/diffs_helper.rb b/spec/contracts/provider/specs/diffs_helper.rb
deleted file mode 100644
index 24bdd00dbae..00000000000
--- a/spec/contracts/provider/specs/diffs_helper.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-# frozen_string_literal: true
-
-require_relative '../spec_helper'
-require_relative '../states/diffs_state'
-
-module Provider
- module DiffsHelper
- Pact.service_provider "Merge Request Diffs Endpoint" do
- app { Environments::Test.app }
-
- honours_pact_with 'Merge Request Page' do
- pact_uri '../contracts/merge_request_page-merge_request_diffs_endpoint.json'
- end
- end
- end
-end
diff --git a/spec/contracts/provider/specs/discussions_helper.rb b/spec/contracts/provider/specs/discussions_helper.rb
deleted file mode 100644
index 135ccf48276..00000000000
--- a/spec/contracts/provider/specs/discussions_helper.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-# frozen_string_literal: true
-
-require_relative '../spec_helper'
-require_relative '../states/discussions_state'
-
-module Provider
- module DiscussionsHelper
- Pact.service_provider "Merge Request Discussions Endpoint" do
- app { Environments::Test.app }
-
- honours_pact_with 'Merge Request Page' do
- pact_uri '../contracts/merge_request_page-merge_request_discussions_endpoint.json'
- end
- end
- end
-end
diff --git a/spec/contracts/provider/specs/metadata_helper.rb b/spec/contracts/provider/specs/metadata_helper.rb
deleted file mode 100644
index e73b993a31a..00000000000
--- a/spec/contracts/provider/specs/metadata_helper.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-# frozen_string_literal: true
-
-require_relative '../spec_helper'
-require_relative '../states/metadata_state'
-
-module Provider
- module MetadataHelper
- Pact.service_provider "Merge Request Metadata Endpoint" do
- app { Environments::Test.app }
-
- honours_pact_with 'Merge Request Page' do
- pact_uri '../contracts/merge_request_page-merge_request_metadata_endpoint.json'
- end
- end
- end
-end
diff --git a/spec/contracts/provider/states/diffs_state.rb b/spec/contracts/provider/states/project/merge_request/diffs_batch_state.rb
index d959cde5f5e..ac20c17c187 100644
--- a/spec/contracts/provider/states/diffs_state.rb
+++ b/spec/contracts/provider/states/project/merge_request/diffs_batch_state.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-Pact.provider_states_for "Merge Request Page" do
+Pact.provider_states_for "MergeRequest#show" do
provider_state "a merge request with diffs exists" do
set_up do
user = User.find_by(name: Provider::UsersHelper::CONTRACT_USER_NAME)
diff --git a/spec/contracts/provider/states/metadata_state.rb b/spec/contracts/provider/states/project/merge_request/diffs_metadata_state.rb
index 59b290ce2fe..8754232690c 100644
--- a/spec/contracts/provider/states/metadata_state.rb
+++ b/spec/contracts/provider/states/project/merge_request/diffs_metadata_state.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-Pact.provider_states_for "Merge Request Page" do
+Pact.provider_states_for "MergeRequest#show" do
provider_state "a merge request exists" do
set_up do
user = User.find_by(name: Provider::UsersHelper::CONTRACT_USER_NAME)
diff --git a/spec/contracts/provider/states/discussions_state.rb b/spec/contracts/provider/states/project/merge_request/discussions_state.rb
index ddbcf80f2c8..2d64f85eedf 100644
--- a/spec/contracts/provider/states/discussions_state.rb
+++ b/spec/contracts/provider/states/project/merge_request/discussions_state.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-Pact.provider_states_for "Merge Request Page" do
+Pact.provider_states_for "MergeRequest#show" do
provider_state "a merge request with discussions exists" do
set_up do
user = User.find_by(name: Provider::UsersHelper::CONTRACT_USER_NAME)
diff --git a/spec/controllers/projects/releases_controller_spec.rb b/spec/controllers/projects/releases_controller_spec.rb
index 1e77da64663..ad6682601f3 100644
--- a/spec/controllers/projects/releases_controller_spec.rb
+++ b/spec/controllers/projects/releases_controller_spec.rb
@@ -148,19 +148,19 @@ RSpec.describe Projects::ReleasesController do
end
let(:release) { create(:release, project: project) }
- let(:tag) { CGI.escape(release.tag) }
+ let(:tag) { release.tag }
it_behaves_like 'successful request'
context 'when tag name contains slash' do
let(:release) { create(:release, project: project, tag: 'awesome/v1.0') }
- let(:tag) { CGI.escape(release.tag) }
+ let(:tag) { release.tag }
it_behaves_like 'successful request'
it 'is accesible at a URL encoded path' do
expect(edit_project_release_path(project, release))
- .to eq("/#{project.namespace.path}/#{project.name}/-/releases/awesome%252Fv1.0/edit")
+ .to eq("/#{project.namespace.path}/#{project.name}/-/releases/awesome%2Fv1.0/edit")
end
end
@@ -187,19 +187,19 @@ RSpec.describe Projects::ReleasesController do
end
let(:release) { create(:release, project: project) }
- let(:tag) { CGI.escape(release.tag) }
+ let(:tag) { release.tag }
it_behaves_like 'successful request'
context 'when tag name contains slash' do
let(:release) { create(:release, project: project, tag: 'awesome/v1.0') }
- let(:tag) { CGI.escape(release.tag) }
+ let(:tag) { release.tag }
it_behaves_like 'successful request'
it 'is accesible at a URL encoded path' do
expect(project_release_path(project, release))
- .to eq("/#{project.namespace.path}/#{project.name}/-/releases/awesome%252Fv1.0")
+ .to eq("/#{project.namespace.path}/#{project.name}/-/releases/awesome%2Fv1.0")
end
end
@@ -239,7 +239,7 @@ RSpec.describe Projects::ReleasesController do
end
let(:release) { create(:release, project: project) }
- let(:tag) { CGI.escape(release.tag) }
+ let(:tag) { release.tag }
context 'when user is a guest' do
let(:project) { private_project }
diff --git a/spec/helpers/diff_helper_spec.rb b/spec/helpers/diff_helper_spec.rb
index 84e702cd6a9..cf16807723b 100644
--- a/spec/helpers/diff_helper_spec.rb
+++ b/spec/helpers/diff_helper_spec.rb
@@ -468,4 +468,25 @@ RSpec.describe DiffHelper do
it { is_expected.to be_nil }
end
end
+
+ describe '#conflicts' do
+ let(:merge_request) { instance_double(MergeRequest) }
+
+ before do
+ allow(helper).to receive(:merge_request).and_return(merge_request)
+ allow(helper).to receive(:options).and_return(merge_ref_head_diff: true)
+ end
+
+ context 'when Gitlab::Git::Conflict::Resolver::ConflictSideMissing exception is raised' do
+ before do
+ allow_next_instance_of(MergeRequests::Conflicts::ListService, merge_request, allow_tree_conflicts: true) do |svc|
+ allow(svc).to receive_message_chain(:conflicts, :files).and_raise(Gitlab::Git::Conflict::Resolver::ConflictSideMissing)
+ end
+ end
+
+ it 'returns an empty hash' do
+ expect(helper.conflicts(allow_tree_conflicts: true)).to eq({})
+ end
+ end
+ end
end
diff --git a/spec/lib/gitlab/form_builders/gitlab_ui_form_builder_spec.rb b/spec/lib/gitlab/form_builders/gitlab_ui_form_builder_spec.rb
index a5f26a212ab..2b1fcac9257 100644
--- a/spec/lib/gitlab/form_builders/gitlab_ui_form_builder_spec.rb
+++ b/spec/lib/gitlab/form_builders/gitlab_ui_form_builder_spec.rb
@@ -3,163 +3,194 @@
require 'spec_helper'
RSpec.describe Gitlab::FormBuilders::GitlabUiFormBuilder do
- let_it_be(:user) { build(:user) }
- let_it_be(:fake_template) do
- Object.new.tap do |template|
- template.extend ActionView::Helpers::FormHelper
- template.extend ActionView::Helpers::FormOptionsHelper
- template.extend ActionView::Helpers::TagHelper
- template.extend ActionView::Context
- end
- end
+ include FormBuilderHelpers
- let_it_be(:form_builder) { described_class.new(:user, user, fake_template, {}) }
-
- describe '#gitlab_ui_checkbox_component' do
- let(:optional_args) { {} }
+ let_it_be(:user) { build(:user, :admin) }
- subject(:checkbox_html) { form_builder.gitlab_ui_checkbox_component(:view_diffs_file_by_file, "Show one file at a time on merge request's Changes tab", **optional_args) }
-
- context 'without optional arguments' do
- it 'renders correct html' do
- expected_html = <<~EOS
- <div class="gl-form-checkbox custom-control custom-checkbox">
- <input name="user[view_diffs_file_by_file]" type="hidden" value="0" />
- <input class="custom-control-input" type="checkbox" value="1" name="user[view_diffs_file_by_file]" id="user_view_diffs_file_by_file" />
- <label class="custom-control-label" for="user_view_diffs_file_by_file">
- Show one file at a time on merge request&#39;s Changes tab
- </label>
- </div>
- EOS
+ let_it_be(:form_builder) { described_class.new(:user, user, fake_action_view_base, {}) }
- expect(checkbox_html).to eq(html_strip_whitespace(expected_html))
+ describe '#gitlab_ui_checkbox_component' do
+ context 'when not using slots' do
+ let(:optional_args) { {} }
+
+ subject(:checkbox_html) do
+ form_builder.gitlab_ui_checkbox_component(
+ :view_diffs_file_by_file,
+ "Show one file at a time on merge request's Changes tab",
+ **optional_args
+ )
end
- end
- context 'with optional arguments' do
- let(:optional_args) do
- {
- help_text: 'Instead of all the files changed, show only one file at a time.',
- checkbox_options: { class: 'checkbox-foo-bar' },
- label_options: { class: 'label-foo-bar' },
- checked_value: '3',
- unchecked_value: '1'
- }
+ context 'without optional arguments' do
+ it 'renders correct html' do
+ expected_html = <<~EOS
+ <div class="gl-form-checkbox custom-control custom-checkbox">
+ <input name="user[view_diffs_file_by_file]" type="hidden" value="0" />
+ <input class="custom-control-input" type="checkbox" value="1" name="user[view_diffs_file_by_file]" id="user_view_diffs_file_by_file" />
+ <label class="custom-control-label" for="user_view_diffs_file_by_file">
+ <span>Show one file at a time on merge request&#39;s Changes tab</span>
+ </label>
+ </div>
+ EOS
+
+ expect(html_strip_whitespace(checkbox_html)).to eq(html_strip_whitespace(expected_html))
+ end
end
- it 'renders help text' do
- expected_html = <<~EOS
- <div class="gl-form-checkbox custom-control custom-checkbox">
- <input name="user[view_diffs_file_by_file]" type="hidden" value="1" />
- <input class="custom-control-input checkbox-foo-bar" type="checkbox" value="3" name="user[view_diffs_file_by_file]" id="user_view_diffs_file_by_file" />
- <label class="custom-control-label label-foo-bar" for="user_view_diffs_file_by_file">
- <span>Show one file at a time on merge request&#39;s Changes tab</span>
- <p class="help-text">Instead of all the files changed, show only one file at a time.</p>
- </label>
- </div>
- EOS
-
- expect(checkbox_html).to eq(html_strip_whitespace(expected_html))
- end
-
- it 'passes arguments to `check_box` method' do
- allow(fake_template).to receive(:check_box).and_return('')
-
- checkbox_html
-
- expect(fake_template).to have_received(:check_box).with(:user, :view_diffs_file_by_file, { class: %w(custom-control-input checkbox-foo-bar), object: user }, '3', '1')
+ context 'with optional arguments' do
+ let(:optional_args) do
+ {
+ help_text: 'Instead of all the files changed, show only one file at a time.',
+ checkbox_options: { class: 'checkbox-foo-bar' },
+ label_options: { class: 'label-foo-bar' },
+ checked_value: '3',
+ unchecked_value: '1'
+ }
+ end
+
+ it 'renders help text' do
+ expected_html = <<~EOS
+ <div class="gl-form-checkbox custom-control custom-checkbox">
+ <input name="user[view_diffs_file_by_file]" type="hidden" value="1" />
+ <input class="custom-control-input checkbox-foo-bar" type="checkbox" value="3" name="user[view_diffs_file_by_file]" id="user_view_diffs_file_by_file" />
+ <label class="custom-control-label label-foo-bar" for="user_view_diffs_file_by_file">
+ <span>Show one file at a time on merge request&#39;s Changes tab</span>
+ <p class="help-text" data-testid="pajamas-component-help-text">Instead of all the files changed, show only one file at a time.</p>
+ </label>
+ </div>
+ EOS
+
+ expect(html_strip_whitespace(checkbox_html)).to eq(html_strip_whitespace(expected_html))
+ end
end
- it 'passes arguments to `label` method' do
- allow(fake_template).to receive(:label).and_return('')
-
- checkbox_html
-
- expect(fake_template).to have_received(:label).with(:user, :view_diffs_file_by_file, { class: %w(custom-control-label label-foo-bar), object: user, value: nil })
+ context 'with checkbox_options: { multiple: true }' do
+ let(:optional_args) do
+ {
+ checkbox_options: { multiple: true },
+ checked_value: 'one',
+ unchecked_value: false
+ }
+ end
+
+ it 'renders labels with correct for attributes' do
+ expected_html = <<~EOS
+ <div class="gl-form-checkbox custom-control custom-checkbox">
+ <input class="custom-control-input" type="checkbox" value="one" name="user[view_diffs_file_by_file][]" id="user_view_diffs_file_by_file_one" />
+ <label class="custom-control-label" for="user_view_diffs_file_by_file_one">
+ <span>Show one file at a time on merge request&#39;s Changes tab</span>
+ </label>
+ </div>
+ EOS
+
+ expect(html_strip_whitespace(checkbox_html)).to eq(html_strip_whitespace(expected_html))
+ end
end
end
- context 'with checkbox_options: { multiple: true }' do
- let(:optional_args) do
- {
- checkbox_options: { multiple: true },
- checked_value: 'one',
- unchecked_value: false
- }
+ context 'when using slots' do
+ subject(:checkbox_html) do
+ form_builder.gitlab_ui_checkbox_component(
+ :view_diffs_file_by_file
+ ) do |c|
+ c.label { "Show one file at a time on merge request's Changes tab" }
+ c.help_text { 'Instead of all the files changed, show only one file at a time.' }
+ end
end
- it 'renders labels with correct for attributes' do
+ it 'renders correct html' do
expected_html = <<~EOS
<div class="gl-form-checkbox custom-control custom-checkbox">
- <input class="custom-control-input" type="checkbox" value="one" name="user[view_diffs_file_by_file][]" id="user_view_diffs_file_by_file_one" />
- <label class="custom-control-label" for="user_view_diffs_file_by_file_one">
- Show one file at a time on merge request&#39;s Changes tab
+ <input name="user[view_diffs_file_by_file]" type="hidden" value="0" />
+ <input class="custom-control-input" type="checkbox" value="1" name="user[view_diffs_file_by_file]" id="user_view_diffs_file_by_file" />
+ <label class="custom-control-label" for="user_view_diffs_file_by_file">
+ <span>Show one file at a time on merge request&#39;s Changes tab</span>
+ <p class="help-text" data-testid="pajamas-component-help-text">Instead of all the files changed, show only one file at a time.</p>
</label>
</div>
EOS
- expect(checkbox_html).to eq(html_strip_whitespace(expected_html))
+ expect(html_strip_whitespace(checkbox_html)).to eq(html_strip_whitespace(expected_html))
end
end
end
describe '#gitlab_ui_radio_component' do
- let(:optional_args) { {} }
-
- subject(:radio_html) { form_builder.gitlab_ui_radio_component(:access_level, :admin, "Access Level", **optional_args) }
+ context 'when not using slots' do
+ let(:optional_args) { {} }
+
+ subject(:radio_html) do
+ form_builder.gitlab_ui_radio_component(
+ :access_level,
+ :admin,
+ "Admin",
+ **optional_args
+ )
+ end
- context 'without optional arguments' do
- it 'renders correct html' do
- expected_html = <<~EOS
- <div class="gl-form-radio custom-control custom-radio">
- <input class="custom-control-input" type="radio" value="admin" name="user[access_level]" id="user_access_level_admin" />
- <label class="custom-control-label" for="user_access_level_admin">
- Access Level
- </label>
- </div>
- EOS
+ context 'without optional arguments' do
+ it 'renders correct html' do
+ expected_html = <<~EOS
+ <div class="gl-form-radio custom-control custom-radio">
+ <input class="custom-control-input" type="radio" value="admin" checked="checked" name="user[access_level]" id="user_access_level_admin" />
+ <label class="custom-control-label" for="user_access_level_admin">
+ <span>Admin</span>
+ </label>
+ </div>
+ EOS
+
+ expect(html_strip_whitespace(radio_html)).to eq(html_strip_whitespace(expected_html))
+ end
+ end
- expect(radio_html).to eq(html_strip_whitespace(expected_html))
+ context 'with optional arguments' do
+ let(:optional_args) do
+ {
+ help_text: 'Administrators have access to all groups, projects, and users and can manage all features in this installation',
+ radio_options: { class: 'radio-foo-bar' },
+ label_options: { class: 'label-foo-bar' }
+ }
+ end
+
+ it 'renders help text' do
+ expected_html = <<~EOS
+ <div class="gl-form-radio custom-control custom-radio">
+ <input class="custom-control-input radio-foo-bar" type="radio" value="admin" checked="checked" name="user[access_level]" id="user_access_level_admin" />
+ <label class="custom-control-label label-foo-bar" for="user_access_level_admin">
+ <span>Admin</span>
+ <p class="help-text" data-testid="pajamas-component-help-text">Administrators have access to all groups, projects, and users and can manage all features in this installation</p>
+ </label>
+ </div>
+ EOS
+
+ expect(html_strip_whitespace(radio_html)).to eq(html_strip_whitespace(expected_html))
+ end
end
end
- context 'with optional arguments' do
- let(:optional_args) do
- {
- help_text: 'Administrators have access to all groups, projects, and users and can manage all features in this installation',
- radio_options: { class: 'radio-foo-bar' },
- label_options: { class: 'label-foo-bar' }
- }
+ context 'when using slots' do
+ subject(:radio_html) do
+ form_builder.gitlab_ui_radio_component(
+ :access_level,
+ :admin
+ ) do |c|
+ c.label { "Admin" }
+ c.help_text { 'Administrators have access to all groups, projects, and users and can manage all features in this installation' }
+ end
end
- it 'renders help text' do
+ it 'renders correct html' do
expected_html = <<~EOS
<div class="gl-form-radio custom-control custom-radio">
- <input class="custom-control-input radio-foo-bar" type="radio" value="admin" name="user[access_level]" id="user_access_level_admin" />
- <label class="custom-control-label label-foo-bar" for="user_access_level_admin">
- <span>Access Level</span>
- <p class="help-text">Administrators have access to all groups, projects, and users and can manage all features in this installation</p>
+ <input class="custom-control-input" type="radio" value="admin" checked="checked" name="user[access_level]" id="user_access_level_admin" />
+ <label class="custom-control-label" for="user_access_level_admin">
+ <span>Admin</span>
+ <p class="help-text" data-testid="pajamas-component-help-text">Administrators have access to all groups, projects, and users and can manage all features in this installation</p>
</label>
</div>
EOS
- expect(radio_html).to eq(html_strip_whitespace(expected_html))
- end
-
- it 'passes arguments to `radio_button` method' do
- allow(fake_template).to receive(:radio_button).and_return('')
-
- radio_html
-
- expect(fake_template).to have_received(:radio_button).with(:user, :access_level, :admin, { class: %w(custom-control-input radio-foo-bar), object: user })
- end
-
- it 'passes arguments to `label` method' do
- allow(fake_template).to receive(:label).and_return('')
-
- radio_html
-
- expect(fake_template).to have_received(:label).with(:user, :access_level, { class: %w(custom-control-label label-foo-bar), object: user, value: :admin })
+ expect(html_strip_whitespace(radio_html)).to eq(html_strip_whitespace(expected_html))
end
end
end
diff --git a/spec/requests/api/internal/workhorse_spec.rb b/spec/requests/api/internal/workhorse_spec.rb
index e6836d8fef5..d40c14cc0fd 100644
--- a/spec/requests/api/internal/workhorse_spec.rb
+++ b/spec/requests/api/internal/workhorse_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe API::Internal::Workhorse do
+RSpec.describe API::Internal::Workhorse, :allow_forgery_protection do
include WorkhorseHelpers
context '/authorize_upload' do
diff --git a/spec/requests/api/releases_spec.rb b/spec/requests/api/releases_spec.rb
index 3108197f662..c050214ff50 100644
--- a/spec/requests/api/releases_spec.rb
+++ b/spec/requests/api/releases_spec.rb
@@ -227,6 +227,7 @@ RSpec.describe API::Releases do
get api("/projects/#{project.id}/releases", maintainer)
expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response[0]['tag_path']).to include('%2F') # properly escape the slash
end
end
diff --git a/spec/services/merge_requests/mergeability/run_checks_service_spec.rb b/spec/services/merge_requests/mergeability/run_checks_service_spec.rb
index d4ee4afd71d..2bb7dc3eef7 100644
--- a/spec/services/merge_requests/mergeability/run_checks_service_spec.rb
+++ b/spec/services/merge_requests/mergeability/run_checks_service_spec.rb
@@ -7,12 +7,6 @@ RSpec.describe MergeRequests::Mergeability::RunChecksService do
let_it_be(:merge_request) { create(:merge_request) }
- describe '#CHECKS' do
- it 'contains every subclass of the base checks service', :eager_load do
- expect(described_class::CHECKS).to contain_exactly(*MergeRequests::Mergeability::CheckBaseService.subclasses)
- end
- end
-
describe '#execute' do
subject(:execute) { run_checks.execute }
@@ -22,8 +16,8 @@ RSpec.describe MergeRequests::Mergeability::RunChecksService do
context 'when every check is skipped', :eager_load do
before do
MergeRequests::Mergeability::CheckBaseService.subclasses.each do |subclass|
- expect_next_instance_of(subclass) do |service|
- expect(service).to receive(:skip?).and_return(true)
+ allow_next_instance_of(subclass) do |service|
+ allow(service).to receive(:skip?).and_return(true)
end
end
end
@@ -35,7 +29,7 @@ RSpec.describe MergeRequests::Mergeability::RunChecksService do
context 'when a check is skipped' do
it 'does not execute the check' do
- described_class::CHECKS.each do |check|
+ merge_request.mergeability_checks.each do |check|
allow_next_instance_of(check) do |service|
allow(service).to receive(:skip?).and_return(false)
allow(service).to receive(:execute).and_return(success_result)
@@ -47,7 +41,13 @@ RSpec.describe MergeRequests::Mergeability::RunChecksService do
expect(service).not_to receive(:execute)
end
- expect(execute).to match_array([success_result, success_result, success_result, success_result])
+ # Since we're only marking one check to be skipped, we expect to receive
+ # `# of checks - 1` success result objects in return
+ #
+ check_count = merge_request.mergeability_checks.count - 1
+ success_array = (1..check_count).each_with_object([]) { |_, array| array << success_result }
+
+ expect(execute).to match_array(success_array)
end
end
@@ -56,7 +56,7 @@ RSpec.describe MergeRequests::Mergeability::RunChecksService do
let(:merge_check) { instance_double(MergeRequests::Mergeability::CheckCiStatusService) }
before do
- described_class::CHECKS.each do |check|
+ merge_request.mergeability_checks.each do |check|
allow_next_instance_of(check) do |service|
allow(service).to receive(:skip?).and_return(true)
end
diff --git a/spec/support/helpers/form_builder_helpers.rb b/spec/support/helpers/form_builder_helpers.rb
new file mode 100644
index 00000000000..4bae7421c4d
--- /dev/null
+++ b/spec/support/helpers/form_builder_helpers.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module FormBuilderHelpers
+ def fake_action_view_base
+ lookup_context = ActionView::LookupContext.new(ActionController::Base.view_paths)
+
+ ActionView::Base.new(lookup_context, {}, ApplicationController.new)
+ end
+
+ def fake_form_for(&block)
+ fake_action_view_base.form_for :user, url: '/user', &block
+ end
+end
diff --git a/spec/support/shared_examples/components/pajamas_shared_examples.rb b/spec/support/shared_examples/components/pajamas_shared_examples.rb
new file mode 100644
index 00000000000..5c0ad1a1bc9
--- /dev/null
+++ b/spec/support/shared_examples/components/pajamas_shared_examples.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'it renders help text' do
+ it 'renders help text' do
+ expect(rendered_component).to have_selector('[data-testid="pajamas-component-help-text"]', text: help_text)
+ end
+end
+
+RSpec.shared_examples 'it does not render help text' do
+ it 'does not render help text' do
+ expect(rendered_component).not_to have_selector('[data-testid="pajamas-component-help-text"]')
+ end
+end
diff --git a/spec/support/shared_examples/graphql/types/gitlab_style_deprecations_shared_examples.rb b/spec/support/shared_examples/graphql/types/gitlab_style_deprecations_shared_examples.rb
index cf9c36fafe8..7fd54408b11 100644
--- a/spec/support/shared_examples/graphql/types/gitlab_style_deprecations_shared_examples.rb
+++ b/spec/support/shared_examples/graphql/types/gitlab_style_deprecations_shared_examples.rb
@@ -53,18 +53,20 @@ RSpec.shared_examples 'Gitlab-style deprecations' do
it 'adds information about the replacement if provided' do
deprecable = subject(deprecated: { milestone: '1.10', reason: :renamed, replacement: 'Foo.bar' })
- expect(deprecable.deprecation_reason).to include 'Please use `Foo.bar`'
+ expect(deprecable.deprecation_reason).to include('Please use `Foo.bar`')
end
it 'supports named reasons: renamed' do
deprecable = subject(deprecated: { milestone: '1.10', reason: :renamed })
- expect(deprecable.deprecation_reason).to include 'This was renamed.'
+ expect(deprecable.deprecation_reason).to eq('This was renamed. Deprecated in 1.10.')
end
it 'supports named reasons: alpha' do
deprecable = subject(deprecated: { milestone: '1.10', reason: :alpha })
- expect(deprecable.deprecation_reason).to include 'This feature is in Alpha'
+ expect(deprecable.deprecation_reason).to eq(
+ 'This feature is in Alpha. It can be changed or removed at any time. Introduced in 1.10.'
+ )
end
end