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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-09-20 14:18:08 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-09-20 14:18:08 +0300
commit5afcbe03ead9ada87621888a31a62652b10a7e4f (patch)
tree9918b67a0d0f0bafa6542e839a8be37adf73102d /spec/serializers
parentc97c0201564848c1f53226fe19d71fdcc472f7d0 (diff)
Add latest changes from gitlab-org/gitlab@16-4-stable-eev16.4.0-rc42
Diffstat (limited to 'spec/serializers')
-rw-r--r--spec/serializers/activity_pub/activity_streams_serializer_spec.rb157
-rw-r--r--spec/serializers/activity_pub/project_entity_spec.rb32
-rw-r--r--spec/serializers/activity_pub/release_entity_spec.rb48
-rw-r--r--spec/serializers/activity_pub/releases_actor_entity_spec.rb39
-rw-r--r--spec/serializers/activity_pub/releases_actor_serializer_spec.rb16
-rw-r--r--spec/serializers/activity_pub/releases_outbox_serializer_spec.rb34
-rw-r--r--spec/serializers/activity_pub/user_entity_spec.rb28
-rw-r--r--spec/serializers/admin/abuse_report_details_entity_spec.rb113
-rw-r--r--spec/serializers/admin/abuse_report_details_serializer_spec.rb5
-rw-r--r--spec/serializers/admin/abuse_report_entity_spec.rb15
-rw-r--r--spec/serializers/admin/reported_content_entity_spec.rb50
-rw-r--r--spec/serializers/build_details_entity_spec.rb16
-rw-r--r--spec/serializers/ci/job_annotation_entity_spec.rb30
-rw-r--r--spec/serializers/codequality_degradation_entity_spec.rb17
-rw-r--r--spec/serializers/codequality_reports_comparer_serializer_spec.rb4
-rw-r--r--spec/serializers/deployment_entity_spec.rb89
-rw-r--r--spec/serializers/import/github_realtime_repo_entity_spec.rb4
-rw-r--r--spec/serializers/import/github_realtime_repo_serializer_spec.rb2
-rw-r--r--spec/serializers/profile/event_entity_spec.rb11
19 files changed, 632 insertions, 78 deletions
diff --git a/spec/serializers/activity_pub/activity_streams_serializer_spec.rb b/spec/serializers/activity_pub/activity_streams_serializer_spec.rb
new file mode 100644
index 00000000000..c74beba7a81
--- /dev/null
+++ b/spec/serializers/activity_pub/activity_streams_serializer_spec.rb
@@ -0,0 +1,157 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ActivityPub::ActivityStreamsSerializer, feature_category: :integrations do
+ let(:implementer_class) do
+ Class.new(described_class) do
+ include WithPagination
+ end
+ end
+
+ let(:entity_class) do
+ Class.new(Grape::Entity) do
+ expose :id do |*|
+ 'https://example.com/unique/url'
+ end
+
+ expose :type do |*|
+ 'Person'
+ end
+
+ expose :name do |*|
+ 'Alice'
+ end
+ end
+ end
+
+ shared_examples_for 'ActivityStreams document' do
+ it 'belongs to the ActivityStreams namespace' do
+ expect(subject['@context']).to eq 'https://www.w3.org/ns/activitystreams'
+ end
+
+ it 'has a unique identifier' do
+ expect(subject).to have_key 'id'
+ end
+
+ it 'has a type' do
+ expect(subject).to have_key 'type'
+ end
+ end
+
+ before do
+ implementer_class.entity entity_class
+ end
+
+ context 'when the serializer is not paginated' do
+ let(:resource) { build_stubbed(:release) }
+ let(:outbox_url) { 'https://example.com/unique/url/outbox' }
+
+ context 'with a valid represented entity' do
+ subject { implementer_class.new.represent(resource, outbox: outbox_url) }
+
+ it_behaves_like 'ActivityStreams document'
+
+ it 'exposes an outbox' do
+ expect(subject['outbox']).to eq 'https://example.com/unique/url/outbox'
+ end
+
+ it 'includes serialized data' do
+ expect(subject['name']).to eq 'Alice'
+ end
+ end
+
+ context 'when the represented entity provides no identifier' do
+ subject { implementer_class.new.represent(resource, outbox: outbox_url) }
+
+ before do
+ allow(entity_class).to receive(:represent).and_return({ type: 'Person' })
+ end
+
+ it 'raises an exception' do
+ expect { subject }.to raise_error(ActivityPub::ActivityStreamsSerializer::MissingIdentifierError)
+ end
+ end
+
+ context 'when the represented entity provides no type' do
+ subject { implementer_class.new.represent(resource, outbox: outbox_url) }
+
+ before do
+ allow(entity_class).to receive(:represent).and_return({ id: 'https://example.com/unique/url' })
+ end
+
+ it 'raises an exception' do
+ expect { subject }.to raise_error(ActivityPub::ActivityStreamsSerializer::MissingTypeError)
+ end
+ end
+
+ context 'when the caller provides no outbox parameter' do
+ subject { implementer_class.new.represent(resource) }
+
+ it 'raises an exception' do
+ expect { subject }.to raise_error(ActivityPub::ActivityStreamsSerializer::MissingOutboxError)
+ end
+ end
+ end
+
+ context 'when the serializer is paginated' do
+ let(:resources) { build_stubbed_list(:release, 3) }
+ let(:request) { ActionDispatch::Request.new(request_data) }
+ let(:response) { ActionDispatch::Response.new }
+ let(:url) { 'https://example.com/resource/url' }
+ let(:decorated) { implementer_class.new.with_pagination(request, response) }
+
+ before do
+ allow(resources).to receive(:page).and_return(resources)
+ allow(resources).to receive(:per).and_return(resources)
+ allow(resources).to receive(:current_page).and_return(2)
+ allow(resources).to receive(:total_pages).and_return(3)
+ allow(resources).to receive(:total_count).and_return(10)
+ allow(decorated.paginator).to receive(:paginate).and_return(resources)
+ end
+
+ context 'when no page parameter is provided' do
+ subject { decorated.represent(resources) }
+
+ let(:request_data) do
+ { "rack.url_scheme" => "https", "HTTP_HOST" => "example.com", "PATH_INFO" => '/resource/url' }
+ end
+
+ it_behaves_like 'ActivityStreams document'
+
+ it 'is an index document for the pagination' do
+ expect(subject['type']).to eq 'OrderedCollection'
+ end
+
+ it 'contains the total amount of items' do
+ expect(subject['totalItems']).to eq 10
+ end
+
+ it 'contains links to first and last page' do
+ expect(subject['first']).to eq "#{url}?page=1"
+ expect(subject['last']).to eq "#{url}?page=3"
+ end
+ end
+
+ context 'when a page parameter is provided' do
+ subject { decorated.represent(resources) }
+
+ let(:request_data) do
+ { 'rack.url_scheme' => 'https', 'HTTP_HOST' => 'example.com', 'PATH_INFO' => '/resource/url',
+ 'QUERY_STRING' => 'page=2&per_page=1' }
+ end
+
+ it_behaves_like 'ActivityStreams document'
+
+ it 'is a page document' do
+ expect(subject['type']).to eq 'OrderedCollectionPage'
+ end
+
+ it 'contains navigation links' do
+ expect(subject['prev']).to be_present
+ expect(subject['next']).to be_present
+ expect(subject['partOf']).to be_present
+ end
+ end
+ end
+end
diff --git a/spec/serializers/activity_pub/project_entity_spec.rb b/spec/serializers/activity_pub/project_entity_spec.rb
new file mode 100644
index 00000000000..f273acace73
--- /dev/null
+++ b/spec/serializers/activity_pub/project_entity_spec.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ActivityPub::ProjectEntity, feature_category: :groups_and_projects do
+ let(:project) { build_stubbed(:project, name: 'Fooify', path: 'fooify') }
+ let(:entity) { described_class.new(project) }
+
+ context 'as json' do
+ subject { entity.as_json }
+
+ it 'has releases page as id' do
+ expect(subject[:id]).to match(%r{/fooify$})
+ end
+
+ it 'is an Application actor' do
+ expect(subject[:type]).to eq 'Application'
+ end
+
+ it 'provides project name' do
+ expect(subject[:name]).to eq project.name
+ end
+
+ it 'provides a description of the project' do
+ expect(subject[:summary]).to eq project.description
+ end
+
+ it 'provides an url for web content' do
+ expect(subject[:url]).to match(%r{/fooify$})
+ end
+ end
+end
diff --git a/spec/serializers/activity_pub/release_entity_spec.rb b/spec/serializers/activity_pub/release_entity_spec.rb
new file mode 100644
index 00000000000..a473fbcc2bd
--- /dev/null
+++ b/spec/serializers/activity_pub/release_entity_spec.rb
@@ -0,0 +1,48 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ActivityPub::ReleaseEntity, feature_category: :groups_and_projects do
+ let(:release) { build_stubbed(:release) }
+ let(:entity) { described_class.new(release, url: '/outbox') }
+
+ context 'as json' do
+ subject { entity.as_json }
+
+ it 'has tag as id' do
+ expect(subject[:id]).to match(/##{release.tag}$/)
+ end
+
+ it 'is a Create activity' do
+ expect(subject[:type]).to eq 'Create'
+ end
+
+ it 'is addressed to public' do
+ expect(subject[:to]).to eq 'https://www.w3.org/ns/activitystreams#Public'
+ end
+
+ it 'has an author' do
+ expect(subject[:actor]).to include(:id, :type, :name, :preferredUsername, :url)
+ end
+
+ it 'embeds the release as an Application actor' do
+ expect(subject[:object][:type]).to eq 'Application'
+ end
+
+ it 'provides release name' do
+ expect(subject[:object][:name]).to eq release.name
+ end
+
+ it 'provides release description' do
+ expect(subject[:object][:content]).to eq release.description
+ end
+
+ it 'provides an url for web content' do
+ expect(subject[:object][:url]).to include release.tag
+ end
+
+ it 'provides project data as context' do
+ expect(subject[:object][:context]).to include(:id, :type, :name, :summary, :url)
+ end
+ end
+end
diff --git a/spec/serializers/activity_pub/releases_actor_entity_spec.rb b/spec/serializers/activity_pub/releases_actor_entity_spec.rb
new file mode 100644
index 00000000000..fe388968867
--- /dev/null
+++ b/spec/serializers/activity_pub/releases_actor_entity_spec.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ActivityPub::ReleasesActorEntity, feature_category: :groups_and_projects do
+ let(:project) { build_stubbed(:project, name: 'Fooify', path: 'fooify') }
+ let(:releases) { build_stubbed_list(:release, 3, project: project) }
+
+ let(:entity) { described_class.new(project) }
+
+ context 'as json' do
+ subject { entity.as_json }
+
+ it 'has releases page as id' do
+ expect(subject[:id]).to include "/fooify/-/releases"
+ end
+
+ it 'is an Application actor' do
+ expect(subject[:type]).to eq 'Application'
+ end
+
+ it 'has a recognizable username' do
+ expect(subject[:preferredUsername]).to include 'releases'
+ end
+
+ it 'has a recognizable full name' do
+ expect(subject[:name]).to eq 'Releases - Fooify'
+ end
+
+ it 'provides a description of the project' do
+ expect(subject[:content]).to eq project.description
+ end
+
+ it 'provides project data as context' do
+ expect(subject[:context]).to include(:id, :type, :name, :summary, :url)
+ expect(subject[:context][:id]).to match(%r{/fooify$})
+ end
+ end
+end
diff --git a/spec/serializers/activity_pub/releases_actor_serializer_spec.rb b/spec/serializers/activity_pub/releases_actor_serializer_spec.rb
new file mode 100644
index 00000000000..bc754eabe5c
--- /dev/null
+++ b/spec/serializers/activity_pub/releases_actor_serializer_spec.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ActivityPub::ReleasesActorSerializer, feature_category: :groups_and_projects do
+ let(:project) { build_stubbed(:project, name: 'Fooify', path: 'fooify') }
+ let(:releases) { build_stubbed_list(:release, 3, project: project) }
+
+ context 'when there is a single object provided' do
+ subject { described_class.new.represent(project, outbox: '/outbox') }
+
+ it 'serializes the actor attributes' do
+ expect(subject).to include(:id, :type, :preferredUsername, :name, :content, :context)
+ end
+ end
+end
diff --git a/spec/serializers/activity_pub/releases_outbox_serializer_spec.rb b/spec/serializers/activity_pub/releases_outbox_serializer_spec.rb
new file mode 100644
index 00000000000..606b0130e0f
--- /dev/null
+++ b/spec/serializers/activity_pub/releases_outbox_serializer_spec.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ActivityPub::ReleasesOutboxSerializer, feature_category: :groups_and_projects do
+ let(:decorated) { described_class.new.with_pagination(request, response) }
+
+ let(:project) { build_stubbed(:project, name: 'Fooify', path: 'fooify') }
+ let(:releases) { build_stubbed_list(:release, 3, project: project) }
+
+ before do
+ allow(releases).to receive(:page).and_return(releases)
+ allow(releases).to receive(:per).and_return(releases)
+ allow(releases).to receive(:current_page).and_return(1)
+ allow(releases).to receive(:total_pages).and_return(1)
+ allow(decorated.paginator).to receive(:paginate).and_return(releases)
+ end
+
+ context 'when there is a list of objects provided' do
+ subject { decorated.represent(releases, url: '/outbox') }
+
+ let(:request) { ActionDispatch::Request.new({ 'QUERY_STRING' => 'page=1' }) }
+ let(:response) { ActionDispatch::Response.new }
+
+ it 'is a OrderedCollection document' do
+ expect(subject[:type]).to eq 'OrderedCollectionPage'
+ end
+
+ it 'serializes the releases' do
+ expect(subject[:orderedItems].count).to eq 3
+ expect(subject[:orderedItems][0]).to include(:id, :type, :to, :actor, :object)
+ end
+ end
+end
diff --git a/spec/serializers/activity_pub/user_entity_spec.rb b/spec/serializers/activity_pub/user_entity_spec.rb
new file mode 100644
index 00000000000..d9ab7a11ecf
--- /dev/null
+++ b/spec/serializers/activity_pub/user_entity_spec.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ActivityPub::UserEntity, feature_category: :user_profile do
+ let(:user) { build_stubbed(:user, name: 'Alice', username: 'alice') }
+ let(:entity) { described_class.new(user) }
+
+ context 'as json' do
+ subject { entity.as_json }
+
+ it 'has releases page as id' do
+ expect(subject[:id]).to match(%r{/alice$})
+ end
+
+ it 'is a Person actor' do
+ expect(subject[:type]).to eq 'Person'
+ end
+
+ it 'provides project name' do
+ expect(subject[:name]).to eq 'Alice'
+ end
+
+ it 'provides an url for web content' do
+ expect(subject[:url]).to match(%r{/alice$})
+ end
+ end
+end
diff --git a/spec/serializers/admin/abuse_report_details_entity_spec.rb b/spec/serializers/admin/abuse_report_details_entity_spec.rb
index 727716d76a4..bed9775ac8c 100644
--- a/spec/serializers/admin/abuse_report_details_entity_spec.rb
+++ b/spec/serializers/admin/abuse_report_details_entity_spec.rb
@@ -5,10 +5,11 @@ require 'spec_helper'
RSpec.describe Admin::AbuseReportDetailsEntity, feature_category: :insider_threat do
include Gitlab::Routing
- let(:report) { build_stubbed(:abuse_report) }
- let(:user) { report.user }
- let(:reporter) { report.reporter }
- let!(:other_report) { create(:abuse_report, user: user) } # rubocop:disable RSpec/FactoryBot/AvoidCreate
+ let_it_be(:report) { build_stubbed(:abuse_report) }
+ let_it_be(:user) { report.user }
+ let_it_be(:reporter) { report.reporter }
+ let_it_be(:past_report) { create_default(:abuse_report, :closed, user: user) }
+ let_it_be(:similar_open_report) { create_default(:abuse_report, user: user, category: report.category) }
let(:entity) do
described_class.new(report)
@@ -18,11 +19,10 @@ RSpec.describe Admin::AbuseReportDetailsEntity, feature_category: :insider_threa
subject(:entity_hash) { entity.as_json }
it 'exposes correct attributes' do
- expect(entity_hash.keys).to include(
+ expect(entity_hash.keys).to match_array([
:user,
- :reporter,
:report
- )
+ ])
end
it 'correctly exposes `user`', :aggregate_failures do
@@ -39,7 +39,8 @@ RSpec.describe Admin::AbuseReportDetailsEntity, feature_category: :insider_threa
:admin_path,
:plan,
:verification_state,
- :other_reports,
+ :past_closed_reports,
+ :similar_open_reports,
:most_used_ip,
:last_sign_in_ip,
:snippets_count,
@@ -53,11 +54,77 @@ RSpec.describe Admin::AbuseReportDetailsEntity, feature_category: :insider_threa
:credit_card
])
- expect(user_hash[:other_reports][0].keys).to match_array([
+ expect(user_hash[:past_closed_reports][0].keys).to match_array([
:created_at,
:category,
:report_path
])
+
+ similar_open_report_hash = user_hash[:similar_open_reports][0]
+ expect(similar_open_report_hash.keys).to match_array([
+ :id,
+ :global_id,
+ :status,
+ :message,
+ :reported_at,
+ :category,
+ :type,
+ :content,
+ :url,
+ :screenshot,
+ :update_path,
+ :moderate_user_path,
+ :reporter
+ ])
+
+ similar_reporter_hash = similar_open_report_hash[:reporter]
+ expect(similar_reporter_hash.keys).to match_array([
+ :name,
+ :username,
+ :avatar_url,
+ :path
+ ])
+ end
+
+ context 'when report is closed' do
+ let(:report) { build_stubbed(:abuse_report, :closed) }
+
+ it 'does not expose `user.similar_open_reports`' do
+ user_hash = entity_hash[:user]
+
+ expect(user_hash).not_to include(:similar_open_reports)
+ end
+ end
+
+ it 'correctly exposes `report`', :aggregate_failures do
+ report_hash = entity_hash[:report]
+
+ expect(report_hash.keys).to match_array([
+ :id,
+ :global_id,
+ :status,
+ :message,
+ :reported_at,
+ :category,
+ :type,
+ :content,
+ :url,
+ :screenshot,
+ :update_path,
+ :moderate_user_path,
+ :reporter
+ ])
+ end
+
+ it 'correctly exposes `reporter`' do
+ reporter_hash = entity_hash[:report][:reporter]
+
+ expect(reporter_hash.keys).to match_array([
+ :name,
+ :username,
+ :avatar_url,
+ :path
+ ])
end
describe 'users plan' do
@@ -110,33 +177,5 @@ RSpec.describe Admin::AbuseReportDetailsEntity, feature_category: :insider_threa
end
end
end
-
- it 'correctly exposes `reporter`' do
- reporter_hash = entity_hash[:reporter]
-
- expect(reporter_hash.keys).to match_array([
- :name,
- :username,
- :avatar_url,
- :path
- ])
- end
-
- it 'correctly exposes `report`' do
- report_hash = entity_hash[:report]
-
- expect(report_hash.keys).to match_array([
- :status,
- :message,
- :reported_at,
- :category,
- :type,
- :content,
- :url,
- :screenshot,
- :update_path,
- :moderate_user_path
- ])
- end
end
end
diff --git a/spec/serializers/admin/abuse_report_details_serializer_spec.rb b/spec/serializers/admin/abuse_report_details_serializer_spec.rb
index a42c56c0921..3bdd2e46ba3 100644
--- a/spec/serializers/admin/abuse_report_details_serializer_spec.rb
+++ b/spec/serializers/admin/abuse_report_details_serializer_spec.rb
@@ -9,11 +9,10 @@ RSpec.describe Admin::AbuseReportDetailsSerializer, feature_category: :insider_t
describe '#represent' do
it 'serializes an abuse report' do
- is_expected.to include(
+ is_expected.to match_array([
:user,
- :reporter,
:report
- )
+ ])
end
end
end
diff --git a/spec/serializers/admin/abuse_report_entity_spec.rb b/spec/serializers/admin/abuse_report_entity_spec.rb
index c7f57258f40..e84cfe73b96 100644
--- a/spec/serializers/admin/abuse_report_entity_spec.rb
+++ b/spec/serializers/admin/abuse_report_entity_spec.rb
@@ -15,15 +15,16 @@ RSpec.describe Admin::AbuseReportEntity, feature_category: :insider_threat do
subject(:entity_hash) { entity.as_json }
it 'exposes correct attributes' do
- expect(entity_hash.keys).to include(
+ expect(entity_hash.keys).to match_array([
:category,
:created_at,
:updated_at,
:count,
+ :labels,
:reported_user,
:reporter,
:report_path
- )
+ ])
end
it 'correctly exposes `reported user`' do
@@ -37,5 +38,15 @@ RSpec.describe Admin::AbuseReportEntity, feature_category: :insider_threat do
it 'correctly exposes :report_path' do
expect(entity_hash[:report_path]).to eq admin_abuse_report_path(abuse_report)
end
+
+ context 'when abuse_report_labels feature flag is disabled' do
+ before do
+ stub_feature_flags(abuse_report_labels: false)
+ end
+
+ it 'does not expose labels' do
+ expect(entity_hash.keys).not_to include(:labels)
+ end
+ end
end
end
diff --git a/spec/serializers/admin/reported_content_entity_spec.rb b/spec/serializers/admin/reported_content_entity_spec.rb
new file mode 100644
index 00000000000..0af16561005
--- /dev/null
+++ b/spec/serializers/admin/reported_content_entity_spec.rb
@@ -0,0 +1,50 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Admin::ReportedContentEntity, feature_category: :insider_threat do
+ let_it_be(:report) { build_stubbed(:abuse_report) }
+
+ let(:entity) do
+ described_class.new(report)
+ end
+
+ describe '#as_json' do
+ subject(:entity_hash) { entity.as_json }
+
+ it 'exposes correct attributes' do
+ expect(entity_hash.keys).to match_array([
+ :id,
+ :global_id,
+ :status,
+ :message,
+ :reported_at,
+ :category,
+ :type,
+ :content,
+ :url,
+ :screenshot,
+ :reporter,
+ :update_path,
+ :moderate_user_path
+ ])
+ end
+
+ it 'includes correct value for global_id' do
+ allow(Gitlab::GlobalId).to receive(:build).with(report, { id: report.id }).and_return(:mock_global_id)
+
+ expect(entity_hash[:global_id]).to eq 'mock_global_id'
+ end
+
+ it 'correctly exposes `reporter`' do
+ reporter_hash = entity_hash[:reporter]
+
+ expect(reporter_hash.keys).to match_array([
+ :name,
+ :username,
+ :avatar_url,
+ :path
+ ])
+ end
+ end
+end
diff --git a/spec/serializers/build_details_entity_spec.rb b/spec/serializers/build_details_entity_spec.rb
index 86eaf160b38..a9d58b20861 100644
--- a/spec/serializers/build_details_entity_spec.rb
+++ b/spec/serializers/build_details_entity_spec.rb
@@ -298,5 +298,21 @@ RSpec.describe BuildDetailsEntity do
end
end
end
+
+ context 'when the build has annotations' do
+ let!(:build) { create(:ci_build) }
+ let!(:annotation) { create(:ci_job_annotation, job: build, name: 'external_links', data: [{ external_link: { label: 'URL', url: 'https://example.com/' } }]) }
+
+ it 'exposes job URLs' do
+ expect(subject[:annotations].count).to eq(1)
+ expect(subject[:annotations].first[:name]).to eq('external_links')
+ expect(subject[:annotations].first[:data]).to include(a_hash_including(
+ 'external_link' => a_hash_including(
+ 'label' => 'URL',
+ 'url' => 'https://example.com/'
+ )
+ ))
+ end
+ end
end
end
diff --git a/spec/serializers/ci/job_annotation_entity_spec.rb b/spec/serializers/ci/job_annotation_entity_spec.rb
new file mode 100644
index 00000000000..8aef6e8cce3
--- /dev/null
+++ b/spec/serializers/ci/job_annotation_entity_spec.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Ci::JobAnnotationEntity, feature_category: :build_artifacts do
+ let(:entity) { described_class.new(annotation) }
+
+ let(:job) { build(:ci_build) }
+ let(:annotation) do
+ build(:ci_job_annotation, job: job, name: 'external_links', data:
+ [{ external_link: { label: 'URL', url: 'https://example.com/' } }])
+ end
+
+ describe '#as_json' do
+ subject { entity.as_json }
+
+ it 'contains valid name' do
+ expect(subject[:name]).to eq 'external_links'
+ end
+
+ it 'contains external links' do
+ expect(subject[:data]).to include(a_hash_including(
+ 'external_link' => a_hash_including(
+ 'label' => 'URL',
+ 'url' => 'https://example.com/'
+ )
+ ))
+ end
+ end
+end
diff --git a/spec/serializers/codequality_degradation_entity_spec.rb b/spec/serializers/codequality_degradation_entity_spec.rb
index 32269e5475b..3d07564c5dc 100644
--- a/spec/serializers/codequality_degradation_entity_spec.rb
+++ b/spec/serializers/codequality_degradation_entity_spec.rb
@@ -2,18 +2,31 @@
require 'spec_helper'
-RSpec.describe CodequalityDegradationEntity do
+RSpec.describe CodequalityDegradationEntity, feature_category: :code_quality do
let(:entity) { described_class.new(codequality_degradation) }
describe '#as_json' do
subject { entity.as_json }
+ context 'when sast_reports_in_inline_diff is disabled' do
+ before do
+ stub_feature_flags(sast_reports_in_inline_diff: false)
+ end
+
+ let(:codequality_degradation) { build(:codequality_degradation_1) }
+
+ it 'does not contain fingerprint' do
+ expect(subject[:fingerprint]).to be_nil
+ end
+ end
+
context 'when codequality contains an error' do
context 'when line is included in location' do
let(:codequality_degradation) { build(:codequality_degradation_2) }
it 'contains correct codequality degradation details', :aggregate_failures do
expect(subject[:description]).to eq("Method `new_array` has 12 arguments (exceeds 4 allowed). Consider refactoring.")
+ expect(subject[:fingerprint]).to eq("f3bdc1e8c102ba5fbd9e7f6cda51c95e")
expect(subject[:severity]).to eq("major")
expect(subject[:file_path]).to eq("file_a.rb")
expect(subject[:line]).to eq(10)
@@ -27,6 +40,7 @@ RSpec.describe CodequalityDegradationEntity do
it 'contains correct codequality degradation details', :aggregate_failures do
expect(subject[:description]).to eq("Avoid parameter lists longer than 5 parameters. [12/5]")
+ expect(subject[:fingerprint]).to eq("ab5f8b935886b942d621399f5a2ca16e")
expect(subject[:severity]).to eq("minor")
expect(subject[:file_path]).to eq("file_b.rb")
expect(subject[:line]).to eq(10)
@@ -44,6 +58,7 @@ RSpec.describe CodequalityDegradationEntity do
it 'lowercases severity', :aggregate_failures do
expect(subject[:description]).to eq("Avoid parameter lists longer than 5 parameters. [12/5]")
+ expect(subject[:fingerprint]).to eq("ab5f8b935886b942d621399f5a2ca16e")
expect(subject[:severity]).to eq("minor")
expect(subject[:file_path]).to eq("file_b.rb")
expect(subject[:line]).to eq(10)
diff --git a/spec/serializers/codequality_reports_comparer_serializer_spec.rb b/spec/serializers/codequality_reports_comparer_serializer_spec.rb
index 50c8a69737c..7d6f49bf41d 100644
--- a/spec/serializers/codequality_reports_comparer_serializer_spec.rb
+++ b/spec/serializers/codequality_reports_comparer_serializer_spec.rb
@@ -2,8 +2,8 @@
require 'spec_helper'
-RSpec.describe CodequalityReportsComparerSerializer do
- let(:project) { double(:project) }
+RSpec.describe CodequalityReportsComparerSerializer, feature_category: :code_quality do
+ let(:project) { build_stubbed(:project) }
let(:serializer) { described_class.new(project: project).represent(comparer) }
let(:comparer) { Gitlab::Ci::Reports::CodequalityReportsComparer.new(base_report, head_report) }
let(:base_report) { Gitlab::Ci::Reports::CodequalityReports.new }
diff --git a/spec/serializers/deployment_entity_spec.rb b/spec/serializers/deployment_entity_spec.rb
index b0f3f328a4f..53f0e0c34e1 100644
--- a/spec/serializers/deployment_entity_spec.rb
+++ b/spec/serializers/deployment_entity_spec.rb
@@ -10,8 +10,11 @@ RSpec.describe DeploymentEntity do
let_it_be(:environment) { create(:environment, project: project) }
let_it_be_with_reload(:pipeline) { create(:ci_pipeline, project: project, user: user) }
let_it_be_with_reload(:build) { create(:ci_build, :manual, :environment_with_deployment_tier, pipeline: pipeline) }
+ let_it_be_with_reload(:bridge) do
+ create(:ci_bridge, :manual, :environment_with_deployment_tier, pipeline: pipeline, downstream: project)
+ end
- let_it_be_with_refind(:deployment) { create(:deployment, deployable: build, environment: environment) }
+ let!(:deployment) { create(:deployment, deployable: job, environment: environment, project: project) }
let(:request) { double('request') }
let(:entity) { described_class.new(deployment, request: request) }
@@ -28,22 +31,33 @@ RSpec.describe DeploymentEntity do
allow(request).to receive(:project).and_return(project)
end
- it 'exposes fields', :aggregate_failures do
- expect(subject).to include(:iid)
- expect(subject[:ref][:name]).to eq 'master'
- expect(subject).to include(:status)
- expect(subject).to include(:created_at)
- expect(subject).to include(:deployed_at)
- expect(subject).to include(:is_last)
- expect(subject).to include(:tier_in_yaml)
+ shared_examples_for 'exposes fields' do
+ it 'exposes fields', :aggregate_failures do
+ expect(subject).to include(:iid)
+ expect(subject[:ref][:name]).to eq 'master'
+ expect(subject).to include(:status)
+ expect(subject).to include(:created_at)
+ expect(subject).to include(:deployed_at)
+ expect(subject).to include(:is_last)
+ expect(subject).to include(:tier_in_yaml)
+ end
+ end
+
+ context 'when deployable is build job' do
+ let(:job) { build }
+
+ it_behaves_like 'exposes fields'
+ end
+
+ context 'when deployable is bridge job' do
+ let(:job) { bridge }
+
+ it_behaves_like 'exposes fields'
end
context 'when deployable is nil' do
let(:entity) { described_class.new(deployment, request: request, deployment_details: false) }
-
- before do
- deployment.update!(deployable: nil)
- end
+ let(:job) { nil }
it 'does not expose deployable entry' do
expect(subject).not_to include(:deployable)
@@ -51,15 +65,17 @@ RSpec.describe DeploymentEntity do
end
context 'when the pipeline has another manual action' do
- let_it_be(:other_build) do
- create(:ci_build, :manual, name: 'another deploy', pipeline: pipeline, environment: build.environment)
+ let!(:other_job) do
+ create(:ci_build, :manual, name: 'another deploy', pipeline: pipeline, environment: job.environment)
end
- let_it_be(:other_deployment) { create(:deployment, deployable: build, environment: environment) }
+ let!(:other_deployment) { create(:deployment, deployable: job, environment: environment) }
+
+ let(:job) { build }
it 'returns another manual action' do
- expect(subject[:manual_actions].count).to eq(1)
- expect(subject[:manual_actions].pluck(:name)).to match_array(['another deploy'])
+ expect(subject[:manual_actions].count).to eq(2)
+ expect(subject[:manual_actions].pluck(:name)).to match_array(['another deploy', 'bridge'])
end
context 'when user is a reporter' do
@@ -82,18 +98,22 @@ RSpec.describe DeploymentEntity do
end
describe 'scheduled_actions' do
- let(:build) { create(:ci_build, :success, pipeline: pipeline) }
-
- before do
- deployment.update!(deployable: build)
- end
+ let(:job) { create(:ci_build, :success, pipeline: pipeline) }
context 'when the same pipeline has a scheduled action' do
- let(:other_build) { create(:ci_build, :schedulable, :success, pipeline: pipeline, name: 'other build') }
- let!(:other_deployment) { create(:deployment, deployable: other_build, environment: environment) }
+ let(:other_job) { create(:ci_build, :schedulable, :success, pipeline: pipeline, name: 'other job') }
+ let!(:other_deployment) { create(:deployment, deployable: other_job, environment: environment) }
it 'returns other scheduled actions' do
- expect(subject[:scheduled_actions][0][:name]).to eq 'other build'
+ expect(subject[:scheduled_actions][0][:name]).to eq 'other job'
+ end
+
+ context 'when deployable is bridge job' do
+ let(:job) { create(:ci_bridge, :success, pipeline: pipeline) }
+
+ it 'returns nil' do
+ expect(subject[:scheduled_actions]).to be_nil
+ end
end
end
@@ -115,10 +135,6 @@ RSpec.describe DeploymentEntity do
end
describe 'playable_build' do
- before do
- deployment.update!(deployable: job)
- end
-
context 'when the deployment has a playable deployable' do
context 'when this job is build and ready to be played' do
let(:job) { create(:ci_build, :playable, :scheduled, pipeline: pipeline) }
@@ -161,6 +177,8 @@ RSpec.describe DeploymentEntity do
described_class.new(deployment, request: request, deployment_details: false)
end
+ let(:job) { build }
+
it 'does not serialize deployment details' do
expect(subject.with_indifferent_access)
.not_to include(:commit, :manual_actions, :scheduled_actions)
@@ -172,5 +190,16 @@ RSpec.describe DeploymentEntity do
.to eq(name: 'test', build_path: path)
end
end
+
+ context 'when deployable is bridge' do
+ let(:job) { bridge }
+
+ it 'only exposes deployable name and path' do
+ project_job_path(project, deployment.deployable).tap do |path|
+ expect(subject.fetch(:deployable))
+ .to eq(name: 'bridge', build_path: path)
+ end
+ end
+ end
end
end
diff --git a/spec/serializers/import/github_realtime_repo_entity_spec.rb b/spec/serializers/import/github_realtime_repo_entity_spec.rb
index 7f137366be2..bbaeb5c4ea8 100644
--- a/spec/serializers/import/github_realtime_repo_entity_spec.rb
+++ b/spec/serializers/import/github_realtime_repo_entity_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe Import::GithubRealtimeRepoEntity, feature_category: :importers do
subject(:entity) { described_class.new(project) }
- let(:import_state) { instance_double(ProjectImportState, failed?: false, in_progress?: true) }
+ let(:import_state) { instance_double(ProjectImportState, failed?: false, completed?: true) }
let(:import_failures) { [instance_double(ImportFailure, exception_message: 'test error')] }
let(:project) do
instance_double(
@@ -27,7 +27,7 @@ RSpec.describe Import::GithubRealtimeRepoEntity, feature_category: :importers do
end
context 'when import stats is failed' do
- let(:import_state) { instance_double(ProjectImportState, failed?: true, in_progress?: false) }
+ let(:import_state) { instance_double(ProjectImportState, failed?: true, completed?: true) }
it 'includes import_error' do
data = entity.as_json
diff --git a/spec/serializers/import/github_realtime_repo_serializer_spec.rb b/spec/serializers/import/github_realtime_repo_serializer_spec.rb
index b656132e332..825118d0f80 100644
--- a/spec/serializers/import/github_realtime_repo_serializer_spec.rb
+++ b/spec/serializers/import/github_realtime_repo_serializer_spec.rb
@@ -10,7 +10,7 @@ RSpec.describe Import::GithubRealtimeRepoSerializer, feature_category: :importer
end
describe '#represent' do
- let(:import_state) { instance_double(ProjectImportState, failed?: false, in_progress?: true) }
+ let(:import_state) { instance_double(ProjectImportState, failed?: false, completed?: false) }
let(:project) do
instance_double(
Project,
diff --git a/spec/serializers/profile/event_entity_spec.rb b/spec/serializers/profile/event_entity_spec.rb
index b1246e7e47d..3dade4210b3 100644
--- a/spec/serializers/profile/event_entity_spec.rb
+++ b/spec/serializers/profile/event_entity_spec.rb
@@ -153,6 +153,17 @@ RSpec.describe Profile::EventEntity, feature_category: :user_profile do
end
end
+ context 'without target' do
+ let(:event) do
+ build(:event, :destroyed, author: user, project: project, target_type: Milestone.to_s)
+ end
+
+ it 'only exposes target.type' do
+ expect(subject[:target][:type]).to eq(Milestone.to_s)
+ expect(subject[:target]).not_to include(:web_url)
+ end
+ end
+
context 'with resource parent' do
it 'exposes resource parent fields' do
resource_parent = event.resource_parent