diff options
Diffstat (limited to 'spec/support/shared_contexts')
13 files changed, 181 insertions, 64 deletions
diff --git a/spec/support/shared_contexts/bulk_imports_requests_shared_context.rb b/spec/support/shared_contexts/bulk_imports_requests_shared_context.rb index 5fcb14e075a..2f74d3131ab 100644 --- a/spec/support/shared_contexts/bulk_imports_requests_shared_context.rb +++ b/spec/support/shared_contexts/bulk_imports_requests_shared_context.rb @@ -25,15 +25,15 @@ RSpec.shared_context 'bulk imports requests context' do |url| stub_request(:get, "https://gitlab.example.com/api/v4/groups?min_access_level=50&page=1&per_page=20&private_token=demo-pat&search=test&top_level_only=true") .with(headers: request_headers) .to_return(status: 200, - body: [{ - id: 2595440, - web_url: 'https://gitlab.com/groups/test', - name: 'Test', - path: 'stub-test-group', - full_name: 'Test', - full_path: 'stub-test-group' - }].to_json, - headers: page_response_headers) + body: [{ + id: 2595440, + web_url: 'https://gitlab.com/groups/test', + name: 'Test', + path: 'stub-test-group', + full_name: 'Test', + full_path: 'stub-test-group' + }].to_json, + headers: page_response_headers) stub_request(:get, "%{url}/api/v4/groups?min_access_level=50&page=1&per_page=20&private_token=demo-pat&search=&top_level_only=true" % { url: url }) .to_return( diff --git a/spec/support/shared_contexts/design_management_shared_contexts.rb b/spec/support/shared_contexts/design_management_shared_contexts.rb index e6ae7e03664..d89bcada1df 100644 --- a/spec/support/shared_contexts/design_management_shared_contexts.rb +++ b/spec/support/shared_contexts/design_management_shared_contexts.rb @@ -14,23 +14,23 @@ RSpec.shared_context 'four designs in three versions' do let_it_be(:first_version) do create(:design_version, issue: issue, - created_designs: [design_a], - modified_designs: [], - deleted_designs: []) + created_designs: [design_a], + modified_designs: [], + deleted_designs: []) end let_it_be(:second_version) do create(:design_version, issue: issue, - created_designs: [design_b, design_c, design_d], - modified_designs: [design_a], - deleted_designs: []) + created_designs: [design_b, design_c, design_d], + modified_designs: [design_a], + deleted_designs: []) end let_it_be(:third_version) do create(:design_version, issue: issue, - created_designs: [], - modified_designs: [design_a], - deleted_designs: [design_d]) + created_designs: [], + modified_designs: [design_a], + deleted_designs: [design_d]) end before do diff --git a/spec/support/shared_contexts/finders/merge_requests_finder_shared_contexts.rb b/spec/support/shared_contexts/finders/merge_requests_finder_shared_contexts.rb index 4c003dff947..91b6baac610 100644 --- a/spec/support/shared_contexts/finders/merge_requests_finder_shared_contexts.rb +++ b/spec/support/shared_contexts/finders/merge_requests_finder_shared_contexts.rb @@ -55,33 +55,33 @@ RSpec.shared_context 'MergeRequestsFinder multiple projects with merge requests let!(:merge_request1) do create(:merge_request, assignees: [user], author: user, reviewers: [user2], - source_project: project2, target_project: project1, - target_branch: 'merged-target') + source_project: project2, target_project: project1, + target_branch: 'merged-target') end let!(:merge_request2) do create(:merge_request, :conflict, assignees: [user], author: user, reviewers: [user2], - source_project: project2, target_project: project1, - state: 'closed') + source_project: project2, target_project: project1, + state: 'closed') end let!(:merge_request3) do create(:merge_request, :simple, author: user, assignees: [user2], reviewers: [user], - source_project: project2, target_project: project2, - state: 'locked', - title: 'thing WIP thing') + source_project: project2, target_project: project2, + state: 'locked', + title: 'thing WIP thing') end let!(:merge_request4) do create(:merge_request, :simple, author: user, - source_project: project3, target_project: project3, - title: 'WIP thing') + source_project: project3, target_project: project3, + title: 'WIP thing') end let_it_be(:merge_request5) do create(:merge_request, :simple, author: user, - source_project: project4, target_project: project4, - title: '[WIP]') + source_project: project4, target_project: project4, + title: '[WIP]') end let!(:label_link) { create(:label_link, label: label, target: merge_request2) } diff --git a/spec/support/shared_contexts/markdown_snapshot_shared_examples.rb b/spec/support/shared_contexts/glfm/api_markdown_snapshot_shared_context.rb index 040b2da9f37..3623fa0850d 100644 --- a/spec/support/shared_contexts/markdown_snapshot_shared_examples.rb +++ b/spec/support/shared_contexts/glfm/api_markdown_snapshot_shared_context.rb @@ -1,31 +1,28 @@ # frozen_string_literal: true -require 'spec_helper' +require_relative '../../../../scripts/lib/glfm/constants' # See https://docs.gitlab.com/ee/development/gitlab_flavored_markdown/specification_guide/#markdown-snapshot-testing # for documentation on this spec. -# rubocop:disable Layout/LineLength -RSpec.shared_context 'with API::Markdown Snapshot shared context' do |glfm_specification_dir| - # rubocop:enable Layout/LineLength - include ApiHelpers - - let_it_be(:user) { create(:user) } - let_it_be(:api_url) { api('/markdown', user) } +RSpec.shared_context 'with API::Markdown Snapshot shared context' do |ee_only: false| + include_context 'with GLFM example snapshot fixtures' - markdown_examples, html_examples = %w[markdown.yml html.yml].map do |file_name| - yaml = File.read("#{glfm_specification_dir}/example_snapshots/#{file_name}") - YAML.safe_load(yaml, symbolize_names: true, aliases: true) - end + include ApiHelpers - normalizations_yaml = File.read( - "#{glfm_specification_dir}/input/gitlab_flavored_markdown/glfm_example_normalizations.yml") - normalizations_by_example_name = YAML.safe_load(normalizations_yaml, symbolize_names: true, aliases: true) + markdown_examples, html_examples, normalizations_by_example_name, metadata_by_example_name = [ + Glfm::Constants::ES_MARKDOWN_YML_PATH, + Glfm::Constants::ES_HTML_YML_PATH, + Glfm::Constants::GLFM_EXAMPLE_NORMALIZATIONS_YML_PATH, + Glfm::Constants::GLFM_EXAMPLE_METADATA_YML_PATH + ].map { |path| YAML.safe_load(File.open(path), symbolize_names: true, aliases: true) } if (focused_markdown_examples_string = ENV['FOCUSED_MARKDOWN_EXAMPLES']) focused_markdown_examples = focused_markdown_examples_string.split(',').map(&:strip).map(&:to_sym) markdown_examples.select! { |example_name| focused_markdown_examples.include?(example_name) } end + markdown_examples.select! { |example_name| !!metadata_by_example_name&.dig(example_name, :ee) == ee_only } + markdown_examples.each do |name, markdown| context "for #{name}" do let(:html) { html_examples.fetch(name).fetch(:static) } @@ -34,13 +31,13 @@ RSpec.shared_context 'with API::Markdown Snapshot shared context' do |glfm_speci it "verifies conversion of GLFM to HTML", :unlimited_max_formatted_output_length do # noinspection RubyResolve normalized_html = normalize_html(html, normalizations) + api_url = metadata_by_example_name&.dig(name, :api_request_override_path) || (api "/markdown") post api_url, params: { text: markdown, gfm: true } expect(response).to be_successful - response_body = Gitlab::Json.parse(response.body) - # Some requests have the HTML in the `html` key, others in the `body` key. - response_html = response_body['body'] ? response_body.fetch('body') : response_body.fetch('html') - # noinspection RubyResolve + parsed_response = Gitlab::Json.parse(response.body, symbolize_names: true) + # Some responses have the HTML in the `html` key, others in the `body` key. + response_html = parsed_response[:body] || parsed_response[:html] normalized_response_html = normalize_html(response_html, normalizations) expect(normalized_response_html).to eq(normalized_html) diff --git a/spec/support/shared_contexts/glfm/example_snapshot_fixtures.rb b/spec/support/shared_contexts/glfm/example_snapshot_fixtures.rb new file mode 100644 index 00000000000..22b401bc841 --- /dev/null +++ b/spec/support/shared_contexts/glfm/example_snapshot_fixtures.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +RSpec.shared_context 'with GLFM example snapshot fixtures' do + let_it_be(:user) { create(:user) } + let_it_be(:group) { create(:group, name: 'glfm_group').tap { |group| group.add_owner(user) } } + + let_it_be(:project) do + # NOTE: We hardcode the IDs on all fixtures to prevent variability in the + # rendered HTML/Prosemirror JSON, and to minimize the need for normalization: + # https://docs.gitlab.com/ee/development/gitlab_flavored_markdown/specification_guide/#normalization + create(:project, :repository, creator: user, group: group, name: 'glfm_project', id: 77777) + end + + let_it_be(:project_snippet) { create(:project_snippet, title: 'glfm_project_snippet', id: 88888, project: project) } + let_it_be(:personal_snippet) { create(:snippet, id: 99999) } + + before do + # Set 'GITLAB_TEST_FOOTNOTE_ID' in order to override random number generation in + # Banzai::Filter::FootnoteFilter#random_number, and thus avoid the need to + # perform normalization on the value. See: + # https://docs.gitlab.com/ee/development/gitlab_flavored_markdown/specification_guide/#normalization + stub_env('GITLAB_TEST_FOOTNOTE_ID', 42) + + stub_licensed_features(group_wikis: true) + sign_in(user) + end +end diff --git a/spec/support/shared_contexts/graphql/requests/packages_shared_context.rb b/spec/support/shared_contexts/graphql/requests/packages_shared_context.rb index b29a231f3a6..d7cfdc09732 100644 --- a/spec/support/shared_contexts/graphql/requests/packages_shared_context.rb +++ b/spec/support/shared_contexts/graphql/requests/packages_shared_context.rb @@ -16,8 +16,8 @@ RSpec.shared_context 'package details setup' do let(:metadata_response) { graphql_data_at(:package, :metadata) } let(:first_file) { package.package_files.find { |f| a_graphql_entity_for(f).matches?(first_file_response) } } let(:package_files_response) { graphql_data_at(:package, :package_files, :nodes) } - let(:first_file_response) { graphql_data_at(:package, :package_files, :nodes, 0)} - let(:first_file_response_metadata) { graphql_data_at(:package, :package_files, :nodes, 0, :file_metadata)} + let(:first_file_response) { graphql_data_at(:package, :package_files, :nodes, 0) } + let(:first_file_response_metadata) { graphql_data_at(:package, :package_files, :nodes, 0, :file_metadata) } let(:query) do graphql_query_for(:package, { id: package_global_id }, <<~FIELDS) diff --git a/spec/support/shared_contexts/markdown_golden_master_shared_examples.rb b/spec/support/shared_contexts/markdown_golden_master_shared_examples.rb index dea03af2248..168aef0f174 100644 --- a/spec/support/shared_contexts/markdown_golden_master_shared_examples.rb +++ b/spec/support/shared_contexts/markdown_golden_master_shared_examples.rb @@ -42,7 +42,7 @@ RSpec.shared_context 'API::Markdown Golden Master shared context' do |markdown_y if focused_markdown_examples_string = ENV['FOCUSED_MARKDOWN_EXAMPLES'] focused_markdown_examples = focused_markdown_examples_string.split(',').map(&:strip) || [] - markdown_examples.reject! {|markdown_example| !focused_markdown_examples.include?(markdown_example.fetch(:name)) } + markdown_examples.reject! { |markdown_example| !focused_markdown_examples.include?(markdown_example.fetch(:name)) } end markdown_examples.each do |markdown_example| diff --git a/spec/support/shared_contexts/navbar_structure_context.rb b/spec/support/shared_contexts/navbar_structure_context.rb index 6c2ed79b343..064e40287be 100644 --- a/spec/support/shared_contexts/navbar_structure_context.rb +++ b/spec/support/shared_contexts/navbar_structure_context.rb @@ -109,8 +109,9 @@ RSpec.shared_context 'project navbar structure' do _('Webhooks'), _('Access Tokens'), _('Repository'), + _('Merge requests'), _('CI/CD'), - _('Packages & Registries'), + _('Packages and registries'), _('Monitor'), s_('UsageQuota|Usage Quotas') ] @@ -139,7 +140,17 @@ RSpec.shared_context 'group navbar structure' do _('Repository'), _('CI/CD'), _('Applications'), - _('Packages & Registries') + _('Packages and registries'), + _('Domain Verification') + ] + } + end + + let(:settings_for_maintainer_nav_item) do + { + nav_item: _('Settings'), + nav_sub_items: [ + _('Repository') ] } end @@ -162,13 +173,6 @@ RSpec.shared_context 'group navbar structure' do } end - let(:push_rules_nav_item) do - { - nav_item: _('Push Rules'), - nav_sub_items: [] - } - end - let(:ci_cd_nav_item) do { nav_item: _('CI/CD'), @@ -210,7 +214,6 @@ RSpec.shared_context 'group navbar structure' do nav_sub_items: [] }, (security_and_compliance_nav_item if Gitlab.ee?), - (push_rules_nav_item if Gitlab.ee?), { nav_item: _('Kubernetes'), nav_sub_items: [] diff --git a/spec/support/shared_contexts/policies/project_policy_shared_context.rb b/spec/support/shared_contexts/policies/project_policy_shared_context.rb index 1d4731d9b39..fc7255a4a20 100644 --- a/spec/support/shared_contexts/policies/project_policy_shared_context.rb +++ b/spec/support/shared_contexts/policies/project_policy_shared_context.rb @@ -6,13 +6,19 @@ RSpec.shared_context 'ProjectPolicy context' do let_it_be(:reporter) { create(:user) } let_it_be(:developer) { create(:user) } let_it_be(:maintainer) { create(:user) } + let_it_be(:inherited_guest) { create(:user) } + let_it_be(:inherited_reporter) { create(:user) } + let_it_be(:inherited_developer) { create(:user) } + let_it_be(:inherited_maintainer) { create(:user) } let_it_be(:owner) { create(:user) } let_it_be(:admin) { create(:admin) } let_it_be(:non_member) { create(:user) } + let_it_be_with_refind(:group) { create(:group, :public) } let_it_be_with_refind(:private_project) { create(:project, :private, namespace: owner.namespace) } let_it_be_with_refind(:internal_project) { create(:project, :internal, namespace: owner.namespace) } let_it_be_with_refind(:public_project) { create(:project, :public, namespace: owner.namespace) } - let_it_be_with_refind(:public_project_in_group) { create(:project, :public, namespace: create(:group, :public)) } + let_it_be_with_refind(:public_project_in_group) { create(:project, :public, namespace: group) } + let_it_be_with_refind(:private_project_in_group) { create(:project, :private, namespace: group) } let(:base_guest_permissions) do %i[ @@ -95,6 +101,11 @@ RSpec.shared_context 'ProjectPolicy context' do let(:owner_permissions) { base_owner_permissions + additional_owner_permissions } before_all do + group.add_guest(inherited_guest) + group.add_reporter(inherited_reporter) + group.add_developer(inherited_developer) + group.add_maintainer(inherited_maintainer) + [private_project, internal_project, public_project, public_project_in_group].each do |project| project.add_guest(guest) project.add_reporter(reporter) diff --git a/spec/support/shared_contexts/projects/container_repository/cleanup_tags_service_shared_context.rb b/spec/support/shared_contexts/projects/container_repository/cleanup_tags_service_shared_context.rb new file mode 100644 index 00000000000..c976bbe9212 --- /dev/null +++ b/spec/support/shared_contexts/projects/container_repository/cleanup_tags_service_shared_context.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +RSpec.shared_context 'for a cleanup tags service' do + def expected_service_response(status: :success, deleted: [], original_size: tags.size) + { + status: status, + deleted: deleted, + original_size: original_size, + before_delete_size: deleted&.size + }.compact.merge(deleted_size: deleted&.size) + end + + def expect_delete(tags, container_expiration_policy: nil) + service = instance_double('Projects::ContainerRepository::DeleteTagsService') + + expect(Projects::ContainerRepository::DeleteTagsService) + .to receive(:new) + .with(repository.project, user, tags: tags, container_expiration_policy: container_expiration_policy) + .and_return(service) + + expect(service).to receive(:execute) + .with(repository) { { status: :success, deleted: tags } } + end + + def expect_no_caching + expect(::Gitlab::Redis::Cache).not_to receive(:with) + end +end diff --git a/spec/support/shared_contexts/requests/api/conan_packages_shared_context.rb b/spec/support/shared_contexts/requests/api/conan_packages_shared_context.rb index b90270356f8..3974338238a 100644 --- a/spec/support/shared_contexts/requests/api/conan_packages_shared_context.rb +++ b/spec/support/shared_contexts/requests/api/conan_packages_shared_context.rb @@ -64,5 +64,5 @@ RSpec.shared_context 'conan file upload endpoints' do let(:jwt) { build_jwt(personal_access_token) } let(:headers_with_token) { build_token_auth_header(jwt.encoded).merge(workhorse_headers) } - let(:recipe_path) { "foo/bar/#{project.full_path.tr('/', '+')}/baz"} + let(:recipe_path) { "foo/bar/#{project.full_path.tr('/', '+')}/baz" } end diff --git a/spec/support/shared_contexts/requests/api/debian_repository_shared_context.rb b/spec/support/shared_contexts/requests/api/debian_repository_shared_context.rb index 95b8b7ed9f8..cf090c7a185 100644 --- a/spec/support/shared_contexts/requests/api/debian_repository_shared_context.rb +++ b/spec/support/shared_contexts/requests/api/debian_repository_shared_context.rb @@ -18,6 +18,11 @@ RSpec.shared_context 'Debian repository shared context' do |container_type, can_ let_it_be(:private_architecture_all, freeze: true) { create("debian_#{container_type}_architecture", distribution: private_distribution, name: 'all') } let_it_be(:private_architecture, freeze: true) { create("debian_#{container_type}_architecture", distribution: private_distribution, name: 'existing-arch') } let_it_be(:private_component_file) { create("debian_#{container_type}_component_file", component: private_component, architecture: private_architecture) } + let_it_be(:private_component_file_sources) { create("debian_#{container_type}_component_file", :sources, component: private_component) } + let_it_be(:private_component_file_di) { create("debian_#{container_type}_component_file", :di_packages, component: private_component, architecture: private_architecture) } + let_it_be(:private_component_file_older_sha256) { create("debian_#{container_type}_component_file", :older_sha256, component: private_component, architecture: private_architecture) } + let_it_be(:private_component_file_sources_older_sha256) { create("debian_#{container_type}_component_file", :sources, :older_sha256, component: private_component) } + let_it_be(:private_component_file_di_older_sha256) { create("debian_#{container_type}_component_file", :di_packages, :older_sha256, component: private_component, architecture: private_architecture) } let_it_be(:public_distribution, freeze: true) { create("debian_#{container_type}_distribution", :with_file, container: public_container, codename: 'existing-codename') } let_it_be(:public_distribution_key, freeze: true) { create("debian_#{container_type}_distribution_key", distribution: public_distribution) } @@ -25,6 +30,11 @@ RSpec.shared_context 'Debian repository shared context' do |container_type, can_ let_it_be(:public_architecture_all, freeze: true) { create("debian_#{container_type}_architecture", distribution: public_distribution, name: 'all') } let_it_be(:public_architecture, freeze: true) { create("debian_#{container_type}_architecture", distribution: public_distribution, name: 'existing-arch') } let_it_be(:public_component_file) { create("debian_#{container_type}_component_file", component: public_component, architecture: public_architecture) } + let_it_be(:public_component_file_sources) { create("debian_#{container_type}_component_file", :sources, component: public_component) } + let_it_be(:public_component_file_di) { create("debian_#{container_type}_component_file", :di_packages, component: public_component, architecture: public_architecture) } + let_it_be(:public_component_file_older_sha256) { create("debian_#{container_type}_component_file", :older_sha256, component: public_component, architecture: public_architecture) } + let_it_be(:public_component_file_sources_older_sha256) { create("debian_#{container_type}_component_file", :sources, :older_sha256, component: public_component) } + let_it_be(:public_component_file_di_older_sha256) { create("debian_#{container_type}_component_file", :di_packages, :older_sha256, component: public_component, architecture: public_architecture) } if container_type == :group let_it_be(:private_project) { create(:project, :private, group: private_container) } @@ -48,7 +58,9 @@ RSpec.shared_context 'Debian repository shared context' do |container_type, can_ let(:distribution) { { private: private_distribution, public: public_distribution }[visibility_level] } let(:architecture) { { private: private_architecture, public: public_architecture }[visibility_level] } let(:component) { { private: private_component, public: public_component }[visibility_level] } - let(:component_file) { { private: private_component_file, public: public_component_file }[visibility_level] } + let(:component_file_older_sha256) { { private: private_component_file_older_sha256, public: public_component_file_older_sha256 }[visibility_level] } + let(:component_file_sources_older_sha256) { { private: private_component_file_sources_older_sha256, public: public_component_file_sources_older_sha256 }[visibility_level] } + let(:component_file_di_older_sha256) { { private: private_component_file_di_older_sha256, public: public_component_file_di_older_sha256 }[visibility_level] } let(:package) { { private: private_package, public: public_package }[visibility_level] } let(:letter) { package.name[0..2] == 'lib' ? package.name[0..3] : package.name[0] } diff --git a/spec/support/shared_contexts/views/html_safe_render_shared_context.rb b/spec/support/shared_contexts/views/html_safe_render_shared_context.rb new file mode 100644 index 00000000000..3acca60c901 --- /dev/null +++ b/spec/support/shared_contexts/views/html_safe_render_shared_context.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +RSpec.shared_context 'when rendered view has no HTML escapes', type: :view do + # Check once per example if `rendered` contains HTML escapes. + let(:rendered) do |example| + super().tap do |rendered| + next if example.metadata[:skip_html_escaped_tags_check] + + ensure_no_html_escaped_tags!(rendered, example) + end + end + + def ensure_no_html_escaped_tags!(content, example) + match_data = HtmlEscapedHelpers.match_html_escaped_tags(content) + return unless match_data + + # Truncate + pre_match = match_data.pre_match.last(50) + match = match_data[0] + post_match = match_data.post_match.first(50) + + string = "#{pre_match}«#{match}»#{post_match}" + + raise <<~MESSAGE + The following string contains HTML escaped tags: + + #{string} + + Please consider using `.html_safe`. + + This check can be disabled via: + + it #{example.description.inspect}, :skip_html_escaped_tags_check do + ... + end + + MESSAGE + end +end |