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:
Diffstat (limited to 'spec/serializers/activity_pub')
-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
7 files changed, 354 insertions, 0 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