From 65de487500295d4093cd53d392ea98980f070d57 Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Thu, 25 Aug 2022 03:10:55 +0000 Subject: [PATCH] Add latest changes from gitlab-org/gitlab@master --- .gitlab/ci/review.gitlab-ci.yml | 5 +-- .../style/percent_literal_delimiters.yml | 1 - .../boards/components/board_card_inner.vue | 3 ++ .../javascripts/google_tag_manager/index.js | 8 +++++ .../jobs/components/filtered_search/utils.js | 8 +++-- .../stylesheets/page_bundles/boards.scss | 6 ++-- .../impersonation_access_token_entity.rb | 11 ++++++ .../impersonation_access_token_serializer.rb | 7 ++++ ...1_add_namespace_id_to_broadcast_message.rb | 9 +++++ ...ex_and_foreign_key_to_broadcast_message.rb | 17 ++++++++++ db/schema_migrations/20220822102651 | 1 + db/schema_migrations/20220822103638 | 1 + db/structure.sql | 8 ++++- doc/user/group/access_and_permissions.md | 28 ++++++++++++--- doc/user/group/manage.md | 8 ++--- lib/gitlab/ci/parsers/sbom/cyclonedx.rb | 14 +++++--- .../sbom/source/dependency_scanning.rb | 10 +++--- lib/gitlab/ci/reports/sbom/component.rb | 8 ++--- lib/gitlab/ci/reports/sbom/report.rb | 4 +-- lib/gitlab/ci/reports/sbom/source.rb | 8 ++--- spec/factories/ci/reports/sbom/components.rb | 19 +++++++++++ spec/factories/ci/reports/sbom/sources.rb | 34 +++++++++++++++++++ .../frontend/google_tag_manager/index_spec.js | 29 ++++++++++++++++ .../components/filtered_search/utils_spec.js | 1 + .../gitlab/ci/parsers/sbom/cyclonedx_spec.rb | 6 ++-- .../sbom/source/dependency_scanning_spec.rb | 10 +++--- .../gitlab/ci/reports/sbom/component_spec.rb | 14 ++++---- .../lib/gitlab/ci/reports/sbom/report_spec.rb | 26 +++----------- .../lib/gitlab/ci/reports/sbom/source_spec.rb | 14 ++++---- .../impersonation_access_token_entity_spec.rb | 26 ++++++++++++++ ...ersonation_access_token_serializer_spec.rb | 20 +++++++++++ 31 files changed, 283 insertions(+), 81 deletions(-) create mode 100644 app/serializers/impersonation_access_token_entity.rb create mode 100644 app/serializers/impersonation_access_token_serializer.rb create mode 100644 db/migrate/20220822102651_add_namespace_id_to_broadcast_message.rb create mode 100644 db/migrate/20220822103638_add_index_and_foreign_key_to_broadcast_message.rb create mode 100644 db/schema_migrations/20220822102651 create mode 100644 db/schema_migrations/20220822103638 create mode 100644 spec/factories/ci/reports/sbom/components.rb create mode 100644 spec/factories/ci/reports/sbom/sources.rb create mode 100644 spec/serializers/impersonation_access_token_entity_spec.rb create mode 100644 spec/serializers/impersonation_access_token_serializer_spec.rb diff --git a/.gitlab/ci/review.gitlab-ci.yml b/.gitlab/ci/review.gitlab-ci.yml index 4f51409d6a8..56725b95fe0 100644 --- a/.gitlab/ci/review.gitlab-ci.yml +++ b/.gitlab/ci/review.gitlab-ci.yml @@ -23,7 +23,7 @@ review-cleanup: - ruby -rrubygems scripts/review_apps/automated_cleanup.rb - gcp_cleanup -review-app-pipeline-generate: +.review-app-pipeline-generate: image: ${GITLAB_DEPENDENCY_PROXY}ruby:${RUBY_VERSION} stage: prepare extends: @@ -52,7 +52,8 @@ review-app-pipeline-generate: exit $exit_code fi -start-review-app-pipeline: +# Temporarily disable review-apps due to https://gitlab.com/gitlab-org/gitlab/-/issues/371809 +.start-review-app-pipeline: extends: - .review:rules:start-review-app-pipeline resource_group: review/${CI_COMMIT_REF_SLUG}${SCHEDULE_TYPE} # CI_ENVIRONMENT_SLUG is not available here and we want this to be the same as the environment diff --git a/.rubocop_todo/style/percent_literal_delimiters.yml b/.rubocop_todo/style/percent_literal_delimiters.yml index c75b5ef325f..9989ae3f8b3 100644 --- a/.rubocop_todo/style/percent_literal_delimiters.yml +++ b/.rubocop_todo/style/percent_literal_delimiters.yml @@ -254,7 +254,6 @@ Style/PercentLiteralDelimiters: - 'ee/app/mailers/previews/license_mailer_preview.rb' - 'ee/app/models/app_sec/fuzzing/api/scan_profile.rb' - 'ee/app/models/app_sec/fuzzing/coverage/corpus.rb' - - 'ee/app/models/concerns/ee/approvable.rb' - 'ee/app/models/concerns/ee/issue_available_features.rb' - 'ee/app/models/ee/audit_event.rb' - 'ee/app/models/ee/description_version.rb' diff --git a/app/assets/javascripts/boards/components/board_card_inner.vue b/app/assets/javascripts/boards/components/board_card_inner.vue index f7e881defb7..098d429a62a 100644 --- a/app/assets/javascripts/boards/components/board_card_inner.vue +++ b/app/assets/javascripts/boards/components/board_card_inner.vue @@ -38,6 +38,8 @@ export default { GlSprintf, BoardCardMoveToPosition, WorkItemTypeIcon, + IssueHealthStatus: () => + import('ee_component/related_items_tree/components/issue_health_status.vue'), }, directives: { GlTooltip: GlTooltipDirective, @@ -381,6 +383,7 @@ export default { :weight="item.weight" @click="filterByWeight(item.weight)" /> + diff --git a/app/assets/javascripts/google_tag_manager/index.js b/app/assets/javascripts/google_tag_manager/index.js index c8204f397ff..ca5a1b29b6d 100644 --- a/app/assets/javascripts/google_tag_manager/index.js +++ b/app/assets/javascripts/google_tag_manager/index.js @@ -290,3 +290,11 @@ export const trackCombinedGroupProjectForm = () => { pushEvent('combinedGroupProjectFormSubmit'); }); }; + +export const trackCompanyForm = (aboutYourCompanyType) => { + if (!isSupported()) { + return; + } + + pushEvent('aboutYourCompanyFormSubmit', { aboutYourCompanyType }); +}; diff --git a/app/assets/javascripts/jobs/components/filtered_search/utils.js b/app/assets/javascripts/jobs/components/filtered_search/utils.js index eef5b738863..696cd8d4706 100644 --- a/app/assets/javascripts/jobs/components/filtered_search/utils.js +++ b/app/assets/javascripts/jobs/components/filtered_search/utils.js @@ -10,10 +10,14 @@ export const validateQueryString = (queryStringObj) => { const filters = Object.keys(queryStringObj); if (filters.includes('statuses')) { - const found = jobStatusValues.find((status) => status === queryStringObj.statuses); + const queryStringStatus = { + statuses: queryStringObj.statuses.toUpperCase(), + }; + + const found = jobStatusValues.find((status) => status === queryStringStatus.statuses); if (found) { - return queryStringObj; + return queryStringStatus; } return null; diff --git a/app/assets/stylesheets/page_bundles/boards.scss b/app/assets/stylesheets/page_bundles/boards.scss index 2b55a87f04a..d45bc865da5 100644 --- a/app/assets/stylesheets/page_bundles/boards.scss +++ b/app/assets/stylesheets/page_bundles/boards.scss @@ -182,10 +182,8 @@ } .board-card-number { - font-size: $gl-font-size-xs; - - @include media-breakpoint-up(md) { - font-size: $label-font-size; + @include media-breakpoint-down(md) { + font-size: $gl-font-size-sm; } } diff --git a/app/serializers/impersonation_access_token_entity.rb b/app/serializers/impersonation_access_token_entity.rb new file mode 100644 index 00000000000..9c59ed58bd8 --- /dev/null +++ b/app/serializers/impersonation_access_token_entity.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +# rubocop: disable Gitlab/NamespacedClass +class ImpersonationAccessTokenEntity < API::Entities::PersonalAccessToken + include Gitlab::Routing + + expose :revoke_path do |token, _options| + revoke_admin_user_impersonation_token_path(token.user, token) + end +end +# rubocop: enable Gitlab/NamespacedClass diff --git a/app/serializers/impersonation_access_token_serializer.rb b/app/serializers/impersonation_access_token_serializer.rb new file mode 100644 index 00000000000..d3ea5ceb305 --- /dev/null +++ b/app/serializers/impersonation_access_token_serializer.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +# rubocop: disable Gitlab/NamespacedClass +class ImpersonationAccessTokenSerializer < BaseSerializer + entity ImpersonationAccessTokenEntity +end +# rubocop: enable Gitlab/NamespacedClass diff --git a/db/migrate/20220822102651_add_namespace_id_to_broadcast_message.rb b/db/migrate/20220822102651_add_namespace_id_to_broadcast_message.rb new file mode 100644 index 00000000000..5413f447366 --- /dev/null +++ b/db/migrate/20220822102651_add_namespace_id_to_broadcast_message.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class AddNamespaceIdToBroadcastMessage < Gitlab::Database::Migration[2.0] + enable_lock_retries! + + def change + add_column :broadcast_messages, :namespace_id, :bigint + end +end diff --git a/db/migrate/20220822103638_add_index_and_foreign_key_to_broadcast_message.rb b/db/migrate/20220822103638_add_index_and_foreign_key_to_broadcast_message.rb new file mode 100644 index 00000000000..a577e5ad157 --- /dev/null +++ b/db/migrate/20220822103638_add_index_and_foreign_key_to_broadcast_message.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +class AddIndexAndForeignKeyToBroadcastMessage < Gitlab::Database::Migration[2.0] + disable_ddl_transaction! + + INDEX_NAME = 'index_broadcast_messages_on_namespace_id' + + def up + add_concurrent_index :broadcast_messages, :namespace_id, name: INDEX_NAME + add_concurrent_foreign_key :broadcast_messages, :namespaces, column: :namespace_id, on_delete: :cascade + end + + def down + remove_foreign_key_if_exists :broadcast_messages, column: :namespace_id + remove_concurrent_index_by_name :broadcast_messages, name: INDEX_NAME + end +end diff --git a/db/schema_migrations/20220822102651 b/db/schema_migrations/20220822102651 new file mode 100644 index 00000000000..851535d2924 --- /dev/null +++ b/db/schema_migrations/20220822102651 @@ -0,0 +1 @@ +2bf5f851ee8919f2306a36ae299cd3c30943d5cc3356981bab2091ff104ef127 \ No newline at end of file diff --git a/db/schema_migrations/20220822103638 b/db/schema_migrations/20220822103638 new file mode 100644 index 00000000000..5633f697b1b --- /dev/null +++ b/db/schema_migrations/20220822103638 @@ -0,0 +1 @@ +9aee5b0e3475736170d7169fd3c8ac9933d976ee69a2769dea29ee4bc553af27 \ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index a8093bf3ceb..7d3336cbe5c 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -12286,7 +12286,8 @@ CREATE TABLE broadcast_messages ( broadcast_type smallint DEFAULT 1 NOT NULL, dismissable boolean, target_access_levels integer[] DEFAULT '{}'::integer[] NOT NULL, - theme smallint DEFAULT 0 NOT NULL + theme smallint DEFAULT 0 NOT NULL, + namespace_id bigint ); CREATE SEQUENCE broadcast_messages_id_seq @@ -27776,6 +27777,8 @@ CREATE INDEX index_boards_on_project_id ON boards USING btree (project_id); CREATE INDEX index_broadcast_message_on_ends_at_and_broadcast_type_and_id ON broadcast_messages USING btree (ends_at, broadcast_type, id); +CREATE INDEX index_broadcast_messages_on_namespace_id ON broadcast_messages USING btree (namespace_id); + CREATE INDEX index_btree_namespaces_traversal_ids ON namespaces USING btree (traversal_ids); CREATE INDEX index_bulk_import_configurations_on_bulk_import_id ON bulk_import_configurations USING btree (bulk_import_id); @@ -32456,6 +32459,9 @@ ALTER TABLE ONLY vulnerabilities ALTER TABLE ONLY issue_customer_relations_contacts ADD CONSTRAINT fk_7b92f835bb FOREIGN KEY (contact_id) REFERENCES customer_relations_contacts(id) ON DELETE CASCADE; +ALTER TABLE ONLY broadcast_messages + ADD CONSTRAINT fk_7bf2ec43da FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE; + ALTER TABLE ONLY vulnerabilities ADD CONSTRAINT fk_7c5bb22a22 FOREIGN KEY (due_date_sourcing_milestone_id) REFERENCES milestones(id) ON DELETE SET NULL; diff --git a/doc/user/group/access_and_permissions.md b/doc/user/group/access_and_permissions.md index d14ccefa4e2..4e4b338d661 100644 --- a/doc/user/group/access_and_permissions.md +++ b/doc/user/group/access_and_permissions.md @@ -30,6 +30,26 @@ The group's new subgroups have push rules set for them based on either: - The closest parent group with push rules defined. - Push rules set at the instance level, if no parent groups have push rules defined. +## Restrict Git access protocols + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/365601) in GitLab 15.1 [with a flag](../../administration/feature_flags.md) named `group_level_git_protocol_control`. Disabled by default. + +FLAG: +On self-managed GitLab, by default this feature is not available. To make it available, ask an administrator to +[enable the feature flag](../../administration/feature_flags.md) named `group_level_git_protocol_control`. On GitLab.com, +this feature is available. + +You can set the permitted protocols used to access a group's repositories to either SSH, HTTPS, or both. This setting +is disabled when the [instance setting](../admin_area/settings/visibility_and_access_controls.md#configure-enabled-git-access-protocols) is +configured by an administrator. + +To change the permitted Git access protocols for a group: + +1. Go to the group's **Settings > General** page. +1. Expand the **Permissions and group features** section. +1. Choose the permitted protocols from **Enabled Git access protocols**. +1. Select **Save changes**. + ## Restrict group access by IP address **(PREMIUM)** > - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/1985) in GitLab 12.0. @@ -67,7 +87,7 @@ To restrict group access by IP address: 1. Go to the group's **Settings > General** page. 1. Expand the **Permissions and group features** section. -1. In the **Allow access to the following IP addresses** field, enter IPv4 or IPv6 address ranges in CIDR notation. +1. In the **Restrict access by IP address** field, enter IPv4 or IPv6 address ranges in CIDR notation. 1. Select **Save changes**. In self-managed installations of GitLab 15.1 and later, you can also configure @@ -130,7 +150,7 @@ To prevent sharing outside of the group's hierarchy: 1. On the top bar, select **Menu > Groups** and find your group. 1. On the left sidebar, select **Settings > General**. 1. Expand **Permissions and group features**. -1. Select **Prevent members from sending invitations to groups outside of `` and its subgroups**. +1. Select **Members cannot invite groups outside of `` and its subgroups**. 1. Select **Save changes**. ## Prevent a project from being shared with groups @@ -143,7 +163,7 @@ To prevent a project from being shared with other groups: 1. Go to the group's **Settings > General** page. 1. Expand the **Permissions and group features** section. -1. Select **Prevent sharing a project in `` with other groups**. +1. Select **Projects in `` cannot be shared with other groups**. 1. Select **Save changes**. This setting applies to all subgroups unless overridden by a group owner. Groups already @@ -199,7 +219,7 @@ To prevent members from being added to projects in a group: 1. Go to the group's **Settings > General** page. 1. Expand the **Permissions and group features** section. -1. Under **Membership**, select **Prevent adding new members to projects within this group**. +1. Under **Membership**, select **Users cannot be added to projects in this group**. 1. Select **Save changes**. All users who previously had permissions can no longer add members to a group. diff --git a/doc/user/group/manage.md b/doc/user/group/manage.md index a9cc6cc8432..45f96d8e18b 100644 --- a/doc/user/group/manage.md +++ b/doc/user/group/manage.md @@ -212,7 +212,7 @@ To change this setting for a specific group: 1. Find the group and select it. 1. From the left menu, select **Settings > General**. 1. Expand the **Permissions and group features** section. -1. Select the desired option in the **Allowed to create projects** dropdown list. +1. Select the desired option in the **Roles allowed to create projects** dropdown list. 1. Select **Save changes**. To change this setting globally, see [Default project creation protection](../admin_area/settings/visibility_and_access_controls.md#define-which-roles-can-create-projects). @@ -342,7 +342,7 @@ To transfer a group: > - [User interface changed](https://gitlab.com/gitlab-org/gitlab/-/issues/352961) in GitLab 15.1. [Delayed project deletion](../project/settings/index.md#delayed-project-deletion) is locked and disabled unless the instance-level settings for -[deletion protection](../admin_area/settings/visibility_and_access_controls.md#deletion-protection) is enabled for either groups only or groups and projects. +[deletion protection](../admin_area/settings/visibility_and_access_controls.md#deletion-protection) are enabled for either groups only or groups and projects. When enabled on groups, projects in the group are deleted after a period of delay. During this period, projects are in a read-only state and can be restored. The default period is seven days but [is configurable at the instance level](../admin_area/settings/visibility_and_access_controls.md#retention-period). @@ -379,7 +379,7 @@ To disable email notifications: 1. Go to the group's **Settings > General** page. 1. Expand the **Permissions and group features** section. -1. Select **Disable email notifications**. +1. Select **Email notifications are disabled**. 1. Select **Save changes**. ## Disable group mentions @@ -398,7 +398,7 @@ To disable group mentions: 1. Go to the group's **Settings > General** page. 1. Expand the **Permissions and group features** section. -1. Select **Disable group mentions**. +1. Select **Group mentions are disabled**. 1. Select **Save changes**. ## Export members as CSV **(PREMIUM)** diff --git a/lib/gitlab/ci/parsers/sbom/cyclonedx.rb b/lib/gitlab/ci/parsers/sbom/cyclonedx.rb index deb20a2138c..aa594ca4049 100644 --- a/lib/gitlab/ci/parsers/sbom/cyclonedx.rb +++ b/lib/gitlab/ci/parsers/sbom/cyclonedx.rb @@ -6,7 +6,6 @@ module Gitlab module Sbom class Cyclonedx SUPPORTED_SPEC_VERSIONS = %w[1.4].freeze - COMPONENT_ATTRIBUTES = %w[type name version].freeze def parse!(blob, sbom_report) @report = sbom_report @@ -62,10 +61,17 @@ module Gitlab end def parse_components - data['components']&.each do |component| - next unless supported_component_type?(component['type']) + data['components']&.each do |component_data| + type = component_data['type'] + next unless supported_component_type?(type) - report.add_component(component.slice(*COMPONENT_ATTRIBUTES)) + component = ::Gitlab::Ci::Reports::Sbom::Component.new( + type: type, + name: component_data['name'], + version: component_data['version'] + ) + + report.add_component(component) end end diff --git a/lib/gitlab/ci/parsers/sbom/source/dependency_scanning.rb b/lib/gitlab/ci/parsers/sbom/source/dependency_scanning.rb index ad04b3257f9..00ca723b258 100644 --- a/lib/gitlab/ci/parsers/sbom/source/dependency_scanning.rb +++ b/lib/gitlab/ci/parsers/sbom/source/dependency_scanning.rb @@ -21,11 +21,11 @@ module Gitlab def source return unless required_attributes_present? - { - 'type' => :dependency_scanning, - 'data' => data, - 'fingerprint' => fingerprint - } + ::Gitlab::Ci::Reports::Sbom::Source.new( + type: :dependency_scanning, + data: data, + fingerprint: fingerprint + ) end private diff --git a/lib/gitlab/ci/reports/sbom/component.rb b/lib/gitlab/ci/reports/sbom/component.rb index 86b9be274cc..198b34451b4 100644 --- a/lib/gitlab/ci/reports/sbom/component.rb +++ b/lib/gitlab/ci/reports/sbom/component.rb @@ -7,10 +7,10 @@ module Gitlab class Component attr_reader :component_type, :name, :version - def initialize(component = {}) - @component_type = component['type'] - @name = component['name'] - @version = component['version'] + def initialize(type:, name:, version:) + @component_type = type + @name = name + @version = version end end end diff --git a/lib/gitlab/ci/reports/sbom/report.rb b/lib/gitlab/ci/reports/sbom/report.rb index dc6b3153e51..4f84d12f78c 100644 --- a/lib/gitlab/ci/reports/sbom/report.rb +++ b/lib/gitlab/ci/reports/sbom/report.rb @@ -17,11 +17,11 @@ module Gitlab end def set_source(source) - self.source = Source.new(source) + self.source = source end def add_component(component) - components << Component.new(component) + components << component end private diff --git a/lib/gitlab/ci/reports/sbom/source.rb b/lib/gitlab/ci/reports/sbom/source.rb index 60bf30b65a5..ea0fb8d4fbb 100644 --- a/lib/gitlab/ci/reports/sbom/source.rb +++ b/lib/gitlab/ci/reports/sbom/source.rb @@ -7,10 +7,10 @@ module Gitlab class Source attr_reader :source_type, :data, :fingerprint - def initialize(source = {}) - @source_type = source['type'] - @data = source['data'] - @fingerprint = source['fingerprint'] + def initialize(type:, data:, fingerprint:) + @source_type = type + @data = data + @fingerprint = fingerprint end end end diff --git a/spec/factories/ci/reports/sbom/components.rb b/spec/factories/ci/reports/sbom/components.rb new file mode 100644 index 00000000000..317e1c863cf --- /dev/null +++ b/spec/factories/ci/reports/sbom/components.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :ci_reports_sbom_component, class: '::Gitlab::Ci::Reports::Sbom::Component' do + type { :library } + sequence(:name) { |n| "component-#{n}" } + sequence(:version) { |n| "v0.0.#{n}" } + + skip_create + + initialize_with do + ::Gitlab::Ci::Reports::Sbom::Component.new( + type: type, + name: name, + version: version + ) + end + end +end diff --git a/spec/factories/ci/reports/sbom/sources.rb b/spec/factories/ci/reports/sbom/sources.rb new file mode 100644 index 00000000000..9093aba86a6 --- /dev/null +++ b/spec/factories/ci/reports/sbom/sources.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :ci_reports_sbom_source, class: '::Gitlab::Ci::Reports::Sbom::Source' do + type { :dependency_scanning } + + transient do + sequence(:input_file_path) { |n| "subproject-#{n}/package-lock.json" } + sequence(:source_file_path) { |n| "subproject-#{n}/package.json" } + end + + data do + { + 'category' => 'development', + 'input_file' => { 'path' => input_file_path }, + 'source_file' => { 'path' => source_file_path }, + 'package_manager' => { 'name' => 'npm' }, + 'language' => { 'name' => 'JavaScript' } + } + end + + fingerprint { Digest::SHA256.hexdigest(data.to_json) } + + skip_create + + initialize_with do + ::Gitlab::Ci::Reports::Sbom::Source.new( + type: type, + data: data, + fingerprint: fingerprint + ) + end + end +end diff --git a/spec/frontend/google_tag_manager/index_spec.js b/spec/frontend/google_tag_manager/index_spec.js index 6a7eb1fd9f1..9c4b23e3a70 100644 --- a/spec/frontend/google_tag_manager/index_spec.js +++ b/spec/frontend/google_tag_manager/index_spec.js @@ -15,6 +15,7 @@ import { trackTransaction, trackAddToCartUsageTab, getNamespaceId, + trackCompanyForm, } from '~/google_tag_manager'; import { setHTMLFixture, resetHTMLFixture } from 'helpers/fixtures'; import { logError } from '~/lib/logger'; @@ -440,6 +441,34 @@ describe('~/google_tag_manager/index', () => { }); }); }); + + describe('when trackCompanyForm is invoked', () => { + it('with an ultimate trial', () => { + expect(spy).not.toHaveBeenCalled(); + + trackCompanyForm('ultimate_trial'); + + expect(spy).toHaveBeenCalledTimes(1); + expect(spy).toHaveBeenCalledWith({ + event: 'aboutYourCompanyFormSubmit', + aboutYourCompanyType: 'ultimate_trial', + }); + expect(logError).not.toHaveBeenCalled(); + }); + + it('with a free account', () => { + expect(spy).not.toHaveBeenCalled(); + + trackCompanyForm('free_account'); + + expect(spy).toHaveBeenCalledTimes(1); + expect(spy).toHaveBeenCalledWith({ + event: 'aboutYourCompanyFormSubmit', + aboutYourCompanyType: 'free_account', + }); + expect(logError).not.toHaveBeenCalled(); + }); + }); }); describe.each([ diff --git a/spec/frontend/jobs/components/filtered_search/utils_spec.js b/spec/frontend/jobs/components/filtered_search/utils_spec.js index 8e9cd357a19..8440ab42b86 100644 --- a/spec/frontend/jobs/components/filtered_search/utils_spec.js +++ b/spec/frontend/jobs/components/filtered_search/utils_spec.js @@ -5,6 +5,7 @@ describe('Filtered search utils', () => { it.each` queryStringObject | expected ${{ statuses: 'SUCCESS' }} | ${{ statuses: 'SUCCESS' }} + ${{ statuses: 'failed' }} | ${{ statuses: 'FAILED' }} ${{ wrong: 'SUCCESS' }} | ${null} ${{ statuses: 'wrong' }} | ${null} ${{ wrong: 'wrong' }} | ${null} diff --git a/spec/lib/gitlab/ci/parsers/sbom/cyclonedx_spec.rb b/spec/lib/gitlab/ci/parsers/sbom/cyclonedx_spec.rb index 431fe9f3591..f3636106b98 100644 --- a/spec/lib/gitlab/ci/parsers/sbom/cyclonedx_spec.rb +++ b/spec/lib/gitlab/ci/parsers/sbom/cyclonedx_spec.rb @@ -102,11 +102,11 @@ RSpec.describe Gitlab::Ci::Parsers::Sbom::Cyclonedx do it 'adds each component, ignoring unused attributes' do expect(report).to receive(:add_component) - .with({ "name" => "activesupport", "version" => "5.1.4", "type" => "library" }) + .with(an_object_having_attributes(name: "activesupport", version: "5.1.4", component_type: "library")) expect(report).to receive(:add_component) - .with({ "name" => "byebug", "version" => "10.0.0", "type" => "library" }) + .with(an_object_having_attributes(name: "byebug", version: "10.0.0", component_type: "library")) expect(report).to receive(:add_component) - .with({ "name" => "minimal-component", "type" => "library" }) + .with(an_object_having_attributes(name: "minimal-component", version: nil, component_type: "library")) parse! end diff --git a/spec/lib/gitlab/ci/parsers/sbom/source/dependency_scanning_spec.rb b/spec/lib/gitlab/ci/parsers/sbom/source/dependency_scanning_spec.rb index 839fba488bd..7222ebc3cb8 100644 --- a/spec/lib/gitlab/ci/parsers/sbom/source/dependency_scanning_spec.rb +++ b/spec/lib/gitlab/ci/parsers/sbom/source/dependency_scanning_spec.rb @@ -17,11 +17,11 @@ RSpec.describe Gitlab::Ci::Parsers::Sbom::Source::DependencyScanning do end it 'returns expected source data' do - is_expected.to eq({ - 'type' => :dependency_scanning, - 'data' => property_data, - 'fingerprint' => '4dbcb747e6f0fb3ed4f48d96b777f1d64acdf43e459fdfefad404e55c004a188' - }) + is_expected.to have_attributes( + source_type: :dependency_scanning, + data: property_data, + fingerprint: '4dbcb747e6f0fb3ed4f48d96b777f1d64acdf43e459fdfefad404e55c004a188' + ) end end diff --git a/spec/lib/gitlab/ci/reports/sbom/component_spec.rb b/spec/lib/gitlab/ci/reports/sbom/component_spec.rb index 80cec30d3b0..06ea3433ef0 100644 --- a/spec/lib/gitlab/ci/reports/sbom/component_spec.rb +++ b/spec/lib/gitlab/ci/reports/sbom/component_spec.rb @@ -5,19 +5,19 @@ require 'fast_spec_helper' RSpec.describe Gitlab::Ci::Reports::Sbom::Component do let(:attributes) do { - 'type' => 'library', - 'name' => 'component-name', - 'version' => 'v0.0.1' + type: 'library', + name: 'component-name', + version: 'v0.0.1' } end - subject { described_class.new(attributes) } + subject { described_class.new(**attributes) } it 'has correct attributes' do expect(subject).to have_attributes( - component_type: 'library', - name: 'component-name', - version: 'v0.0.1' + component_type: attributes[:type], + name: attributes[:name], + version: attributes[:version] ) end end diff --git a/spec/lib/gitlab/ci/reports/sbom/report_spec.rb b/spec/lib/gitlab/ci/reports/sbom/report_spec.rb index d7a285ab13c..6ffa93e5fc8 100644 --- a/spec/lib/gitlab/ci/reports/sbom/report_spec.rb +++ b/spec/lib/gitlab/ci/reports/sbom/report_spec.rb @@ -15,40 +15,22 @@ RSpec.describe Gitlab::Ci::Reports::Sbom::Report do end describe '#set_source' do - let_it_be(:source) do - { - 'type' => :dependency_scanning, - 'data' => { - 'input_file' => { 'path' => 'package-lock.json' }, - 'source_file' => { 'path' => 'package.json' }, - 'package_manager' => { 'name' => 'npm' }, - 'language' => { 'name' => 'JavaScript' } - }, - 'fingerprint' => 'c01df1dc736c1148717e053edbde56cb3a55d3e31f87cea955945b6f67c17d42' - } - end + let_it_be(:source) { create(:ci_reports_sbom_source) } it 'stores the source' do report.set_source(source) - expect(report.source).to be_a(Gitlab::Ci::Reports::Sbom::Source) + expect(report.source).to eq(source) end end describe '#add_component' do - let_it_be(:components) do - [ - { 'type' => 'library', 'name' => 'component1', 'version' => 'v0.0.1' }, - { 'type' => 'library', 'name' => 'component2', 'version' => 'v0.0.2' }, - { 'type' => 'library', 'name' => 'component2' } - ] - end + let_it_be(:components) { create_list(:ci_reports_sbom_component, 3) } it 'appends components to a list' do components.each { |component| report.add_component(component) } - expect(report.components.size).to eq(3) - expect(report.components).to all(be_a(Gitlab::Ci::Reports::Sbom::Component)) + expect(report.components).to match_array(components) end end end diff --git a/spec/lib/gitlab/ci/reports/sbom/source_spec.rb b/spec/lib/gitlab/ci/reports/sbom/source_spec.rb index 656a92c0f0e..cb30bd721dd 100644 --- a/spec/lib/gitlab/ci/reports/sbom/source_spec.rb +++ b/spec/lib/gitlab/ci/reports/sbom/source_spec.rb @@ -5,25 +5,25 @@ require 'fast_spec_helper' RSpec.describe Gitlab::Ci::Reports::Sbom::Source do let(:attributes) do { - 'type' => :dependency_scanning, - 'data' => { + type: :dependency_scanning, + data: { 'category' => 'development', 'input_file' => { 'path' => 'package-lock.json' }, 'source_file' => { 'path' => 'package.json' }, 'package_manager' => { 'name' => 'npm' }, 'language' => { 'name' => 'JavaScript' } }, - 'fingerprint' => '4dbcb747e6f0fb3ed4f48d96b777f1d64acdf43e459fdfefad404e55c004a188' + fingerprint: '4dbcb747e6f0fb3ed4f48d96b777f1d64acdf43e459fdfefad404e55c004a188' } end - subject { described_class.new(attributes) } + subject { described_class.new(**attributes) } it 'has correct attributes' do expect(subject).to have_attributes( - source_type: attributes['type'], - data: attributes['data'], - fingerprint: attributes['fingerprint'] + source_type: attributes[:type], + data: attributes[:data], + fingerprint: attributes[:fingerprint] ) end end diff --git a/spec/serializers/impersonation_access_token_entity_spec.rb b/spec/serializers/impersonation_access_token_entity_spec.rb new file mode 100644 index 00000000000..e8517779c0d --- /dev/null +++ b/spec/serializers/impersonation_access_token_entity_spec.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true +require 'spec_helper' + +RSpec.describe ImpersonationAccessTokenEntity do + let_it_be(:user) { create(:user) } + let_it_be(:token) { create(:personal_access_token, :impersonation, user: user) } + + subject(:json) { described_class.new(token).as_json } + + it 'has the correct attributes' do + expected_revoke_path = Gitlab::Routing.url_helpers + .revoke_admin_user_impersonation_token_path( + { user_id: user, id: token }) + + expect(json).to( + include( + id: token.id, + name: token.name, + scopes: token.scopes, + user_id: token.user_id, + revoke_path: expected_revoke_path + )) + + expect(json).not_to include(:token) + end +end diff --git a/spec/serializers/impersonation_access_token_serializer_spec.rb b/spec/serializers/impersonation_access_token_serializer_spec.rb new file mode 100644 index 00000000000..0c8cebb94b1 --- /dev/null +++ b/spec/serializers/impersonation_access_token_serializer_spec.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true +require 'spec_helper' + +RSpec.describe ImpersonationAccessTokenSerializer do + subject(:serializer) { described_class.new } + + describe '#represent' do + it 'can render a single token' do + token = create(:personal_access_token) + + expect(serializer.represent(token)).to be_kind_of(Hash) + end + + it 'can render a collection of tokens' do + tokens = create_list(:personal_access_token, 2) + + expect(serializer.represent(tokens)).to be_kind_of(Array) + end + end +end