diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-06-16 09:08:59 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-06-16 09:08:59 +0300 |
commit | 06bcbc77e472a70b8332150a941539c55953ef2b (patch) | |
tree | 903ff19991a3c3234626b1e86827a42063eeac61 /spec | |
parent | 1325f8cf2dce0f24403ea27c4ee58afd51fa3a8e (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
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'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'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'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'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'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'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'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 |