Files
mastodon/spec/requests/api/v1/collection_items_spec.rb
jcoffey-dev 319ed76dbd
Crowdin / Upload translations / upload-translations (push) Skipped
Historical data migration test / test (14-alpine) (push) Canceled after 0s
Historical data migration test / test (15-alpine) (push) Canceled after 0s
Historical data migration test / test (16-alpine) (push) Canceled after 0s
Historical data migration test / test (17-alpine) (push) Canceled after 0s
Bundler Audit / security (push) Canceled after 0s
Haml Linting / lint (push) Canceled after 0s
JavaScript Linting / lint (push) Canceled after 0s
Ruby Linting / lint (push) Canceled after 0s
JavaScript Testing / test (push) Canceled after 0s
Ruby Testing / build (production) (push) Canceled after 0s
Ruby Testing / test (.ruby-version) (push) Canceled after 0s
Ruby Testing / test (3.3) (push) Canceled after 0s
Ruby Testing / test (3.4) (push) Canceled after 0s
Ruby Testing / End to End testing (.ruby-version) (push) Canceled after 0s
Ruby Testing / End to End testing (3.3) (push) Canceled after 0s
Ruby Testing / End to End testing (3.4) (push) Canceled after 0s
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:7.17.29) (push) Canceled after 0s
Check i18n / check-i18n (push) Canceled after 0s
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (javascript) (push) Canceled after 0s
CodeQL / Analyze (ruby) (push) Canceled after 0s
Ruby Testing / Elastic Search integration testing (.ruby-version, opensearchproject/opensearch:2) (push) Canceled after 0s
Ruby Testing / Elastic Search integration testing (3.3, docker.elastic.co/elasticsearch/elasticsearch:7.17.29) (push) Canceled after 0s
Ruby Testing / Elastic Search integration testing (3.4, docker.elastic.co/elasticsearch/elasticsearch:7.17.29) (push) Canceled after 0s
Check formatting / lint (push) Canceled after 0s
CSS Linting / lint (push) Canceled after 0s
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:8.19.2) (push) Canceled after 0s
Chromatic / Check for relevant changes (push) Canceled after 0s
Chromatic / Run Chromatic (push) Canceled after 0s
Import Mastodon v4.7.3
Snapshot of upstream tag v4.7.3 (commit 8ff11c2bb7b9f0714e947b10fa3629c6542c7121) from
https://github.com/mastodon/mastodon, unmodified.
2026-10-05 22:03:13 -07:00

145 lines
4.2 KiB
Ruby

# frozen_string_literal: true
require 'rails_helper'
RSpec.describe 'Api::V1Alpha::CollectionItems' do
include_context 'with API authentication', oauth_scopes: 'read:collections write:collections'
describe 'POST /api/v1/collections/:collection_id/items' do
subject do
post "/api/v1/collections/#{collection.id}/items", headers: headers, params: params
end
let(:collection) { Fabricate(:collection, account: user.account) }
let(:params) { {} }
it_behaves_like 'forbidden for wrong scope', 'read'
context 'when user is owner of the collection' do
context 'with valid params' do
let(:other_account) { Fabricate(:account) }
let(:params) { { account_id: other_account.id } }
it 'creates a collection item and returns http success' do
expect do
subject
end.to change(collection.collection_items, :count).by(1)
expect(response).to have_http_status(200)
expect(response.parsed_body).to have_key('collection_item')
end
it 'features a deprecation header when requested via the alpha route' do
subject
expect(response.headers['Deprecation']).to be_nil
post "/api/v1_alpha/collections/#{collection.id}/items", headers: headers, params: params
expect(response.headers['Deprecation']).to eq '@1781049600'
end
end
context 'with invalid params' do
it 'returns http unprocessable content' do
expect do
subject
end.to_not change(CollectionItem, :count)
expect(response).to have_http_status(422)
end
end
end
context 'when user is not the owner of the collection' do
let(:collection) { Fabricate(:collection) }
let(:other_account) { Fabricate(:account) }
let(:params) { { account_id: other_account.id } }
it 'returns http forbidden' do
subject
expect(response).to have_http_status(403)
end
end
end
describe 'DELETE /api/v1/collections/:collection_id/items/:id' do
subject do
delete "/api/v1/collections/#{collection.id}/items/#{item.id}", headers: headers
end
let(:collection) { Fabricate(:collection, account: user.account) }
let(:item) { Fabricate(:collection_item, collection:) }
it_behaves_like 'forbidden for wrong scope', 'read'
context 'when user is owner of the collection' do
context 'when item belongs to collection' do
it 'deletes the collection item and returns http success' do
item # Make sure this exists before calling the API
expect do
subject
end.to change(collection.collection_items, :count).by(-1)
expect(response).to have_http_status(200)
end
end
context 'when item does not belong to to collection' do
let(:item) { Fabricate(:collection_item) }
it 'returns http not found' do
item # Make sure this exists before calling the API
expect do
subject
end.to_not change(CollectionItem, :count)
expect(response).to have_http_status(404)
end
end
end
context 'when user is not the owner of the collection' do
let(:collection) { Fabricate(:collection) }
it 'returns http forbidden' do
subject
expect(response).to have_http_status(403)
end
end
end
describe 'POST /api/v1/collections/:collection_id/items/:id/revoke' do
subject do
post "/api/v1/collections/#{collection.id}/items/#{item.id}/revoke", headers: headers
end
let(:collection) { Fabricate(:collection) }
let(:item) { Fabricate(:collection_item, collection:, account: user.account) }
it_behaves_like 'forbidden for wrong scope', 'read'
context 'when user is in item' do
it 'revokes the collection item and returns http success' do
subject
expect(item.reload).to be_revoked
expect(response).to have_http_status(200)
end
end
context 'when user is not in the item' do
let(:item) { Fabricate(:collection_item, collection:) }
it 'returns http forbidden' do
subject
expect(response).to have_http_status(403)
end
end
end
end