diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-09-20 14:18:08 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-09-20 14:18:08 +0300 |
commit | 5afcbe03ead9ada87621888a31a62652b10a7e4f (patch) | |
tree | 9918b67a0d0f0bafa6542e839a8be37adf73102d /spec/serializers | |
parent | c97c0201564848c1f53226fe19d71fdcc472f7d0 (diff) |
Add latest changes from gitlab-org/gitlab@16-4-stable-eev16.4.0-rc42
Diffstat (limited to 'spec/serializers')
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 |