diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-08-01 09:12:25 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-08-01 09:12:25 +0300 |
commit | 2bfa43cf3a8b0bb25a85066ff48db58f068bc493 (patch) | |
tree | 7ba5f89b4953742f025f5c8e0911cd1f964bb2e5 /spec | |
parent | 188f99dcc3de4678b308851d1cd8d26a200393cd (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r-- | spec/features/groups/show_spec.rb | 43 | ||||
-rw-r--r-- | spec/features/users/email_verification_on_login_spec.rb | 2 | ||||
-rw-r--r-- | spec/frontend/groups/components/group_item_spec.js | 49 | ||||
-rw-r--r-- | spec/frontend/groups/components/groups_spec.js | 4 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/parsers/sbom/cyclonedx_spec.rb | 24 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/parsers/sbom/validators/cyclonedx_schema_validator_spec.rb | 132 | ||||
-rw-r--r-- | spec/lib/gitlab/global_id/deprecations_spec.rb | 11 | ||||
-rw-r--r-- | spec/models/concerns/token_authenticatable_spec.rb | 8 | ||||
-rw-r--r-- | spec/services/notes/copy_service_spec.rb | 4 |
9 files changed, 225 insertions, 52 deletions
diff --git a/spec/features/groups/show_spec.rb b/spec/features/groups/show_spec.rb index 1e49e7b02fe..d814906a274 100644 --- a/spec/features/groups/show_spec.rb +++ b/spec/features/groups/show_spec.rb @@ -97,28 +97,43 @@ RSpec.describe 'Group show page' do end end - context 'when a public project is shared with a private group' do - let_it_be(:private_group) { create(:group, :private) } + context 'visibility warning popover' do let_it_be(:public_project) { create(:project, :public) } - let_it_be(:project_group_link) { create(:project_group_link, group: private_group, project: public_project) } - before do - private_group.add_owner(user) - sign_in(user) - end + shared_examples 'it shows warning popover' do + it 'shows warning popover', :js do + group_to_share_with.add_owner(user) + sign_in(user) + visit group_path(group_to_share_with) + + click_link _('Shared projects') + + wait_for_requests - it 'shows warning popover', :js do - visit group_path(private_group) + page.within("[data-testid=\"group-overview-item-#{public_project.id}\"]") do + click_button _('Less restrictive visibility') + end + + expect(page).to have_content _('Project visibility level is less restrictive than the group settings.') + end + end - click_link _('Shared projects') + context 'when a public project is shared with a private group' do + let_it_be(:group_to_share_with) { create(:group, :private) } + let_it_be(:project_group_link) do + create(:project_group_link, group: group_to_share_with, project: public_project) + end - wait_for_requests + include_examples 'it shows warning popover' + end - page.within("[data-testid=\"group-overview-item-#{public_project.id}\"]") do - click_button _('Less restrictive visibility') + context 'when a public project is shared with an internal group' do + let_it_be(:group_to_share_with) { create(:group, :internal) } + let_it_be(:project_group_link) do + create(:project_group_link, group: group_to_share_with, project: public_project) end - expect(page).to have_content _('Project visibility level is less restrictive than the group settings.') + include_examples 'it shows warning popover' end end diff --git a/spec/features/users/email_verification_on_login_spec.rb b/spec/features/users/email_verification_on_login_spec.rb index 0833f7f6f8e..c8301c2fc91 100644 --- a/spec/features/users/email_verification_on_login_spec.rb +++ b/spec/features/users/email_verification_on_login_spec.rb @@ -335,7 +335,7 @@ RSpec.describe 'Email Verification On Login', :clean_gitlab_redis_rate_limiting mail = find_email_for(user) expect(mail.to).to match_array([user.email]) expect(mail.subject).to eq('Verify your identity') - code = mail.body.parts.first.to_s[/\d{#{VerifiesWithEmail::TOKEN_LENGTH}}/] + code = mail.body.parts.first.to_s[/\d{#{VerifiesWithEmail::TOKEN_LENGTH}}/o] reset_delivered_emails! code end diff --git a/spec/frontend/groups/components/group_item_spec.js b/spec/frontend/groups/components/group_item_spec.js index 0bc80df6535..9906f62878f 100644 --- a/spec/frontend/groups/components/group_item_spec.js +++ b/spec/frontend/groups/components/group_item_spec.js @@ -6,19 +6,20 @@ import ItemActions from '~/groups/components/item_actions.vue'; import eventHub from '~/groups/event_hub'; import { getGroupItemMicrodata } from '~/groups/store/utils'; import * as urlUtilities from '~/lib/utils/url_utility'; +import { ITEM_TYPE } from '~/groups/constants'; import { - ITEM_TYPE, - VISIBILITY_INTERNAL, - VISIBILITY_PRIVATE, - VISIBILITY_PUBLIC, -} from '~/groups/constants'; -import { mountExtended } from 'helpers/vue_test_utils_helper'; + VISIBILITY_LEVEL_PRIVATE, + VISIBILITY_LEVEL_INTERNAL, + VISIBILITY_LEVEL_PUBLIC, +} from '~/visibility_level/constants'; +import { helpPagePath } from '~/helpers/help_page_helper'; +import { mountExtended, extendedWrapper } from 'helpers/vue_test_utils_helper'; import { mockParentGroupItem, mockChildren } from '../mock_data'; const createComponent = ( propsData = { group: mockParentGroupItem, parentGroup: mockChildren[0] }, provide = { - currentGroupVisibility: VISIBILITY_PRIVATE, + currentGroupVisibility: VISIBILITY_LEVEL_PRIVATE, }, ) => { return mountExtended(GroupItem, { @@ -289,7 +290,7 @@ describe('GroupItemComponent', () => { }); describe('visibility warning popover', () => { - const findPopover = () => wrapper.findComponent(GlPopover); + const findPopover = () => extendedWrapper(wrapper.findComponent(GlPopover)); const itDoesNotRenderVisibilityWarningPopover = () => { it('does not render visibility warning popover', () => { @@ -319,13 +320,16 @@ describe('GroupItemComponent', () => { describe('when showing projects', () => { describe.each` - itemVisibility | currentGroupVisibility | isPopoverShown - ${VISIBILITY_PRIVATE} | ${VISIBILITY_PUBLIC} | ${false} - ${VISIBILITY_INTERNAL} | ${VISIBILITY_PUBLIC} | ${false} - ${VISIBILITY_PUBLIC} | ${VISIBILITY_PUBLIC} | ${false} - ${VISIBILITY_PRIVATE} | ${VISIBILITY_PRIVATE} | ${false} - ${VISIBILITY_INTERNAL} | ${VISIBILITY_PRIVATE} | ${true} - ${VISIBILITY_PUBLIC} | ${VISIBILITY_PRIVATE} | ${true} + itemVisibility | currentGroupVisibility | isPopoverShown + ${VISIBILITY_LEVEL_PRIVATE} | ${VISIBILITY_LEVEL_PUBLIC} | ${false} + ${VISIBILITY_LEVEL_INTERNAL} | ${VISIBILITY_LEVEL_PUBLIC} | ${false} + ${VISIBILITY_LEVEL_PUBLIC} | ${VISIBILITY_LEVEL_PUBLIC} | ${false} + ${VISIBILITY_LEVEL_PRIVATE} | ${VISIBILITY_LEVEL_PRIVATE} | ${false} + ${VISIBILITY_LEVEL_INTERNAL} | ${VISIBILITY_LEVEL_PRIVATE} | ${true} + ${VISIBILITY_LEVEL_PUBLIC} | ${VISIBILITY_LEVEL_PRIVATE} | ${true} + ${VISIBILITY_LEVEL_PRIVATE} | ${VISIBILITY_LEVEL_INTERNAL} | ${false} + ${VISIBILITY_LEVEL_INTERNAL} | ${VISIBILITY_LEVEL_INTERNAL} | ${false} + ${VISIBILITY_LEVEL_PUBLIC} | ${VISIBILITY_LEVEL_INTERNAL} | ${true} `( 'when item visibility is $itemVisibility and parent group visibility is $currentGroupVisibility', ({ itemVisibility, currentGroupVisibility, isPopoverShown }) => { @@ -347,8 +351,17 @@ describe('GroupItemComponent', () => { }); if (isPopoverShown) { - it('renders visibility warning popover', () => { - expect(findPopover().exists()).toBe(true); + it('renders visibility warning popover with `Learn more` link', () => { + const popover = findPopover(); + + expect(popover.exists()).toBe(true); + expect( + popover.findByRole('link', { name: GroupItem.i18n.learnMore }).attributes('href'), + ).toBe( + helpPagePath('user/project/members/share_project_with_groups', { + anchor: 'sharing-projects-with-groups-of-a-higher-restrictive-visibility-level', + }), + ); }); } else { itDoesNotRenderVisibilityWarningPopover(); @@ -361,7 +374,7 @@ describe('GroupItemComponent', () => { wrapper = createComponent({ group: { ...mockParentGroupItem, - visibility: VISIBILITY_PUBLIC, + visibility: VISIBILITY_LEVEL_PUBLIC, type: ITEM_TYPE.PROJECT, }, parentGroup: mockChildren[0], diff --git a/spec/frontend/groups/components/groups_spec.js b/spec/frontend/groups/components/groups_spec.js index 48a2319cf96..6c1eb373b7e 100644 --- a/spec/frontend/groups/components/groups_spec.js +++ b/spec/frontend/groups/components/groups_spec.js @@ -6,7 +6,7 @@ import GroupItemComponent from '~/groups/components/group_item.vue'; import PaginationLinks from '~/vue_shared/components/pagination_links.vue'; import GroupsComponent from '~/groups/components/groups.vue'; import eventHub from '~/groups/event_hub'; -import { VISIBILITY_PRIVATE } from '~/groups/constants'; +import { VISIBILITY_LEVEL_PRIVATE } from '~/visibility_level/constants'; import { mockGroups, mockPageInfo } from '../mock_data'; describe('GroupsComponent', () => { @@ -26,7 +26,7 @@ describe('GroupsComponent', () => { ...propsData, }, provide: { - currentGroupVisibility: VISIBILITY_PRIVATE, + currentGroupVisibility: VISIBILITY_LEVEL_PRIVATE, }, }); }; diff --git a/spec/lib/gitlab/ci/parsers/sbom/cyclonedx_spec.rb b/spec/lib/gitlab/ci/parsers/sbom/cyclonedx_spec.rb index 59a7a03acea..c58e11063b8 100644 --- a/spec/lib/gitlab/ci/parsers/sbom/cyclonedx_spec.rb +++ b/spec/lib/gitlab/ci/parsers/sbom/cyclonedx_spec.rb @@ -4,7 +4,10 @@ require 'spec_helper' RSpec.describe Gitlab::Ci::Parsers::Sbom::Cyclonedx do let(:report) { instance_double('Gitlab::Ci::Reports::Sbom::Report') } + let(:report_data) { base_report_data } let(:raw_report_data) { report_data.to_json } + let(:report_valid?) { true } + let(:validator_errors) { [] } let(:base_report_data) do { @@ -16,6 +19,13 @@ RSpec.describe Gitlab::Ci::Parsers::Sbom::Cyclonedx do subject(:parse!) { described_class.new(raw_report_data, report).parse! } + before do + allow_next_instance_of(Gitlab::Ci::Parsers::Sbom::Validators::CyclonedxSchemaValidator) do |validator| + allow(validator).to receive(:valid?).and_return(report_valid?) + allow(validator).to receive(:errors).and_return(validator_errors) + end + end + context 'when report JSON is invalid' do let(:raw_report_data) { '{ ' } @@ -36,9 +46,19 @@ RSpec.describe Gitlab::Ci::Parsers::Sbom::Cyclonedx do end end - context 'when cyclonedx report has no components' do - let(:report_data) { base_report_data } + context 'when report does not conform to the CycloneDX schema' do + let(:report_valid?) { false } + let(:validator_errors) { %w[error1 error2] } + + it 'reports all errors returned by the validator' do + expect(report).to receive(:add_error).with("error1") + expect(report).to receive(:add_error).with("error2") + parse! + end + end + + context 'when cyclonedx report has no components' do it 'skips component processing' do expect(report).not_to receive(:add_component) diff --git a/spec/lib/gitlab/ci/parsers/sbom/validators/cyclonedx_schema_validator_spec.rb b/spec/lib/gitlab/ci/parsers/sbom/validators/cyclonedx_schema_validator_spec.rb new file mode 100644 index 00000000000..c54a3268bbe --- /dev/null +++ b/spec/lib/gitlab/ci/parsers/sbom/validators/cyclonedx_schema_validator_spec.rb @@ -0,0 +1,132 @@ +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe Gitlab::Ci::Parsers::Sbom::Validators::CyclonedxSchemaValidator do + # Reports should be valid or invalid according to the specification at + # https://cyclonedx.org/docs/1.4/json/ + + subject(:validator) { described_class.new(report_data) } + + let_it_be(:required_attributes) do + { + "bomFormat" => "CycloneDX", + "specVersion" => "1.4", + "version" => 1 + } + end + + context "with minimally valid report" do + let_it_be(:report_data) { required_attributes } + + it { is_expected.to be_valid } + end + + context "when report has components" do + let(:report_data) { required_attributes.merge({ "components" => components }) } + + context "with minimally valid components" do + let(:components) do + [ + { + "type" => "library", + "name" => "activesupport" + }, + { + "type" => "library", + "name" => "byebug" + } + ] + end + + it { is_expected.to be_valid } + end + + context "when components have versions" do + let(:components) do + [ + { + "type" => "library", + "name" => "activesupport", + "version" => "5.1.4" + }, + { + "type" => "library", + "name" => "byebug", + "version" => "10.0.0" + } + ] + end + + it { is_expected.to be_valid } + end + + context "when components are not valid" do + let(:components) do + [ + { "type" => "foo" }, + { "name" => "activesupport" } + ] + end + + it { is_expected.not_to be_valid } + + it "outputs errors for each validation failure" do + expect(validator.errors).to match_array([ + "property '/components/0' is missing required keys: name", + "property '/components/0/type' is not one of: [\"application\", \"framework\"," \ + " \"library\", \"container\", \"operating-system\", \"device\", \"firmware\", \"file\"]", + "property '/components/1' is missing required keys: type" + ]) + end + end + end + + context "when report has metadata" do + let(:metadata) do + { + "timestamp" => "2022-02-23T08:02:39Z", + "tools" => [{ "vendor" => "GitLab", "name" => "Gemnasium", "version" => "2.34.0" }], + "authors" => [{ "name" => "GitLab", "email" => "support@gitlab.com" }] + } + end + + let(:report_data) { required_attributes.merge({ "metadata" => metadata }) } + + it { is_expected.to be_valid } + + context "when metadata has properties" do + before do + metadata.merge!({ "properties" => properties }) + end + + context "when properties are valid" do + let(:properties) do + [ + { "name" => "gitlab:dependency_scanning:input_file", "value" => "Gemfile.lock" }, + { "name" => "gitlab:dependency_scanning:package_manager", "value" => "bundler" } + ] + end + + it { is_expected.to be_valid } + end + + context "when properties are invalid" do + let(:properties) do + [ + { "name" => ["gitlab:meta:schema_version"], "value" => 1 } + ] + end + + it { is_expected.not_to be_valid } + + it "outputs errors for each validation failure" do + expect(validator.errors).to match_array([ + "property '/metadata/properties/0/name' is not of type: string", + "property '/metadata/properties/0/value' is not of type: string" + ]) + end + end + end + end +end diff --git a/spec/lib/gitlab/global_id/deprecations_spec.rb b/spec/lib/gitlab/global_id/deprecations_spec.rb index 2c58c7ff15d..3824473c95b 100644 --- a/spec/lib/gitlab/global_id/deprecations_spec.rb +++ b/spec/lib/gitlab/global_id/deprecations_spec.rb @@ -1,26 +1,19 @@ # frozen_string_literal: true require 'fast_spec_helper' -require 'test_prof/recipes/rspec/let_it_be' require 'graphql' require_relative '../../../../app/graphql/types/base_scalar' require_relative '../../../../app/graphql/types/global_id_type' require_relative '../../../support/helpers/global_id_deprecation_helpers' -TestProf::BeforeAll.adapter = Class.new do - def begin_transaction; end - - def rollback_transaction; end -end.new - RSpec.describe Gitlab::GlobalId::Deprecations do include GlobalIDDeprecationHelpers - let_it_be(:deprecation_1) do + let(:deprecation_1) do described_class::NameDeprecation.new(old_name: 'Foo::Model', new_name: 'Bar', milestone: '9.0') end - let_it_be(:deprecation_2) do + let(:deprecation_2) do described_class::NameDeprecation.new(old_name: 'Baz', new_name: 'Qux::Model', milestone: '10.0') end diff --git a/spec/models/concerns/token_authenticatable_spec.rb b/spec/models/concerns/token_authenticatable_spec.rb index a2ce02f4661..675315cfa5a 100644 --- a/spec/models/concerns/token_authenticatable_spec.rb +++ b/spec/models/concerns/token_authenticatable_spec.rb @@ -442,7 +442,7 @@ RSpec.shared_examples 'prefixed token rotation' do context 'token is not set' do it 'generates a new token' do - expect(subject).to match(/^#{RunnersTokenPrefixable::RUNNERS_TOKEN_PREFIX}/) + expect(subject).to match(/^#{RunnersTokenPrefixable::RUNNERS_TOKEN_PREFIX}/o) expect(instance).not_to be_persisted end end @@ -453,7 +453,7 @@ RSpec.shared_examples 'prefixed token rotation' do end it 'generates a new token' do - expect(subject).to match(/^#{RunnersTokenPrefixable::RUNNERS_TOKEN_PREFIX}/) + expect(subject).to match(/^#{RunnersTokenPrefixable::RUNNERS_TOKEN_PREFIX}/o) expect(instance).not_to be_persisted end end @@ -475,7 +475,7 @@ RSpec.shared_examples 'prefixed token rotation' do context 'token is not set' do it 'generates a new token' do - expect(subject).to match(/^#{RunnersTokenPrefixable::RUNNERS_TOKEN_PREFIX}/) + expect(subject).to match(/^#{RunnersTokenPrefixable::RUNNERS_TOKEN_PREFIX}/o) expect(instance).to be_persisted end end @@ -486,7 +486,7 @@ RSpec.shared_examples 'prefixed token rotation' do end it 'generates a new token' do - expect(subject).to match(/^#{RunnersTokenPrefixable::RUNNERS_TOKEN_PREFIX}/) + expect(subject).to match(/^#{RunnersTokenPrefixable::RUNNERS_TOKEN_PREFIX}/o) expect(instance).to be_persisted end end diff --git a/spec/services/notes/copy_service_spec.rb b/spec/services/notes/copy_service_spec.rb index fd8802e6640..ea47087b88f 100644 --- a/spec/services/notes/copy_service_spec.rb +++ b/spec/services/notes/copy_service_spec.rb @@ -146,8 +146,8 @@ RSpec.describe Notes::CopyService do new_note = to_noteable.notes.first aggregate_failures do - expect(note.note).to match(/Simple text with image: #{FileUploader::MARKDOWN_PATTERN}/) - expect(new_note.note).to match(/Simple text with image: #{FileUploader::MARKDOWN_PATTERN}/) + expect(note.note).to match(/Simple text with image: #{FileUploader::MARKDOWN_PATTERN}/o) + expect(new_note.note).to match(/Simple text with image: #{FileUploader::MARKDOWN_PATTERN}/o) expect(note.note).not_to eq(new_note.note) expect(note.note_html).not_to eq(new_note.note_html) end |