166 lines
No EOL
6 KiB
Ruby
166 lines
No EOL
6 KiB
Ruby
require 'rails_helper'
|
|
|
|
RSpec.describe 'Collection Viewing API', type: :request do
|
|
let(:user) { create(:user, collection_privacy: 'everyone') }
|
|
let(:private_user) { create(:user, collection_privacy: 'private_collection') }
|
|
let(:crew_only_user) { create(:user, collection_privacy: 'crew_only') }
|
|
let(:viewer) { create(:user) }
|
|
|
|
let(:access_token) do
|
|
Doorkeeper::AccessToken.create!(resource_owner_id: viewer.id, expires_in: 30.days, scopes: 'public')
|
|
end
|
|
let(:headers) do
|
|
{ 'Authorization' => "Bearer #{access_token.token}", 'Content-Type' => 'application/json' }
|
|
end
|
|
|
|
# Create some collection items for testing
|
|
before do
|
|
# User's collection
|
|
create(:collection_character, user: user)
|
|
create(:collection_weapon, user: user)
|
|
create(:collection_summon, user: user)
|
|
create(:collection_job_accessory, user: user)
|
|
|
|
# Private user's collection
|
|
create(:collection_character, user: private_user)
|
|
create(:collection_weapon, user: private_user)
|
|
end
|
|
|
|
describe 'GET /api/v1/users/:user_id/collection' do
|
|
context 'viewing public collection' do
|
|
it 'returns the complete collection' do
|
|
get "/api/v1/users/#{user.id}/collection", headers: headers
|
|
|
|
expect(response).to have_http_status(:ok)
|
|
json = JSON.parse(response.body)
|
|
expect(json).to have_key('characters')
|
|
expect(json).to have_key('weapons')
|
|
expect(json).to have_key('summons')
|
|
expect(json).to have_key('job_accessories')
|
|
expect(json['characters'].length).to eq(1)
|
|
expect(json['weapons'].length).to eq(1)
|
|
expect(json['summons'].length).to eq(1)
|
|
expect(json['job_accessories'].length).to eq(1)
|
|
end
|
|
|
|
it 'returns only characters when type=characters' do
|
|
get "/api/v1/users/#{user.id}/collection", params: { type: 'characters' }, headers: headers
|
|
|
|
expect(response).to have_http_status(:ok)
|
|
json = JSON.parse(response.body)
|
|
expect(json).to have_key('characters')
|
|
expect(json).not_to have_key('weapons')
|
|
expect(json).not_to have_key('summons')
|
|
expect(json['characters'].length).to eq(1)
|
|
end
|
|
|
|
it 'returns only weapons when type=weapons' do
|
|
get "/api/v1/users/#{user.id}/collection", params: { type: 'weapons' }, headers: headers
|
|
|
|
expect(response).to have_http_status(:ok)
|
|
json = JSON.parse(response.body)
|
|
expect(json).to have_key('weapons')
|
|
expect(json).not_to have_key('characters')
|
|
expect(json).not_to have_key('summons')
|
|
expect(json['weapons'].length).to eq(1)
|
|
end
|
|
|
|
it 'returns only summons when type=summons' do
|
|
get "/api/v1/users/#{user.id}/collection", params: { type: 'summons' }, headers: headers
|
|
|
|
expect(response).to have_http_status(:ok)
|
|
json = JSON.parse(response.body)
|
|
expect(json).to have_key('summons')
|
|
expect(json).not_to have_key('characters')
|
|
expect(json).not_to have_key('weapons')
|
|
expect(json['summons'].length).to eq(1)
|
|
end
|
|
|
|
it 'returns only job accessories when type=job_accessories' do
|
|
get "/api/v1/users/#{user.id}/collection", params: { type: 'job_accessories' }, headers: headers
|
|
|
|
expect(response).to have_http_status(:ok)
|
|
json = JSON.parse(response.body)
|
|
expect(json).to have_key('job_accessories')
|
|
expect(json).not_to have_key('characters')
|
|
expect(json).not_to have_key('weapons')
|
|
expect(json['job_accessories'].length).to eq(1)
|
|
end
|
|
|
|
it 'works without authentication for public collections' do
|
|
get "/api/v1/users/#{user.id}/collection"
|
|
|
|
expect(response).to have_http_status(:ok)
|
|
json = JSON.parse(response.body)
|
|
expect(json).to have_key('characters')
|
|
end
|
|
end
|
|
|
|
context 'viewing private collection' do
|
|
it 'returns forbidden for non-owner' do
|
|
get "/api/v1/users/#{private_user.id}/collection", headers: headers
|
|
|
|
expect(response).to have_http_status(:forbidden)
|
|
json = JSON.parse(response.body)
|
|
expect(json['error']).to include('do not have permission')
|
|
end
|
|
|
|
it 'allows owner to view their own private collection' do
|
|
owner_token = Doorkeeper::AccessToken.create!(
|
|
resource_owner_id: private_user.id,
|
|
expires_in: 30.days,
|
|
scopes: 'public'
|
|
)
|
|
owner_headers = {
|
|
'Authorization' => "Bearer #{owner_token.token}",
|
|
'Content-Type' => 'application/json'
|
|
}
|
|
|
|
get "/api/v1/users/#{private_user.id}/collection", headers: owner_headers
|
|
|
|
expect(response).to have_http_status(:ok)
|
|
json = JSON.parse(response.body)
|
|
expect(json).to have_key('characters')
|
|
expect(json).to have_key('weapons')
|
|
end
|
|
end
|
|
|
|
context 'viewing crew-only collection' do
|
|
it 'returns forbidden for non-crew members' do
|
|
get "/api/v1/users/#{crew_only_user.id}/collection", headers: headers
|
|
|
|
expect(response).to have_http_status(:forbidden)
|
|
json = JSON.parse(response.body)
|
|
expect(json['error']).to include('do not have permission')
|
|
end
|
|
|
|
it 'allows owner to view their own crew-only collection' do
|
|
owner_token = Doorkeeper::AccessToken.create!(
|
|
resource_owner_id: crew_only_user.id,
|
|
expires_in: 30.days,
|
|
scopes: 'public'
|
|
)
|
|
owner_headers = {
|
|
'Authorization' => "Bearer #{owner_token.token}",
|
|
'Content-Type' => 'application/json'
|
|
}
|
|
|
|
get "/api/v1/users/#{crew_only_user.id}/collection", headers: owner_headers
|
|
|
|
expect(response).to have_http_status(:ok)
|
|
json = JSON.parse(response.body)
|
|
expect(json).to have_key('characters')
|
|
end
|
|
end
|
|
|
|
context 'error handling' do
|
|
it 'returns not found for non-existent user' do
|
|
get "/api/v1/users/#{SecureRandom.uuid}/collection", headers: headers
|
|
|
|
expect(response).to have_http_status(:not_found)
|
|
json = JSON.parse(response.body)
|
|
expect(json['error']).to include('User not found')
|
|
end
|
|
end
|
|
end
|
|
end |