This commit is contained in:
parent
e54f927149
commit
e18ca373eb
@ -28,10 +28,9 @@ class Api::V1Alpha::CollectionsController < Api::BaseController
|
|||||||
cache_if_unauthenticated!
|
cache_if_unauthenticated!
|
||||||
authorize @account, :index_collections?
|
authorize @account, :index_collections?
|
||||||
|
|
||||||
presenter = CollectionsPresenter.new(collections: @collections)
|
render json: @collections, each_serializer: REST::CollectionSerializer, adapter: :json
|
||||||
render json: presenter, serializer: REST::CollectionsWithAccountPreviewsSerializer
|
|
||||||
rescue Mastodon::NotPermittedError
|
rescue Mastodon::NotPermittedError
|
||||||
render json: { collections: [], partial_accounts: [] }
|
render json: { collections: [] }
|
||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@ -74,7 +73,6 @@ class Api::V1Alpha::CollectionsController < Api::BaseController
|
|||||||
def set_collections
|
def set_collections
|
||||||
@collections = @account.collections
|
@collections = @account.collections
|
||||||
.with_tag
|
.with_tag
|
||||||
.preload(top_items: :account)
|
|
||||||
.order(created_at: :desc)
|
.order(created_at: :desc)
|
||||||
.offset(offset_param)
|
.offset(offset_param)
|
||||||
.limit(limit_param(DEFAULT_COLLECTIONS_LIMIT))
|
.limit(limit_param(DEFAULT_COLLECTIONS_LIMIT))
|
||||||
|
|||||||
@ -31,7 +31,6 @@ class Collection < ApplicationRecord
|
|||||||
|
|
||||||
has_many :collection_items, dependent: :delete_all
|
has_many :collection_items, dependent: :delete_all
|
||||||
has_many :accepted_collection_items, -> { accepted }, class_name: 'CollectionItem', inverse_of: :collection # rubocop:disable Rails/HasManyOrHasOneDependent
|
has_many :accepted_collection_items, -> { accepted }, class_name: 'CollectionItem', inverse_of: :collection # rubocop:disable Rails/HasManyOrHasOneDependent
|
||||||
has_many :top_items, -> { top_items }, class_name: 'CollectionItem', inverse_of: :collection # rubocop:disable Rails/HasManyOrHasOneDependent
|
|
||||||
has_many :collection_reports, dependent: :delete_all
|
has_many :collection_reports, dependent: :delete_all
|
||||||
|
|
||||||
validates :name, presence: true
|
validates :name, presence: true
|
||||||
|
|||||||
@ -47,15 +47,6 @@ class CollectionItem < ApplicationRecord
|
|||||||
scope :local, -> { joins(:collection).merge(Collection.local) }
|
scope :local, -> { joins(:collection).merge(Collection.local) }
|
||||||
scope :accepted_partial, ->(account) { joins(:account).merge(Account.local).accepted.where(uri: nil, account_id: account.id) }
|
scope :accepted_partial, ->(account) { joins(:account).merge(Account.local).accepted.where(uri: nil, account_id: account.id) }
|
||||||
scope :pending_or_accepted, -> { where(state: [:pending, :accepted]) }
|
scope :pending_or_accepted, -> { where(state: [:pending, :accepted]) }
|
||||||
scope :top_items, lambda { |limit = 4|
|
|
||||||
subquery = where('collection_items.collection_id = collections.id')
|
|
||||||
.accepted.ordered.limit(limit)
|
|
||||||
.arel.lateral('top_items')
|
|
||||||
collection_query = Collection
|
|
||||||
.select('top_items.*')
|
|
||||||
.from([Collection.arel_table, subquery])
|
|
||||||
from(collection_query, 'collection_items')
|
|
||||||
}
|
|
||||||
|
|
||||||
def with_local_account?
|
def with_local_account?
|
||||||
account&.local?
|
account&.local?
|
||||||
|
|||||||
@ -1,11 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class CollectionsPresenter < ActiveModelSerializers::Model
|
|
||||||
attributes :collections
|
|
||||||
|
|
||||||
def accounts
|
|
||||||
owners = collections.map(&:account)
|
|
||||||
top_accounts = collections.flat_map { |c| c.top_items.map(&:account) }
|
|
||||||
(owners + top_accounts).uniq
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class REST::CollectionsWithAccountPreviewsSerializer < ActiveModel::Serializer
|
|
||||||
has_many :collections, serializer: REST::CollectionSerializer
|
|
||||||
has_many :partial_accounts, serializer: REST::PartialAccountSerializer
|
|
||||||
|
|
||||||
def partial_accounts
|
|
||||||
object.accounts
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@ -199,16 +199,4 @@ RSpec.describe Collection do
|
|||||||
expect(subject.to_log_permalink).to eq ActivityPub::TagManager.instance.uri_for(subject)
|
expect(subject.to_log_permalink).to eq ActivityPub::TagManager.instance.uri_for(subject)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#top_items' do
|
|
||||||
let(:collection) { Fabricate(:collection) }
|
|
||||||
|
|
||||||
before do
|
|
||||||
5.times { |i| Fabricate(:collection_item, collection:, position: i + 1) }
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns the topmost four items' do
|
|
||||||
expect(collection.top_items.map(&:position)).to contain_exactly(1, 2, 3, 4)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1,48 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
require 'rails_helper'
|
|
||||||
|
|
||||||
RSpec.describe CollectionsPresenter do
|
|
||||||
subject { described_class.new(collections:) }
|
|
||||||
|
|
||||||
let(:collection_owner_one) { Fabricate(:account) }
|
|
||||||
let(:collection_owner_two) { Fabricate(:account) }
|
|
||||||
let(:collection_one) do
|
|
||||||
Fabricate(:collection,
|
|
||||||
account: collection_owner_one,
|
|
||||||
name: 'Exquisite follows')
|
|
||||||
end
|
|
||||||
let(:collection_two) do
|
|
||||||
Fabricate(:collection,
|
|
||||||
account: collection_owner_two,
|
|
||||||
name: 'Excellent people')
|
|
||||||
end
|
|
||||||
let(:collections) { [collection_one, collection_two] }
|
|
||||||
|
|
||||||
describe '#accounts' do
|
|
||||||
context 'when collections do not have any items' do
|
|
||||||
it 'includes only the collection owners' do
|
|
||||||
expect(subject.accounts).to contain_exactly(collection_owner_one, collection_owner_two)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when collections include accounts' do
|
|
||||||
let(:accounts) { Fabricate.times(3, :account) }
|
|
||||||
|
|
||||||
before do
|
|
||||||
accounts[0..1].each { |a| Fabricate(:collection_item, collection: collection_one, account: a) }
|
|
||||||
accounts[1..2].each { |a| Fabricate(:collection_item, collection: collection_two, account: a) }
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'includes collection owners and unique preview accounts' do
|
|
||||||
expect(subject.accounts).to contain_exactly(
|
|
||||||
collection_owner_one,
|
|
||||||
collection_owner_two,
|
|
||||||
accounts[0],
|
|
||||||
accounts[1],
|
|
||||||
accounts[2]
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@ -1,45 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
require 'rails_helper'
|
|
||||||
|
|
||||||
RSpec.describe REST::CollectionsWithAccountPreviewsSerializer do
|
|
||||||
subject do
|
|
||||||
serialized_record_json(presenter, described_class, options: {
|
|
||||||
scope_name: :current_user, scope: nil
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
let(:collection_owner_one) { Fabricate(:account) }
|
|
||||||
let(:collection_owner_two) { Fabricate(:account) }
|
|
||||||
let(:featured_account) { Fabricate(:account) }
|
|
||||||
let(:collection_one) do
|
|
||||||
Fabricate(:collection,
|
|
||||||
account: collection_owner_one,
|
|
||||||
name: 'Exquisite follows')
|
|
||||||
end
|
|
||||||
let(:collection_two) do
|
|
||||||
Fabricate(:collection,
|
|
||||||
account: collection_owner_two,
|
|
||||||
name: 'Excellent people')
|
|
||||||
end
|
|
||||||
let(:collections) { [collection_one, collection_two] }
|
|
||||||
let(:presenter) { CollectionsPresenter.new(collections:) }
|
|
||||||
|
|
||||||
before do
|
|
||||||
Fabricate(:collection_item, collection: collection_one, account: featured_account)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'includes collections and partial accounts with the expected attributes' do
|
|
||||||
expect(subject).to include({
|
|
||||||
'collections' => [
|
|
||||||
a_hash_including({ 'name' => 'Exquisite follows' }),
|
|
||||||
a_hash_including({ 'name' => 'Excellent people' }),
|
|
||||||
],
|
|
||||||
'partial_accounts' => [
|
|
||||||
a_hash_including({ 'id' => collection_owner_one.id.to_s }),
|
|
||||||
a_hash_including({ 'id' => collection_owner_two.id.to_s }),
|
|
||||||
a_hash_including({ 'id' => featured_account.id.to_s }),
|
|
||||||
],
|
|
||||||
})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
Loading…
x
Reference in New Issue
Block a user